private void ReadVertex([NotNull] IDictionary <string, TVertex> vertices)
            {
                Debug.Assert(vertices != null);
                Debug.Assert(
                    _reader.NodeType == XmlNodeType.Element &&
                    _reader.Name == NodeTag &&
                    _reader.NamespaceURI == _graphMLNamespace);

                // Get subtree
                using (XmlReader subReader = _reader.ReadSubtree())
                {
                    // Read id
                    string id = ReadAttributeValue(_reader, IdAttribute);
                    // Create new vertex
                    TVertex vertex = _vertexFactory(id);
                    // Apply defaults
                    ReadDelegateCompiler.SetVertexDefault(vertex);
                    // Read data
                    while (subReader.Read())
                    {
                        if (_reader.NodeType == XmlNodeType.Element &&
                            _reader.Name == DataTag &&
                            _reader.NamespaceURI == _graphMLNamespace)
                        {
                            ReadDelegateCompiler.VertexAttributesReader(subReader, _graphMLNamespace, vertex);
                        }
                    }

                    // Add to graph
                    _graph.AddVertex(vertex);
                    vertices.Add(id, vertex);
                }
            }
            private void ReadVertex(Dictionary <string, TVertex> vertices)
            {
                Contract.Requires(vertices != null);
                Contract.Assert(
                    this.Reader.NodeType == XmlNodeType.Element &&
                    this.Reader.Name == "node" &&
                    this.Reader.NamespaceURI == this.graphMLNamespace);

                // get subtree
                using (var subReader = this.Reader.ReadSubtree())
                {
                    // read id
                    string id = ReadAttributeValue(this.Reader, "id");
                    // create new vertex
                    TVertex vertex = vertexFactory(id);
                    // apply defaults
                    ReadDelegateCompiler.SetVertexDefault(vertex);
                    // read data
                    while (subReader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element &&
                            reader.Name == "data" &&
                            reader.NamespaceURI == this.graphMLNamespace)
                        {
                            ReadDelegateCompiler.VertexAttributesReader(subReader, this.graphMLNamespace, vertex);
                        }
                    }
                    // add to graph
                    this.VisitedGraph.AddVertex(vertex);
                    vertices.Add(id, vertex);
                }
            }
            private void ReadEdge(Dictionary <string, TVertex> vertices)
            {
                Contract.Requires(vertices != null);
                Contract.Assert(
                    this.Reader.NodeType == XmlNodeType.Element &&
                    this.Reader.Name == "edge" &&
                    this.Reader.NamespaceURI == this.graphMLNamespace);

                // get subtree
                using (var subReader = this.Reader.ReadSubtree())
                {
                    // read id
                    string  id       = "" + edge_id++; // ReadAttributeValue(this.Reader, "id");
                    string  sourceid = ReadAttributeValue(this.Reader, "source");
                    TVertex source;
                    if (!vertices.TryGetValue(sourceid, out source))
                    {
                        throw new ArgumentException("Could not find vertex " + sourceid);
                    }
                    string  targetid = ReadAttributeValue(this.Reader, "target");
                    TVertex target;
                    if (!vertices.TryGetValue(targetid, out target))
                    {
                        throw new ArgumentException("Could not find vertex " + targetid);
                    }

                    var edge = this.edgeFactory(source, target, id);
                    ReadDelegateCompiler.SetEdgeDefault(edge);

                    // read data
                    while (subReader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element &&
                            reader.Name == "data" &&
                            reader.NamespaceURI == this.graphMLNamespace)
                        {
                            ReadDelegateCompiler.EdgeAttributesReader(subReader, this.graphMLNamespace, edge);
                        }
                    }

                    this.VisitedGraph.AddEdge(edge);
                }
            }
            private void ReadEdge([NotNull] IDictionary <string, TVertex> vertices)
            {
                Debug.Assert(vertices != null);
                Debug.Assert(
                    _reader.NodeType == XmlNodeType.Element &&
                    _reader.Name == EdgeTag &&
                    _reader.NamespaceURI == _graphMLNamespace);

                // Get subtree
                using (XmlReader subReader = _reader.ReadSubtree())
                {
                    // Read id
                    string id       = ReadAttributeValue(_reader, IdAttribute);
                    string sourceId = ReadAttributeValue(_reader, SourceAttribute);
                    if (!vertices.TryGetValue(sourceId, out TVertex source))
                    {
                        throw new ArgumentException($"Could not find vertex {sourceId}.");
                    }
                    string targetId = ReadAttributeValue(_reader, TargetAttribute);
                    if (!vertices.TryGetValue(targetId, out TVertex target))
                    {
                        throw new ArgumentException($"Could not find vertex {targetId}.");
                    }

                    TEdge edge = _edgeFactory(source, target, id);
                    ReadDelegateCompiler.SetEdgeDefault(edge);

                    // Read data
                    while (subReader.Read())
                    {
                        if (_reader.NodeType == XmlNodeType.Element &&
                            _reader.Name == DataTag &&
                            _reader.NamespaceURI == _graphMLNamespace)
                        {
                            ReadDelegateCompiler.EdgeAttributesReader(subReader, _graphMLNamespace, edge);
                        }
                    }

                    _graph.AddEdge(edge);
                }
            }
            private void ReadElements()
            {
                Contract.Requires(
                    this.Reader.Name == "graph" &&
                    this.Reader.NamespaceURI == this.graphMLNamespace,
                    "incorrect reader position");

                ReadDelegateCompiler.SetGraphDefault(this.VisitedGraph);

                var vertices = new Dictionary <string, TVertex>(StringComparer.Ordinal);

                edge_id = 0;

                // read vertices or edges
                var reader = this.Reader;

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element &&
                        reader.NamespaceURI == this.graphMLNamespace)
                    {
                        switch (reader.Name)
                        {
                        case "node":
                            this.ReadVertex(vertices);
                            break;

                        case "edge":
                            this.ReadEdge(vertices);
                            break;

                        //case "data":
                        //    GraphMLDeserializer<TVertex, TEdge, TGraph>.ReadDelegateCompiler.GraphAttributesReader(this.Reader, this.graphMLNamespace, this.VisitedGraph);
                        //    break;
                        default:
                            //throw new InvalidOperationException(String.Format("invalid reader position {0}:{1}", this.Reader.NamespaceURI, this.Reader.Name));
                            break;
                        }
                    }
                }
            }
            private void ReadElements()
            {
                Debug.Assert(
                    _reader.Name == GraphTag && _reader.NamespaceURI == _graphMLNamespace,
                    "Incorrect reader position.");

                ReadDelegateCompiler.SetGraphDefault(_graph);

                var vertices = new Dictionary <string, TVertex>(StringComparer.Ordinal);

                // Read vertices or edges
                XmlReader reader = _reader;

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element &&
                        reader.NamespaceURI == _graphMLNamespace)
                    {
                        switch (reader.Name)
                        {
                        case NodeTag:
                            ReadVertex(vertices);
                            break;

                        case EdgeTag:
                            ReadEdge(vertices);
                            break;

                        case DataTag:
                            ReadDelegateCompiler.GraphAttributesReader(_reader, _graphMLNamespace, _graph);
                            break;

                        default:
                            throw new InvalidOperationException($"Invalid reader position {_reader.NamespaceURI}: {_reader.Name}.");
                        }
                    }
                }
            }