string GetConnectorViewStateKey(ModelItem linkModelItem, ConnectionPoint srcConnPoint)
 {
     string viewStateKey = ConnectorViewStateKey;
     if ((typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType)))
     {
         if (srcConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             viewStateKey = TrueConnectorViewStateKey;
         }
         else
         {
             viewStateKey = FalseConnectorViewStateKey;
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             viewStateKey = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             viewStateKey = link.CaseName + CaseViewStateKeyAppendString;
         }
     }
     return viewStateKey;
 }
 //Returns a new connector if viewstate exists, null otherwise.
 Connector GetConnectorViewState(UIElement source, UIElement dest, ModelItem linkModelItem, ConnectionPoint sourceConnectionPoint)
 {
     Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
     Connector connector = null;
     object connectorLocation = null;
     if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
     {
         Fx.Assert(sourceConnectionPoint != null, "Source connection point is null.");
         if (sourceConnectionPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, TrueConnectorViewStateKey);
         }
         else
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, FalseConnectorViewStateKey);
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         string key = null;
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             key = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             key = link.CaseName + CaseViewStateKeyAppendString;
         }
         //Transitioning from fake ModelItem world to real ModelItem world.
         ModelItem realFSModelItem = (this.ModelItem as IModelTreeItem).ModelTreeManager.WrapAsModelItem(link.ParentFlowSwitch);
         connectorLocation = this.ViewStateService.RetrieveViewState(realFSModelItem, key);
     }
     else
     {
         connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, ConnectorViewStateKey);
     }
     PointCollection locationPts = connectorLocation as PointCollection;
     if (locationPts != null)
     {
         ConnectionPoint srcConnPoint, destConnPoint;
         System.Diagnostics.Debug.WriteLine(this.isLoaded ? "About to call ConnectionPointHitTest - Loaded" : "About to call ConnectionPointHitTest - Not Loaded");
         srcConnPoint = ConnectionPointHitTest(source, locationPts[0]);
         destConnPoint = ConnectionPointHitTest(dest, locationPts[locationPts.Count - 1]);
         //In Debug mode, the size of the designer changes due to the debug adorner(border). Because of this connection points will move and
         //won't coincide with the viewstate.
         //The following code path is added for the scenario where we reload the flowchart designer by navigating back and forth on breadcrumb
         //when one of the flowchart activities has the debug border.
         //In this scenario we try to find the closest connection point from the end point stored in viewstate. If the distance between the two
         //is within the acceptable range, we will reuse the viewstate and avoid re-drawing the connector.
         if (this.IsReadOnly)
         {
             ConnectionPoint pt;
             double dist;
             if (srcConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[0], FlowchartDesigner.GetConnectionPoints(source), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Incoming && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     srcConnPoint = pt;
                 }
             }
             if (destConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[locationPts.Count - 1], FlowchartDesigner.GetConnectionPoints(dest), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Outgoing && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     destConnPoint = pt;
                 }
             }
         }
         if (srcConnPoint != null && destConnPoint != null)
         {
             connector = GetConnector(linkModelItem, srcConnPoint, destConnPoint);
             connector.Points = locationPts;
         }
     }
     return connector;
 }
        bool UpdateFlowChartObject(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, out string errorMessage, bool isLinkValidDueToLinkMove, IFlowSwitchLink caseKey)
        {
            //srcDesigner will be null for the case where source designer is StartSymbol.
            VirtualizedContainerService.VirtualizingContainer srcDesigner = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            ModelItem linkSource;
            ModelItem linkDest = destDesigner.ModelItem;
            ModelItem destFlowElementMI = GetFlowElementMI(linkDest);
            PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
            errorMessage = string.Empty;
            
            if (sourceConnPoint.ParentDesigner is StartSymbol)
            {
                linkSource = this.ModelItem;
                if (linkSource.Properties["StartNode"].Value == null || isLinkValidDueToLinkMove)
                {
                    this.StoreConnectorViewState(linkSource, connectorViewState, sourceConnPoint);
                    linkSource.Properties["StartNode"].SetValue(destFlowElementMI);
                }
                else
                {
                    errorMessage = SR.FCNextLinkDefined;
                }
            }
            else
            {
                linkSource = srcDesigner.ModelItem;
                ModelItem srcFlowElementMI = GetFlowElementMI(linkSource);

                if (typeof(FlowStep).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (srcFlowElementMI.Properties["Next"].Value == null || isLinkValidDueToLinkMove)
                    {
                        this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                        srcFlowElementMI.Properties["Next"].SetValue(destFlowElementMI);
                    }
                    else
                    {
                        errorMessage = SR.FCNextLinkDefined;
                    }
                }
                else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (sourceConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["True"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["True"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCTrueBranchExists;
                        }
                    }
                    else if (sourceConnPoint.Equals(FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["False"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["False"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCFalseBranchExists;
                        }
                    }
                    else
                    {
                        errorMessage = SR.FCFlowConditionLinkError;
                    }

                }
                else //FlowSwitch
                {
                    if (!CreateFlowSwitchLink(sourceConnPoint, srcFlowElementMI, destFlowElementMI, caseKey, connectorViewState, ref errorMessage))
                    {
                        return false;
                    }
                }
            }
            return errorMessage.Equals(string.Empty);
        }