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);
                }
            }