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