`type/graphsymbol` := proc(s) local x;
    if type(s,symbol) then # Classic GUI
       x := [attributes(s)];
       type(s,symbol) and length(s)>6 and substring(s,1..6)='`Graph `'
       and type(x,'list'(`=`)) and hasoption(x,'GRAPHLN');
    elif type(s,function) then # Standard GUI
       return evalb( op(0,s)=GRAPHLN );
       # Don't use type(s,GRAPHLN) because s has been print preprocessed
    else false
    fi;
end:


`type/undirectedgraphsymbol` := proc(s)
   type(s,graphsymbol) and
(  type(s,symbol) and searchtext("undirected",s) > 0   # classic GUI
or type(s,function) and op(1,s)=undirected # java GUI
)
end:


`type/weightedgraphsymbol` := proc(s)
   type(s,graphsymbol) and 
(  type(s,symbol) and searchtext("unweighted",s) = 0   # classic GUI
or type(s,function) and op(2,s)=weighted # java GUI
)
end:


`type/simplegraph` := proc(s)
   type(s,undirectedgraphsymbol) and
(  type(s,symbol) and searchtext("unweighted",s) > 0   # classic GUI
or type(s,function) and op(2,s)=unweighted # java GUI
)
end:


`type/unweightedgraph` := proc(s)
   type(s,graphsymbol) and
(  type(s,symbol) and searchtext("unweighted",s) > 0   # classic GUI
or type(s,function) and op(2,s)=unweighted # java GUI
)
end:

`type/nonsimplegraph` := proc(s) not type(s,simplegraph) end:


`type/digraphsymbol` := proc(s)
   type(s,graphsymbol) and 
(  type(s,symbol) and searchtext(" directed",s) > 0
or type(s,function) and op(1,s)=directed
)
end:

`type/acyclicdigraphsymbol` := proc(s)
   type(s,digraphsymbol) and GraphTheory:-IsAcyclic( preprograph(s) );
end:

`type/networksymbol` := proc(s) local S,T;
   if not type(s,digraphsymbol) then return false; fi;
   S,T := GraphTheory:-IsNetwork( preprograph(s) );
   S <> {} and T <> {};
end:

`type/weightednetworksymbol` := proc(s)
   type(s,networksymbol) and
(  type(s,symbol) and searchtext("unweighted",s) = 0   # classic GUI
or type(s,function) and op(2,s)=weighted # java GUI
)
end:

preprograph := proc(g) local A,M,GUI;
  GUI := interface(version);
  if substring(GUI,1..7)='`Classic`' then return ExtractGraph(g); fi;
  if substring(GUI,1..8)='`Standard`' and 
#type(g,'GRAPHLN'(symbol,symbol,list,'Array'(anything=integer),symbol,{0,'Matrix'(anything=integer)})) then
#The above doesn't work because type/Array and type/Matrix are special types
type(g,'GRAPHLN'(symbol,symbol,list,specfunc(identical(`%id`)=integer,'Array'),symbol,{0,function})) then
     # In the java GUI, g looks like this
     # GRAPHLN(directed,weighted,[...],Array(`%id`=NNN),`GRAPHLN/table/nnn`,Matrix(`%id`=MMM))
     # where NNN and MMM are handles to the actual objects.
     A := pointto(op(2,op(1,op(4,g))));
     if op(6,g)=0 then M := 0; else M := pointto(op(2,op(1,op(6,g)))); fi;
     return subsop(4=A,6=M,g);
  fi;
  error "not implemented for this version: %1", GUI;
end:

ExtractGraph := proc(g) local G;
# For a Maple command which outputs a graph, e.g.,
#    > Graph([1,2,3],{{1,2},{2,3}});
# outputs the following symbol from print/GRAPHLN
#    `Graph 1: an undirected and unweighted graph with 3 vertices and 2 edge(s)`
# In the classic GUI, g is this symbol, with the graph attached as an attribute.
# In the java GUI, g will be the actual graph.
# However, for a Maple command which assigns a graph to a variable, e.g.,
#    > G := Graph([1,2,3],{{1,2},{2,3}});
#    `Graph 2: an undirected and unweighted graph with 3 vertices and 2 edge(s)`
# In this case, for both classic and java GUIs, g will be the graph
# printf("EXT=%a: %a\n",type(g,GRAPHLN),g);
  if type(g,GRAPHLN) then return g fi;
  if not type(g,symbol) then error "bad graph" fi;
  G := subs([attributes(g)],GRAPHLN);
  if G=GRAPHLN then error "bad graph" else G fi;
end:


