protected override bool LoadView()
        {
            var ret = false;

            var isDocDataDirty = 0;
            // Save IsDocDataDirty flag here to be set back later. 
            // This is because loading-view can cause the flag to be set since a new diagram could potentially created.
            DocData.IsDocDataDirty(out isDocDataDirty);
            IsLoading = true;
            try
            {
                var uri = Utils.FileName2Uri(DocData.FileName);
                _context = PackageManager.Package.DocumentFrameMgr.EditingContextManager.GetNewOrExistingContext(uri);
                Debug.Assert(_context != null, "_context should not be null");

                // Set DSL Diagram instance and values.
                // Note: the code should be executed before we suspend rule notification. The diagram shapes will not created correctly if we don't.

                // When document is reloaded, a new diagram will be created; so we always need to check for the new view diagram every time LoadView is called.
                var currentDiagram = GetNewOrExistingViewDiagram();
                if (Diagram != currentDiagram)
                {
                    Diagram = currentDiagram;
                }

                // Ensure that cache _xRef is cleared.
                _xRef = null;

                // The only case where diagram is null at this point is that VS tries to open diagram that doesn't exist in our model.
                // One of the possibilities: the user creates multiple diagrams, open the diagrams in VS, then close the project without saving the document.
                // When the project is reopened in the same VS, VS remembers any opened windows and will try to reopen it.
                // In this case, we should close the frame.
                if (Diagram == null)
                {
                    // Return false will force the window frame to be closed.
                    return false;
                }

                ApplyLayoutInformationFromModelDiagram();

                Debug.Assert(DocData.Store.RuleManager.IsRuleSuspended == false, "The rule notification should not be suspended.");
                DocData.Store.RuleManager.SuspendRuleNotification();

                // We don't call base.LoadView() because the code assumes there is only 1 diagram (will assert otherwise),
                // and will always choose the first diagram.
                if (BaseLoadView())
                {
                    // Normally our toolbox items get populated only when the window is activated, but
                    // in certain circumstances we may switch the mode of our designer (normal/safe-mode/etc)
                    // when the window is already active. This is an expensive operation so we only need it when
                    // we reload the active document.
                    var escherDocData = DocData as MicrosoftDataEntityDesignDocData;
                    if (escherDocData != null
                        && escherDocData.IsHandlingDocumentReloaded)
                    {
                        ToolboxService.Refresh();
                    }
                    ret = true;
                }

                // Listen to Diagram Title change event so we can update our window caption with the information.
                var entityDesignerDiagram = Diagram as EntityDesignerDiagram;
                Debug.Assert(entityDesignerDiagram != null, "The diagram is not the type of EntityDesignerDiagram");
                if (entityDesignerDiagram != null)
                {
                    entityDesignerDiagram.OnDiagramTitleChanged += OnDiagramTitleChanged;
                }
                UpdateWindowFrameCaption();
            }
            finally
            {
                // After Diagram is set, DSL code enabled DSL Undo Manager, so the code below is to disable it.
                if (DocData.Store.UndoManager.UndoState == DslModeling.UndoState.Enabled)
                {
                    DocData.Store.UndoManager.UndoState = DslModeling.UndoState.Disabled;
                }

                if (DocData.Store.RuleManager.IsRuleSuspended)
                {
                    DocData.Store.RuleManager.ResumeRuleNotification();
                }
                DocData.SetDocDataDirty(isDocDataDirty);
                IsLoading = false;
            }
            return ret;
        }
        /// <summary>
        ///     Updates corresponding view model item.
        ///     For simplicity each change updates all item values.
        /// </summary>
        private void OnEFObjectUpdated(EfiChange change, ModelToDesignerModelXRefItem xref)
        {
            Debug.Assert(change.Changed != null);
            var efObject = change.Changed;

            // Updating a base type is a special case, because it really means creating or deleting an inheritance connector
            var baseType = efObject as EntityTypeBaseType;
            if (baseType != null)
            {
                if (xref.ContainsKey(baseType.Parent))
                {
                    // always recreate inheritance
                    OnEFObjectDeleted(baseType, xref);
                    if (xref.ContainsKey(baseType.Parent))
                    {
                        ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext).SynchronizeSingleDslModelElement(this, efObject);
                    }
                }
                return;
            }

            // for AssociationEnd we want to update parent Association
            var associationEnd = efObject as AssociationEnd;
            if (associationEnd != null)
            {
                efObject = associationEnd.Parent;
            }

            // regardless the change always update whole element (it shouldn't be too big overhead)
            OnEFObjectCreatedOrUpdated(efObject, xref);
        }
        private void OnEFObjectCreatedOrUpdated(EFObject efObject, ModelToDesignerModelXRefItem xref)
        {
            Debug.Assert(efObject != null);

            if (false == ModelHelper.IsInConceptualModel(efObject))
            {
                return; // ignore events from storage model
            }

            // special case for creating base type
            var baseType = efObject as EntityTypeBaseType;
            if (baseType != null)
            {
                if (xref.ContainsKey(baseType.Parent))
                {
                    ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext).SynchronizeSingleDslModelElement(this, efObject);
                }
                return;
            }

            var efElement = efObject as EFElement;
            if (efElement == null)
            {
                efElement = efObject.Parent as EFElement;
            }

            if (efElement != null)
            {
                var modelRoot = efElement as ConceptualEntityModel;
                if (modelRoot != null)
                {
                    Namespace = modelRoot.Namespace.Value;
                    return;
                }

                var modelEntityType = efElement as ConceptualEntityType;
                if (modelEntityType != null)
                {
                    var viewEntityType = xref.GetExisting(modelEntityType) as EntityType;
                    if (viewEntityType != null)
                    {
                        //update only
                        ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                            .SynchronizeSingleDslModelElement(this, modelEntityType);
                    }
                        // Check to see if EFObject is type of ConceptualEntityType.
                        // This is to prevent that the scenario updating entity-type name causes a new entity-type to be created in different diagram.
                    else if (efObject is ConceptualEntityType)
                    {
                        //create EntityType and add it to the view model
                        viewEntityType =
                            ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                .SynchronizeSingleDslModelElement(this, modelEntityType) as EntityType;
                        EntityTypes.Add(viewEntityType);
                    }

                    return;
                }

                var modelProperty = efElement as Model.Entity.Property;
                if (modelProperty != null)
                {
                    var entityType = modelProperty.Parent as Model.Entity.EntityType;
                    if (entityType != null)
                    {
                        var viewEntityType = xref.GetExisting(entityType) as EntityType;
                        // If the view Entity Type does not exist skip, continue since nothing to update.
                        if (viewEntityType != null)
                        {
                            var viewProperty = xref.GetExisting(modelProperty) as Property;
                            if (viewProperty != null)
                            {
                                //update only
                                ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                    .SynchronizeSingleDslModelElement(viewEntityType, modelProperty);
                            }
                            else
                            {
                                //create property and add it to view's EntityType
                                viewProperty =
                                    ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                        .SynchronizeSingleDslModelElement(viewEntityType, modelProperty) as Property;
                                Debug.Assert(viewProperty != null, "Why DSL property is null?");
                                if (viewProperty != null)
                                {
                                    // Determine where we should insert the new property by getting the previous sibling.
                                    var previousSibling = FindPreviousProperty(viewProperty) as Property;
                                    if (previousSibling != null)
                                    {
                                        // Get the index of the previous sibling.
                                        var propertyIndex = viewEntityType.Properties.IndexOf(previousSibling);
                                        Debug.Assert(
                                            propertyIndex >= 0,
                                            "Unable to find index of DSL property: " + previousSibling.Name + " in entity:"
                                            + viewEntityType.Name);
                                        if (propertyIndex >= 0)
                                        {
                                            viewEntityType.Properties.Insert(propertyIndex + 1, viewProperty);
                                        }
                                    }
                                    else
                                    {
                                        // if previous sibling is null, that means we need to insert the property as the first property of the entity-type.
                                        viewEntityType.Properties.Insert(0, viewProperty);
                                    }
                                }
                            }
                        }
                    }
                    return;
                }

                var modelAssociationEnd = efElement as AssociationEnd;
                if (modelAssociationEnd != null)
                {
                    // change focus to the association and it will be processed below
                    efElement = modelAssociationEnd.Parent as EFElement;
                }

                var modelAssociation = efElement as Model.Entity.Association;
                if (modelAssociation != null)
                {
                    // this will create association if necessary (if not it's update only)
                    ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                        .SynchronizeSingleDslModelElement(this, modelAssociation);
                    return;
                }

                var modelNavigationProperty = efElement as Model.Entity.NavigationProperty;
                if (modelNavigationProperty != null)
                {
                    var entityType = modelNavigationProperty.Parent as Model.Entity.EntityType;
                    Debug.Assert(entityType != null);

                    var viewEntityType = xref.GetExisting(entityType) as EntityType;

                    if (viewEntityType != null)
                    {
                        var viewNavigationProperty = xref.GetExisting(modelNavigationProperty) as NavigationProperty;
                        if (viewNavigationProperty != null)
                        {
                            //update only
                            ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                .SynchronizeSingleDslModelElement(viewEntityType, modelNavigationProperty);
                        }
                        else
                        {
                            //create navigation property and add it to view's EntityType
                            viewNavigationProperty =
                                ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                    .SynchronizeSingleDslModelElement(viewEntityType, modelNavigationProperty) as NavigationProperty;
                            Debug.Assert(viewNavigationProperty != null, "Why DSL navigation property is null?");
                            if (viewNavigationProperty != null)
                            {
                                var previousSibling = FindPreviousProperty(viewNavigationProperty) as NavigationProperty;
                                if (previousSibling != null)
                                {
                                    var propertyIndex = viewEntityType.NavigationProperties.IndexOf(previousSibling);
                                    Debug.Assert(
                                        propertyIndex >= 0,
                                        "Unable to find index of DSL navigation property: " + previousSibling.Name + " in entity:"
                                        + viewEntityType.Name);
                                    if (propertyIndex >= 0)
                                    {
                                        viewEntityType.NavigationProperties.Insert(propertyIndex + 1, viewNavigationProperty);
                                    }
                                }
                                else
                                {
                                    // if previous sibling is null, that means we need to insert the property as the first navigation property of the entity-type.
                                    viewEntityType.NavigationProperties.Insert(0, viewNavigationProperty);
                                }
                            }
                        }
                    }
                    return;
                }

                // see if we are creating the Key element or just a PropertyRef
                var key = efElement as Key;
                var propertyRefs = new List<PropertyRef>();

                if (key != null)
                {
                    // if this is true, we are not necessarily creating the Key element with only one property ref element - 
                    // we may be handling an undo operation, and there may be more than one property ref element.
                    foreach (var propRef in key.PropertyRefs)
                    {
                        propertyRefs.Add(propRef);
                    }
                }
                else
                {
                    var propertyRef = efElement as PropertyRef;
                    if (propertyRef != null)
                    {
                        propertyRefs.Add(propertyRef);
                    }
                }

                if (propertyRefs.Count > 0)
                {
                    foreach (var propRef in propertyRefs)
                    {
                        if (propRef != null
                            && propRef.Parent is Key)
                        {
                            var property = propRef.Name.Target;
                            if (property != null)
                            {
                                var entityType = property.Parent as Model.Entity.EntityType;
                                Debug.Assert(entityType != null);

                                var viewEntityType = xref.GetExisting(entityType) as EntityType;

                                if (viewEntityType != null)
                                {
                                    ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                        .SynchronizeSingleDslModelElement(viewEntityType, property);
                                }
                            }
                        }
                    }
                    return;
                }
            }
        }
        private void OnEFObjectDeleted(EFObject efObject, ModelToDesignerModelXRefItem xref)
        {
            Debug.Assert(efObject != null);

            // deleting key means that we will have to re-translate the properties of the
            // EntityType because the propertyRefs were deleted
            var key = efObject as Key;
            if (key != null
                && key.Parent != null)
            {
                var entityType = key.Parent as Model.Entity.EntityType;
                if (entityType != null)
                {
                    var viewEntityType = xref.GetExisting(entityType) as EntityType;
                    if (viewEntityType != null)
                    {
                        // Only translate properties that are in the view model
                        foreach (var property in entityType.Properties().Where(p => xref.GetExisting(p) != null))
                        {
                            ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                                .SynchronizeSingleDslModelElement(viewEntityType, property);
                        }
                    }
                }
                return;
            }

            // deleting key's propertyref means removing property from entity's key
            var propertyRef = efObject as PropertyRef;
            if (propertyRef != null
                && propertyRef.Parent is Key)
            {
                var property = propertyRef.Name.Target;
                if (property != null)
                {
                    var entityType = property.Parent as Model.Entity.EntityType;
                    Debug.Assert(entityType != null);

                    var viewEntityType = xref.GetExisting(entityType) as EntityType;
                    var viewProperty = xref.GetExisting(property) as Property;
                    // if we are deleting whole EntityType this will be null
                    if (viewEntityType != null
                        && viewProperty != null)
                    {
                        ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                            .SynchronizeSingleDslModelElement(viewEntityType, property);
                    }
                }
                return;
            }

            var modelProperty = efObject.Parent as ComplexConceptualProperty;
            if (modelProperty != null)
            {
                var entityType = modelProperty.Parent as Model.Entity.EntityType;
                if (entityType != null)
                {
                    var viewEntityType = xref.GetExisting(entityType) as EntityType;
                    if (viewEntityType != null)
                    {
                        Debug.Assert(xref.ContainsKey(modelProperty), "view for modelProperty not found");
                        ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext)
                            .SynchronizeSingleDslModelElement(viewEntityType, modelProperty);
                    }
                }
                return;
            }

            ModelElement modelElement = null;

            var et = efObject as ConceptualEntityType;
            if (et != null)
            {
                foreach (var prop in et.Properties())
                {
                    modelElement = xref.GetExisting(prop);
                    if (modelElement != null)
                    {
                        ModelXRef.Remove(prop, modelElement);
                        modelElement.Delete();
                    }
                }
                foreach (var prop in et.NavigationProperties())
                {
                    modelElement = xref.GetExisting(prop);
                    if (modelElement != null)
                    {
                        ModelXRef.Remove(prop, modelElement);
                        modelElement.Delete();
                    }
                }
            }

            // If a diagram is deleted and the diagram is the only diagram that is opened in VS, we need to open the first diagram.
            // The assumption is that there will be another diagram exists in the model because the user can't delete a diagram if the diagram is the only diagram in the model.
            // We need to do this to ensure Model-Browser window is not closed and there at least 1 active designer for the EDMX in VS.
            var modelDiagram = efObject as ModelDesigner.Diagram;
            var currentDiagram = GetDiagram();
            if (null != currentDiagram
                && null != modelDiagram
                && currentDiagram.DiagramId == modelDiagram.Id.Value)
            {
                var foundAnotherActiveDiagram = false;
                // Check if there is any active diagram in VS.
                foreach (var diagram in Store.ElementDirectory.FindElements<EntityDesignerDiagram>())
                {
                    if (currentDiagram != diagram
                        && diagram.ActiveDiagramView != null
                        && diagram.IsDeleted == false
                        && diagram.IsDeleting == false)
                    {
                        foundAnotherActiveDiagram = true;
                        break;
                    }
                }

                if (!foundAnotherActiveDiagram)
                {
                    var service = EditingContext.GetEFArtifactService();
                    var entityDesignArtifact = service.Artifact as EntityDesignArtifact;
                    Debug.Assert(entityDesignArtifact != null, "EFArtifactService's artifact is null.");
                    if (entityDesignArtifact != null)
                    {
                        var firstModelDiagram = entityDesignArtifact.DesignerInfo.Diagrams.FirstDiagram;

                        // firstModelDiagram should never be equal to the diagram that was deleted.
                        Debug.Assert(
                            firstModelDiagram != null && firstModelDiagram != modelDiagram, "There is no valid diagram in the model.");

                        if (firstModelDiagram != null
                            && firstModelDiagram != modelDiagram)
                        {
                            // Change the DiagramID and reload.
                            currentDiagram.DiagramId = firstModelDiagram.Id.Value;
                            // Unfortunately we could not call ClearAndReloadDiagram here because a DSL transaction has been opened before this method is called; 
                            // Need to make wait until the transaction is committed.
                            _shouldClearAndReloadDiagram = true;
                            return;
                        }
                    }
                }
            }

            modelElement = xref.GetExisting(efObject);
            if (modelElement != null)
            {
                ModelXRef.Remove(efObject, modelElement);
                modelElement.Delete();
            }
        }