context: /*
   * GrGen: graph rewrite generator tool -- release GrGen.NET 4.4
   * Copyright (C) 2003-2015 Universitaet Karlsruhe, Institut fuer Programmstrukturen und Datenorganisation, LS Goos; and free programmers
   * licensed under LGPL v3 (see LICENSE.txt included in the packaging of this file)
   * www.grgen.net
   */
  
  // by Moritz Kroll, Edgar Jakumeit
  
  using System;
  using System.Diagnostics;
  using System.Collections.Generic;
  using Microsoft.CSharp;
  using System.CodeDom.Compiler;
  using System.Reflection;
  using System.IO;
  using System.Collections;
  using de.unika.ipd.grGen.libGr;
  
  namespace de.unika.ipd.grGen.lgsp
  {
      /// <summary>
      /// An implementation of the INamedGraph interface.
      /// </summary>
      public class LGSPNamedGraph : LGSPGraph, INamedGraph
      {
          internal Dictionary<String, IGraphElement> NameToElem;
          internal Dictionary<IGraphElement, String> ElemToName;
  
          private static IDictionary<IGraphElement, IGraphElement> tmpOldToNewMap; // workaround to hide map parameter passing in copy constructor
  
          private int nextID = 0;
  
          private String GetNextName()
          {
              String nameCandidate;
              do
              {
                  nameCandidate = String.Format("${0,00000000:X}", nextID++);
              }
              while(NameToElem.ContainsKey(nameCandidate));
              return nameCandidate;
          }
  
  
          /// <summary>
          /// Constructs an LGSPNamedGraph object with the given model and capacity, and an automatically generated name.
          /// </summary>
          /// <param name="grmodel">The graph model.</param>
          /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
          public LGSPNamedGraph(IGraphModel grmodel, int capacity)
              : base(grmodel)
          {
              NameToElem = new Dictionary<String, IGraphElement>(capacity);
              ElemToName = new Dictionary<IGraphElement, String>(capacity);
          }
  
          /// <summary>
          /// Constructs an LGSPNamedGraph object with the given model, backend, and capacity, and an automatically generated name.
          /// </summary>
          /// <param name="grmodel">The graph model.</param>
          /// <param name="backend">The backend.</param>
          /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
          public LGSPNamedGraph(IGraphModel grmodel, LGSPBackend backend, int capacity)
              : base(grmodel, backend)
          {
              NameToElem = new Dictionary<String, IGraphElement>(capacity);
              ElemToName = new Dictionary<IGraphElement, String>(capacity);
          }
  
          /// <summary>
          /// Constructs an LGSPNamedGraph object with the given model, name, and capacity.
          /// </summary>
          /// <param name="grmodel">The graph model.</param>
          /// <param name="grname">The name for the graph.</param>
          /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
          public LGSPNamedGraph(IGraphModel grmodel, String grname, int capacity)
              : base(grmodel, grname)
          {
              NameToElem = new Dictionary<String, IGraphElement>(capacity);
              ElemToName = new Dictionary<IGraphElement, String>(capacity);
          }
  
          /// <summary>
          /// Constructs an LGSPNamedGraph object with the given model, backend, name, and capacity.
          /// </summary>
          /// <param name="grmodel">The graph model.</param>
          /// <param name="backend">The backend.</param>
          /// <param name="grname">The name for the graph.</param>
          /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
          public LGSPNamedGraph(IGraphModel grmodel, LGSPBackend backend, String grname, int capacity)
              : base(grmodel, backend, grname)
          {
              NameToElem = new Dictionary<String, IGraphElement>(capacity);
              ElemToName = new Dictionary<IGraphElement, String>(capacity);
          }
  
          /// <summary>
          /// Constructs an LGSPNamedGraph object.
          /// Deprecated.
          /// </summary>
          /// <param name="lgspBackend">The responsible backend object.</param>
          /// <param name="grmodel">The graph model.</param>
          /// <param name="grname">The name for the graph.</param>
          /// <param name="modelassemblyname">The name of the model assembly.</param>
          /// <param name="capacity">The initial capacity for the name maps (performance optimization, use 0 if unsure).</param>
          public LGSPNamedGraph(LGSPBackend lgspBackend, IGraphModel grmodel, String grname, String modelassemblyname, int capacity)
              : base(lgspBackend, grmodel, grname, modelassemblyname)
          {
              NameToElem = new Dictionary<String, IGraphElement>(capacity);
              ElemToName = new Dictionary<IGraphElement, String>(capacity);
          }
  
          /// <summary>
          /// Constructs an LGSPNameGraph object without initializing it.
          /// </summary>
          /// <param name="grname">The name for the graph.</param>
          protected LGSPNamedGraph(String grname)
              : base(grname)
          {
              NameToElem = new Dictionary<String, IGraphElement>();
              ElemToName = new Dictionary<IGraphElement, String>();
          }
  
          /// <summary>
          /// Copy constructor.
          /// </summary>
          /// <param name="dataSource">The LGSPNamedGraph object to get the data from</param>
          /// <param name="newName">Name of the copied graph.</param>
          /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning.</param>
          public LGSPNamedGraph(LGSPNamedGraph dataSource, String newName, out IDictionary<IGraphElement, IGraphElement> oldToNewMap)
              : base(dataSource, newName, out oldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(dataSource.NumNodes + dataSource.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(dataSource.NumNodes + dataSource.NumEdges);
              CopyNames(dataSource, oldToNewMap);
          }
  
          /// <summary>
          /// Copy constructor.
          /// </summary>
          /// <param name="dataSource">The LGSPNamedGraph object to get the data from</param>
          /// <param name="newName">Name of the copied graph.</param>
          public LGSPNamedGraph(LGSPNamedGraph dataSource, String newName)
              : base(dataSource, newName, out tmpOldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(dataSource.NumNodes + dataSource.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(dataSource.NumNodes + dataSource.NumEdges);
              CopyNames(dataSource, tmpOldToNewMap);
              tmpOldToNewMap = null;
          }
  
          /// <summary>
          /// Copy constructor helper.
          /// </summary>
          /// <param name="dataSource">The LGSPNamedGraph object to get the data from</param>
          /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning.</param>
          private void CopyNames(LGSPNamedGraph dataSource, IDictionary<IGraphElement, IGraphElement> oldToNewMap)
          {
              foreach(INode node in dataSource.Nodes)
              {
                  NameToElem[dataSource.GetElementName(node)] = oldToNewMap[node];
                  ElemToName[oldToNewMap[node]] = dataSource.GetElementName(node);
              }
  
              foreach(IEdge edge in dataSource.Edges)
              {
                  NameToElem[dataSource.GetElementName(edge)] = oldToNewMap[edge];
                  ElemToName[oldToNewMap[edge]] = dataSource.GetElementName(edge);
              }
  
              /* TODO: remove when cloning of graph variables was implemented
               * foreach(KeyValuePair<IGraphElement, LinkedList<Variable>> kvp in dataSource.ElementMap)
              {
                  IGraphElement newElem = oldToNewMap[kvp.Key];
                  foreach(Variable var in kvp.Value)
                      SetVariableValue(var.Name, newElem);
              }*/
          }
  
          /// <summary>
          /// Copy and extend constructor, creates a named graph from a normal graph.
          /// Initializes the name maps with anonymous names in the form "$" + GetNextName()
          /// </summary>
          /// <param name="graph">The graph to be used named</param>
          /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning</param>
          public LGSPNamedGraph(LGSPGraph graph, out IDictionary<IGraphElement, IGraphElement> oldToNewMap)
              : base(graph, graph.Name, out oldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(graph.NumNodes + graph.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(graph.NumNodes + graph.NumEdges);
              DoName();
          }
  
          /// <summary>
          /// Copy and extend constructor, creates a named graph from a normal graph.
          /// Initializes the name maps with anonymous names in the form "$" + GetNextName()
          /// </summary>
          /// <param name="graph">The graph to be used named</param>
          public LGSPNamedGraph(LGSPGraph graph)
              : base(graph, graph.Name, out tmpOldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(graph.NumNodes + graph.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(graph.NumNodes + graph.NumEdges);
              tmpOldToNewMap = null;
              DoName();
          }
  
          /// <summary>
          /// Initializes the name maps with anonymous names in the form "$" + GetNextName()
          /// </summary>
          /// <param name="graph">The graph to be used named</param>
          public void DoName()
          {
              foreach(INode node in Nodes)
              {
                  String name = GetNextName();
                  NameToElem[name] = node;
                  ElemToName[node] = name;
              }
  
              foreach(IEdge edge in Edges)
              {
                  String name = GetNextName();
                  NameToElem[name] = edge;
                  ElemToName[edge] = name;
              }
          }
  
          /// <summary>
          /// Copy and extend constructor, creates a named graph from a normal graph.
          /// Initializes the name maps with the names provided in a given attribute each graph element must have
          /// </summary>
          /// <param name="graph">The graph to be used named</param>
          /// <param name="nameAttributeName">The name of the attribute to be used for naming</param>
          /// <param name="oldToNewMap">A map of the old elements to the new elements after cloning</param>
          public LGSPNamedGraph(LGSPGraph graph, String nameAttributeName, out IDictionary<IGraphElement, IGraphElement> oldToNewMap)
              : base(graph, graph.Name, out oldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(graph.NumNodes + graph.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(graph.NumNodes + graph.NumEdges);
              DoName(nameAttributeName);
          }
  
          /// <summary>
          /// Copy and extend constructor, creates a named graph from a normal graph.
          /// Initializes the name maps with the names provided in a given attribute each graph element must have
          /// </summary>
          /// <param name="graph">The graph to be used named</param>
          /// <param name="nameAttributeName">The name of the attribute to be used for naming</param>
          public LGSPNamedGraph(LGSPGraph graph, String nameAttributeName)
              : base(graph, graph.Name, out tmpOldToNewMap)
          {
              NameToElem = new Dictionary<String, IGraphElement>(graph.NumNodes + graph.NumEdges);
              ElemToName = new Dictionary<IGraphElement, String>(graph.NumNodes + graph.NumEdges);
              tmpOldToNewMap = null;
              DoName(nameAttributeName);
          }
  
          /// <summary>
          /// </summary>
          /// <param name="nameAttributeName">The name of the attribute to be used for naming</param>
          public void DoName(String nameAttributeName)
          {
              foreach(INode node in Nodes)
              {
                  AttributeType attrType = node.Type.GetAttributeType(nameAttributeName);
                  if(attrType == null)
                      throw new ArgumentException(String.Format(
                          "Illegal name attribute for node of type {0}!", node.Type.Name));
                  if(attrType.Kind != AttributeKind.StringAttr)
                      throw new ArgumentException("Name attribute is not a string attribute in type {0}!", node.Type.Name);
  
  
gt:                 String name = (String) node.GetAttribute(nameAttributeName);