use ContextMenu in

 CM := New();


 CM[EntryGenerators][Add]( "GraphTheoryExportList", 
   proc(G) local n, i, f, s, H;
         H := preprograph(G);
         n := `GRAPHLN/number`(H); # n should be the unique print number for this graph
         if not type(n,posint) then return []; fi; # this should not happen but if it does ....
         n := cat("Graph",n); # this is the file name prefix
         if op(1,H)=undirected and op(2,H)=unweighted then
            f := ["combinatorica","dimacs","metapost"];
            s := ["combinatorica","col","mp"];
         else f := ["metapost"]; s := ["mp"];
         fi;
         [seq( [f[i],[cat(n,".",s[i]),f[i]]], i=1..nops(f) )];
   end );

 CM[Entries][Add]( "DrawGraph", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false );
 CM[Entries][Add]( "ExportGraph", "GraphTheory:-ExportGraph(ExtractGraph(%EXPR),%ARG1,%ARG2)", graphsymbol,
    entry_generator = "GraphTheoryExportList", 'autoassign'=false );

 CM[Entries][AddMultiple](
    ["DrawGraph (spring)", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR),style=spring)", graphsymbol, 'autoassign'=false],
    ["DrawGraph (3D)", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR),style=spring,dimension=3)", graphsymbol, 'autoassign'=false],
    ["DrawNetwork", "GraphTheory:-DrawNetwork(ExtractGraph(%EXPR))", networksymbol, 'autoassign'=false],
   submenu=["Graph drawing"]);

 CM[EntryGenerators][Add]( "GraphTheoryPolynomialVariableList", 
   proc(G) local v,X; X := remove(assigned,'[x,y,lambda,p,q]'); [seq([convert(v,string),[v]], v=X)]; end);
 CM[Entries][AddMultiple](
   ["AcyclicPolynomial", "GraphTheory:-AcyclicPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph,
    entry_generator = "GraphTheoryPolynomialVariableList"],
   ["CharacteristicPolynomial", "GraphTheory:-CharacteristicPolynomial(ExtractGraph(%EXPR),%ARG1)", graphsymbol,
    entry_generator = "GraphTheoryPolynomialVariableList"],
   ["ChromaticPolynomial", "GraphTheory:-ChromaticPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph,
    entry_generator = "GraphTheoryPolynomialVariableList"],
   ["FlowPolynomial", "GraphTheory:-FlowPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph,
    entry_generator = "GraphTheoryPolynomialVariableList"],
   ["SpanningPolynomial", "GraphTheory:-SpanningPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph,
    entry_generator = "GraphTheoryPolynomialVariableList"],
   submenu=["Graph polynomials"]);

 CM[Entries][AddMultiple](
   ["AdjacencyMatrix", "GraphTheory:-AdjacencyMatrix(ExtractGraph(%EXPR))", graphsymbol],
   ["AllPairsDistance", "GraphTheory:-AllPairsDistance(ExtractGraph(%EXPR))", graphsymbol],
   ["ArticulationPoints", "GraphTheory:-ArticulationPoints(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["BiconnectedComponents", "GraphTheory:-BiconnectedComponents(ExtractGraph(%EXPR))", graphsymbol],
   ["BipartiteMatching", "GraphTheory:-BipartiteMatching(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["ConnectedComponents", "GraphTheory:-ConnectedComponents(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["CycleBasis", "GraphTheory:-CycleBasis(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["Edges", "GraphTheory:-Edges(ExtractGraph(%EXPR))", graphsymbol],
   ["GraphComplement", "GraphTheory:-GraphComplement(ExtractGraph(%EXPR))", graphsymbol],
   ["GraphPower", "GraphTheory:-GraphPower(ExtractGraph(%EXPR),%ARG1)", unweightedgraph,
     entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]]] end],
   ["GraphSpectrum", "GraphTheory:-GraphSpectrum(ExtractGraph(%EXPR))", graphsymbol],
   ["IndicenceMatrix", "GraphTheory:-IncidenceMatrix(ExtractGraph(%EXPR))", graphsymbol],
   ["LineGraph", "GraphTheory:-LineGraph(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["MaximumClique", "GraphTheory:-MaximumClique(ExtractGraph(%EXPR))", graphsymbol],
   ["MaxFlow", "GraphTheory:-MaxFlow(ExtractGraph(%EXPR),%ARG1,%ARG2)", weightednetworksymbol,
     entry_generator=proc(G) local N, sources,sinks, i,j, m,n;
           N := preprograph(G);
           sources,sinks := GraphTheory:-IsNetwork(N); # sources and sinks are non-empty sets
           (m,n) := (nops(sources),nops(sinks));
           while m*n > 12 do if m>n then m := m-1; else n := n-1 fi; od;
           (sources,sinks) := (sources[1..m], sinks[1..n]);
           [seq( seq( [sprintf("source(%d), sink(%d)",i,j), [i,j]], i=sources ), j=sinks )];
           end],
   ["MinimalSpanningTree", "GraphTheory:-MinimalSpanningTree(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["Mycielski", "GraphTheory:-Mycielski(ExtractGraph(%EXPR))", simplegraph],
   ["Neighbors", "GraphTheory:-Neighbors(ExtractGraph(%EXPR))", graphsymbol],
   ["OptimalEdgeColoring", "GraphTheory:-OptimalEdgeColoring(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["OptimalVertexColoring", "GraphTheory:-OptimalVertexColoring(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["SeidelSpectrum", "GraphTheory:-SeidelSpectrum(ExtractGraph(%EXPR))", graphsymbol],
   ["SpanningTree", "GraphTheory:-SpanningTree(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["StronglyConnectedComponents", "GraphTheory:-StronglyConnectedComponents(ExtractGraph(%EXPR))", digraphsymbol],
   ["TopologicSort", "GraphTheory:-TopologicSort(ExtractGraph(%EXPR))", acyclicdigraphsymbol],
   ["TravelingSalesman", "GraphTheory:-TravelingSalesman(ExtractGraph(%EXPR))", graphsymbol],
   ["UnderlyingGraph", "GraphTheory:-UnderlyingGraph(ExtractGraph(%EXPR))", digraphsymbol],
   ["VertexConnectivity", "GraphTheory:-VertexConnectivity(ExtractGraph(%EXPR))", graphsymbol],
   ["Vertices", "GraphTheory:-Vertices(ExtractGraph(%EXPR))", graphsymbol],
   ["WeightMatrix", "GraphTheory:-WeightMatrix(ExtractGraph(%EXPR))", weightedgraphsymbol],
   submenu=["Graph commands"]);

 CM[Entries][AddMultiple](
   ["ChromaticIndex", "GraphTheory:-ChromaticIndex(ExtractGraph(%EXPR))", simplegraph],
   ["ChromaticNumber", "GraphTheory:-ChromaticNumber(ExtractGraph(%EXPR))", simplegraph],
   ["CliqueNumber", "GraphTheory:-CliqueNumber(ExtractGraph(%EXPR))", simplegraph],
   ["Diameter", "GraphTheory:-Diameter(ExtractGraph(%EXPR))", graphsymbol],
   ["EdgeChromaticNumber", "GraphTheory:-EdgeChromaticNumber(ExtractGraph(%EXPR))", simplegraph],
   ["EdgeConnectivity", "GraphTheory:-EdgeConnectivity(ExtractGraph(%EXPR))", simplegraph],
   ["Girth", "GraphTheory:-Girth(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["GraphRank", "GraphTheory:-GraphRank(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["IndependenceNumber", "GraphTheory:-IndependenceNumber(ExtractGraph(%EXPR))", simplegraph],
   ["IsAcyclic", "GraphTheory:-IsAcyclic(ExtractGraph(%EXPR))", digraphsymbol, 'autoassign'=false],
   ["IsBiconnected", "GraphTheory:-IsBiconnected(ExtractGraph(%EXPR))", simplegraph, 'autoassign'=false],
   ["IsBipartite", "GraphTheory:-IsBipartite(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsClique", "GraphTheory:-IsClique(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false],
   ["IsConnected", "GraphTheory:-IsConnected(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false],
   ["IsDirected", "GraphTheory:-IsDirected(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsEulerian", "GraphTheory:-IsEulerian(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsForest", "GraphTheory:-IsForest(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false],
   ["IsKColorable", "GraphTheory:-IsKColorable(%EXPR,%ARG1)", graphsymbol,
     entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end],
   ["IsKEdgeColorable", "GraphTheory:-IsKEdgeColorable(%EXPR,%ARG1)", undirectedgraphsymbol,
     entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end],
   ["IsNetwork", "[GraphTheory:-IsNetwork(ExtractGraph(%EXPR))]", digraphsymbol, 'autoassign'=false],
   ["IsHamiltonian", "GraphTheory:-IsHamiltonian(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsPlanar", "GraphTheory:-IsPlanar(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsRegular", "GraphTheory:-IsRegular(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["IsStronglyConnected", "GraphTheory:-IsStronglyConnected(ExtractGraph(%EXPR))", digraphsymbol, 'autoassign'=false],
   ["IsTree", "GraphTheory:-IsTree(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false],
   ["IsTwoEdgeConnected", "GraphTheory:-IsTwoEdgeConnected(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false],
   ["IsWeighted", "GraphTheory:-IsWeighted(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false],
   ["MaximumDegree", "GraphTheory:-MaximumDegree(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   ["MinimumDegree", "GraphTheory:-MinimumDegree(ExtractGraph(%EXPR))", undirectedgraphsymbol],
   submenu=["Graph properties"]);

 CM[Entries][AddMultiple](
   ["AntiPrism", "SpecialGraphs:-AntiPrismGraph(%ARG1,1)", graphsymbol,
     entry_generator=proc() [["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end],
   ["Clique", "CompleteGraph(%ARG1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end],
   ["Cube", "SpecialGraphs:-HypercubeGraph(3)", graphsymbol],
   ["Cycle", "CycleGraph(%ARG1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end],
   ["Dodecahedron", "SpecialGraphs:-DodecahedronGraph()", graphsymbol],
   ["Grid", "SpecialGraphs:-GridGraph(%ARG1,%ARG2)", graphsymbol,
     entry_generator=proc() [["3 by 3",[3,3]],["3 by 4",[4,3]],["4 by 4",[4,4]],
                             ["2 by 3",[3,2]],["2 by 4",[4,2]],["2 by 5",[5,2]],
                             ["5 by 3",[3,5]],["5 by 4",[4,5]],["5 by 5",[5,5]]] end],
   ["Hypercube", "SpecialGraphs:-HypercubeGraph(%ARG1)", graphsymbol,
     entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end],
   ["Icosahedron", "SpecialGraphs:-IcosahedronGraph()", graphsymbol],
   ["Octahedron", "SpecialGraphs:-OctahedronGraph()", graphsymbol],
   ["Prism", "SpecialGraphs:-PrismGraph(%ARG1,1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end],
   ["Soccer ball", "SpecialGraphs:-SoccerBallGraph()", graphsymbol],
   ["Tetrahedron", "SpecialGraphs:-TetrahedronGraph()", graphsymbol],
   ["Torus grid", "SpecialGraphs:-TorusGridGraph(%ARG1,%ARG2)", graphsymbol,
     entry_generator=proc() [["3 by 3",[3,3]],["4 by 3",[4,3]],["5 by 3",[5,3]],["6 by 3",[6,3]]] end],
   ["Spider web", "SpecialGraphs:-WebGraph(8,3)", graphsymbol],
   ["Wheel", "SpecialGraphs:-WheelGraph(%ARG1)", graphsymbol,
     entry_generator=proc() [["4",[4]],["5",[5]],["6",[6]],["7",[7]],["8",[8]]] end],
   submenu=["Standard graphs"]);

 CM[Entries][AddMultiple](
   ["Clebsch graph", "SpecialGraphs:-ClebschGraph()", graphsymbol],
   ["Complete binary tree", "SpecialGraphs:-CompleteBinaryTree(%ARG1)", graphsymbol,
     entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]]] end],
   ["Complete k-ary tree", "SpecialGraphs:-CompleteKaryTree(3,3)", graphsymbol],
   ["Complete graph", "CompleteGraph(%ARG1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end],
   ["Desargues graph", "SpecialGraphs:-DesarguesGraph()", graphsymbol],
   ["Double star snark", "SpecialGraphs:-DoubleStarSnark()", graphsymbol],
   ["Dyck graph", "SpecialGraphs:-DyckGraph()", graphsymbol],
   ["Flower snark", "SpecialGraphs:-FlowerSnark(%ARG1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["5",[5]],["7",[7]],["9",[9]]] end],
   ["Foster graph", "SpecialGraphs:-FosterGraph()", graphsymbol],
   ["Goldberg snark", "SpecialGraphs:-GoldbergSnark(%ARG1)", graphsymbol,
     entry_generator=proc() [["3",[3]],["5",[5]],["7",[7]]] end],
   ["Grinberg graph", "SpecialGraphs:-GrinbergGraph()", graphsymbol],
   ["Grotzsch graph", "SpecialGraphs:-GrotzschGraph()", graphsymbol],
   ["Heawood graph", "SpecialGraphs:-HeawoodGraph()", graphsymbol],
   ["Herschel graph", "SpecialGraphs:-HerschelGraph()", graphsymbol],
   ["Kneser graph", "SpecialGraphs:-KneserGraph(5,2)", graphsymbol],
   ["Levi graph", "SpecialGraphs:-LeviGraph()", graphsymbol],
   ["Mobius Kantor graph", "SpecialGraphs:-MobiusKantorGraph()", graphsymbol],
   ["Pappus graph", "SpecialGraphs:-PappusGraph()", graphsymbol],
   ["Petersen graph", "SpecialGraphs:-PetersenGraph()", graphsymbol],
   ["Shrikhande graph", "SpecialGraphs:-ShrikhandeGraph()", graphsymbol],
   ["Szekeres snark", "SpecialGraphs:-SzekeresSnark()", graphsymbol],
   submenu=["Special graphs"]);

  Install(CM);

end use:
