private async void MyDrawObject_DrawComplete(object sender, DrawEventArgs args)
        {
            try
            {
                _myDrawObject.IsEnabled = false;

                if (_cts != null)
                {
                    _cts.Cancel();
                }

                _cts = new CancellationTokenSource();

                QueryTask queryTask =
                    new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsParcelCharacteristics/MapServer/1");
                Query query = new Query()
                {
                    Geometry            = args.Geometry,
                    ReturnGeometry      = true,
                    OutSpatialReference = MyMap.SpatialReference
                };

                QueryResult parcelsToIntersectResult = await queryTask.ExecuteTaskAsync(query, _cts.Token);

                List <Graphic> graphicList = new List <Graphic>();
                graphicList.Add(new Graphic()
                {
                    Geometry = args.Geometry
                });
                SimplifyResult simplifiedIntersectGeometryResult = await _geometryService.SimplifyTaskAsync(graphicList, _cts.Token);

                IntersectResult intersectedParcelsResult = await _geometryService.IntersectTaskAsync(parcelsToIntersectResult.FeatureSet.ToList(), simplifiedIntersectGeometryResult.Results[0].Geometry, _cts.Token);

                Random random = new Random();
                foreach (Graphic g in intersectedParcelsResult.Results)
                {
                    SimpleFillSymbol symbol = new SimpleFillSymbol()
                    {
                        Fill = new System.Windows.Media.SolidColorBrush(
                            System.Windows.Media.Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255),
                                                                (byte)random.Next(0, 255))),
                        BorderBrush     = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Black),
                        BorderThickness = 1
                    };
                    g.Symbol = symbol;
                    _intersectGraphicsLayer.Graphics.Add(g);
                }
            }
            catch (Exception ex)
            {
                if (ex is ServiceException)
                {
                    MessageBox.Show(String.Format("{0}: {1}", (ex as ServiceException).Code.ToString(), (ex as ServiceException).Details[0]), "Error", MessageBoxButton.OK);
                    return;
                }
            }
        }
        // Main simplifying function.
        // Should be called asynchronously to show status texts at each step.
        public IEnumerable <string> ApplySimplifyingStep()
        {
            SimplifyResult = SimplifyResult.CannotSimplifyAgain;

            List <Graph> newGraphParts = new List <Graph>();

            // PREPROCESSING 1: If the graph is not connected, then consider each component separately.
            foreach (Graph graphPart in GraphParts)
            {
                newGraphParts.AddRange(graphPart.SplitDisonnectedComponents());
            }
            if (newGraphParts.Count > GraphParts.Count)
            {
                // When no simplification is done in a simplify step, then it can be said
                // that the graph can no longer be simplified.
                // Here, we did a simplification and we may simplify again in the next step.
                SimplifyResult = SimplifyResult.CanSimplifyAgain;
                GraphParts     = newGraphParts;
            }

            yield return("PREPROCESS STEP 1: Seperated disconnected components...");

            newGraphParts = new List <Graph>();

            // PREPROCESSING 2: If the graph has cut-vertices, then test each block separately.
            foreach (Graph graphPart in GraphParts)
            {
                CutVerticesFinder cvf      = new CutVerticesFinder();
                List <Node>       cutNodes = cvf.FindCutVertices(graphPart);
                if (cutNodes != null && cutNodes.Count > 1)
                {
                    SimplifyResult = SimplifyResult.CanSimplifyAgain;
                    // Since we consider "blocks" we need to add back the edges incident to
                    // cut nodes to get blocks including cut nodes and their edges.
                    List <Edge> edgesToAddBack = new List <Edge>();
                    foreach (Node cutNode in cutNodes)
                    {
                        List <Edge> edges = graphPart.GetEdges(cutNode);
                        edgesToAddBack.AddRange(edges);
                        // Cut nodes AND their edges are removed,
                        // they will be added back to corresponding blocks.
                        edges.ForEach(e => graphPart.Edges.Remove(e));
                        graphPart.Nodes.Remove(cutNode);
                    }
                    foreach (Graph disonnectedComponent in graphPart.SplitDisonnectedComponents())
                    {
                        // Now we add back the edges.
                        foreach (Edge edgeToAddBack in edgesToAddBack)
                        {
                            Node nodeInComponent = disonnectedComponent.Nodes.FirstOrDefault(n => n == edgeToAddBack.Node1 || n == edgeToAddBack.Node2);
                            if (nodeInComponent != null)
                            {
                                Node cutNode = edgeToAddBack.Node1 == nodeInComponent ? edgeToAddBack.Node2 : edgeToAddBack.Node1;
                                disonnectedComponent.AddNode(cutNode);
                                disonnectedComponent.AddEdge(edgeToAddBack);
                            }
                        }
                        newGraphParts.Add(disonnectedComponent);
                    }
                }
                else
                {
                    newGraphParts.Add(graphPart);
                }
            }
            GraphParts = newGraphParts;

            yield return("PREPROCESS STEP 2: If the graph has cut vertices, seperated all blocks of the graph...");

            // PREPROCESSING 3: Each vertex of degree 2 plus its incident edges can be replaced by a single edge.
            foreach (Graph graphPart in GraphParts)
            {
                for (int i = 0; i < graphPart.Nodes.Count; i++)
                {
                    List <Edge> edges = graphPart.GetEdges(graphPart.Nodes[i]);
                    if (edges.Count == 1)
                    {
                        // Node with degree 1 is irrelevant to planarity, we can just remove.
                        // This step may even be not needed (already removed previously).
                        graphPart.Edges.Remove(edges[0]);
                        graphPart.Nodes.Remove(graphPart.Nodes[i]);
                        i--;
                        SimplifyResult = SimplifyResult.CanSimplifyAgain;
                    }
                    if (edges.Count == 2)
                    {
                        // Node with degree 2, delete node and merge edges.
                        Node node1 = edges[0].Node1 == graphPart.Nodes[i] ? edges[0].Node2 : edges[0].Node1;
                        Node node2 = edges[1].Node1 == graphPart.Nodes[i] ? edges[1].Node2 : edges[1].Node1;
                        graphPart.Edges.Remove(edges[0]);
                        graphPart.Edges.Remove(edges[1]);
                        graphPart.Nodes.Remove(graphPart.Nodes[i]);
                        graphPart.GetOrCreateEdge(node1, node2);
                        i--;
                        SimplifyResult = SimplifyResult.CanSimplifyAgain;
                    }
                }
            }

            yield return("PREPROCESS STEP 3: Each vertex of degree 2 plus its incident edges is replaced by a single edge...");

            // Remove planar components from "GraphParts" or determine if any of components are non-planar
            List <Graph> partsToRemove = new List <Graph>();

            foreach (Graph graphPart in GraphParts)
            {
                int n = graphPart.Nodes.Count;
                int e = graphPart.Edges.Count;
                if (n < 5 || e < 9)
                {
                    partsToRemove.Add(graphPart);
                }
                else if (e > 3 * n - 6)
                {
                    PlanarityResult = PlanarityResult.NonPlanar;
                }
            }

            foreach (Graph graph in partsToRemove)
            {
                GraphParts.Remove(graph);
            }

            if (GraphParts.Count == 0)
            {
                PlanarityResult = PlanarityResult.Planar;
            }

            yield return("PREPROCESS STEP 4: Removed planar components...");
        }