public override void MakeVisual()
        {
            if (GeometryEdge.Curve == null)
            {
                return;
            }
            SetValue(Canvas.LeftProperty, Edge.BoundingBox.Left);
            SetValue(Canvas.TopProperty, Edge.BoundingBox.Bottom);

            if (StrokeDashArray == null)
            {
                // Note that Draw.CreateGraphicsPath returns a curve with coordinates in graph space.
                var pathFigure   = Draw.CreateGraphicsPath((DrawingEdge.GeometryObject as GeometryEdge).Curve);
                var pathGeometry = new PathGeometry();
                pathGeometry.Figures.Add(pathFigure);
                Draw.DrawEdgeArrows(pathGeometry, DrawingEdge, FillArrowheadAtSource, FillArrowheadAtTarget);
                // Apply a translation to bring the coordinates in node space (i.e. top left corner is 0,0).
                pathGeometry.Transform = new MatrixTransform()
                {
                    Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom)
                };

                if (SelectedForEditing && GeometryEdge.UnderlyingPolyline != null)
                {
                    Draw.DrawUnderlyingPolyline(pathGeometry, this);
                }
                var path = new Path()
                {
                    Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush
                };
                Content = path;
            }
            else
            {
                // A dash array has been specified. I don't want to apply it to both the edge and the arrowheads; for this reason, I'm going to split the drawing in two Path instances.
                // This is not done in the general case to keep the number of Paths down.
                var pathFigure   = Draw.CreateGraphicsPath((DrawingEdge.GeometryObject as GeometryEdge).Curve);
                var pathGeometry = new PathGeometry();
                pathGeometry.Figures.Add(pathFigure);
                pathGeometry.Transform = new MatrixTransform()
                {
                    Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom)
                };

                if (SelectedForEditing && GeometryEdge.UnderlyingPolyline != null)
                {
                    Draw.DrawUnderlyingPolyline(pathGeometry, this);
                }
                DoubleCollection dc = new DoubleCollection();
                foreach (double d in StrokeDashArray)
                {
                    dc.Add(d);
                }
                var path1 = new Path()
                {
                    Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush, StrokeDashArray = dc
                };

                pathGeometry           = new PathGeometry();
                pathGeometry.Transform = new MatrixTransform()
                {
                    Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom)
                };
                Draw.DrawEdgeArrows(pathGeometry, DrawingEdge, FillArrowheadAtSource, FillArrowheadAtTarget);
                var path2 = new Path()
                {
                    Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush
                };

                var c = new Grid();
                c.Children.Add(path1);
                c.Children.Add(path2);
                Content = c;
            }
        }