/// <summary>
        /// Called whenever properties change.
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnElementPropertyChanged(DslModeling::ElementPropertyChangedEventArgs args)
        {
			if (args.DomainProperty.Id == global::Tum.PDE.ModelingDSL.ConversionModelInfo.HasModelChangedDomainPropertyId)
                OnPropertyChanged("HasModelChanged");
        }
		/// <summary>
        /// Called whenever a relationship of type DomainElementReferencesDEType is deleted and
        /// the element hosted by this model is the source.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnElementTypeRemoved(DslModeling::ElementDeletedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType con = args.ModelElement as global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType;
            if (con != null)
            {
                DeleteElementType(con.DEType);
            }
		}
		/// <summary>
        /// Called whenever properties change.
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnElementPropertyChanged(DslModeling::ElementPropertyChangedEventArgs args)
        {
			if (args.DomainProperty.Id == global::Tum.PDE.ModelingDSL.DomainProperty.ValueDomainPropertyId)
                OnPropertyChanged("Value");
        }
		/// <summary>
        /// Called whenever a relationship of type DomainPropertyReferencesDomainType is added and
        /// the element hosted by this model is the source.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnDomainTypeAdded(DslModeling::ElementAddedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.DomainPropertyReferencesDomainType con = args.ModelElement as global::Tum.PDE.ModelingDSL.DomainPropertyReferencesDomainType;
            if (con != null)
            {
                AddDomainType(con.DomainType);
            }
		}
		/// <summary>
        /// Called on a role player changing.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnTargetsChanged(DslModeling::RolePlayerChangedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.ReferenceRelationship con = args.ElementLink as global::Tum.PDE.ModelingDSL.ReferenceRelationship;
            if (con != null)
            {
                if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.ReferenceRelationship.SourceDomainRoleId)
                {
                    if (args.OldRolePlayerId == this.Element.Id)
                       DeleteTargets(con.Target);

                    if (args.NewRolePlayerId == this.Element.Id)
                        AddTargets(con.Target);
                }
				else if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.ReferenceRelationship.TargetDomainRoleId)
				{
					if( args.OldRolePlayer != null )
                        DeleteTargets(args.OldRolePlayer as global::Tum.PDE.ModelingDSL.ReferenceableElement);

                    if( args.NewRolePlayer != null )
                        AddTargets(args.NewRolePlayer as global::Tum.PDE.ModelingDSL.ReferenceableElement);
				}
            }
		}
 /// <summary>
 ///     Translate Model to DSL Model.
 /// </summary>
 /// <param name="modelElement"></param>
 /// <param name="partition"></param>
 /// <returns></returns>
 internal abstract DslModeling.ModelElement TranslateModelToDslModel(EFObject modelElement, DslModeling.Partition partition);
		/// <summary>
        /// Called whenever properties change.
        /// </summary>
        /// <param name="args"></param>
        protected override void OnElementPropertyChanged(DslModeling::ElementPropertyChangedEventArgs args)
        {
			base.OnElementPropertyChanged(args);
			
			if (args.DomainProperty.Id == global::Tum.PDE.ModelingDSL.NamedDomainElement.DescriptionDomainPropertyId)
                OnPropertyChanged("Description");
        }
		/// <summary>
        /// Called whenever a relationship of type ReferenceRelationship is deleted and
        /// the element hosted by this model is the source.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnTargetsRemoved(DslModeling::ElementDeletedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.ReferenceRelationship con = args.ModelElement as global::Tum.PDE.ModelingDSL.ReferenceRelationship;
            if (con != null)
            {
                DeleteTargets(con.Target);
            }
		}
		/// <summary>
        /// Called whenever a relationship of type EmbeddingRelationship is deleted and
        /// the element hosted by this model is the source.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnParentRemoved(DslModeling::ElementDeletedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.EmbeddingRelationship con = args.ModelElement as global::Tum.PDE.ModelingDSL.EmbeddingRelationship;
            if (con != null)
            {
                DeleteParent(con.Parent);
            }
		}
		/// <summary>
        /// Called on a role player changing.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnParentChanged(DslModeling::RolePlayerChangedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.EmbeddingRelationship con = args.ElementLink as global::Tum.PDE.ModelingDSL.EmbeddingRelationship;
            if (con != null)
            {
                if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.EmbeddingRelationship.ChildDomainRoleId)
                {
                    if (args.OldRolePlayerId == this.Element.Id)
                       DeleteParent(con.Parent);

                    if (args.NewRolePlayerId == this.Element.Id)
                        AddParent(con.Parent);
                }
				else if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.EmbeddingRelationship.ParentDomainRoleId)
				{
					if( args.OldRolePlayer != null )
                        DeleteParent(args.OldRolePlayer as global::Tum.PDE.ModelingDSL.EmbeddableElement);

                    if( args.NewRolePlayer != null )
                        AddParent(args.NewRolePlayer as global::Tum.PDE.ModelingDSL.EmbeddableElement);
				}
            }
		}
        internal override DslModeling.ModelElement TranslateModelToDslModel(EFObject modelElement, DslModeling.Partition partition)
        {
            DesignerModel.Diagram diagram = null;

            if (modelElement != null)
            {
                diagram = modelElement as DesignerModel.Diagram;
                if (diagram == null)
                {
                    throw new ArgumentException("modelElement should be a diagram");
                }
            }

            // get the service so that we can access the root of the entity model
            var service = _editingContext.GetEFArtifactService();
            if (service == null)
            {
                throw new InvalidOperationException(EntityDesignerResources.Error_NoArtifactService);
            }

            EntityDesignerViewModel entityViewModel = null;

            var entityDesignArtifact = service.Artifact as EntityDesignArtifact;
            Debug.Assert(entityDesignArtifact != null, "Artifact is not type of EntityDesignArtifact");

            if (entityDesignArtifact != null)
            {
                // Only translate the Escher Model to Dsl Model if the artifact is designer safe.
                if (entityDesignArtifact.IsDesignerSafe)
                {
                    // now get the root of the model.
                    var model = entityDesignArtifact.ConceptualModel;
                    Debug.Assert(model != null, "Could not get ConceptualModel from the artifact.");

                    if (model != null)
                    {
                        entityViewModel =
                            ModelToDesignerModelXRef.GetNewOrExisting(_editingContext, model, partition) as EntityDesignerViewModel;
                        entityViewModel.Namespace = model.Namespace.Value;

                        // If the passed-in diagram is null, retrieve the first diagram if available.
                        if (diagram == null
                            && entityDesignArtifact.DesignerInfo() != null
                            && entityDesignArtifact.DesignerInfo().Diagrams != null
                            && entityDesignArtifact.DesignerInfo().Diagrams.FirstDiagram != null)
                        {
                            diagram = entityDesignArtifact.DesignerInfo().Diagrams.FirstDiagram;
                        }

                        IList<ModelEntityType> entities;
                        IList<ModelAssociation> associations;

                        if (diagram != null)
                        {
                            RetrieveModelElementsFromDiagram(diagram, out entities, out associations);
                        }
                        else
                        {
                            entities = model.EntityTypes().ToList();
                            associations = model.Associations().ToList();
                        }
                        TranslateEntityModel(entities, associations, entityViewModel);
                    }
                }
                else
                {
                    // return empty view model if the artifact is not designer safe so the Diagram can show safe-mode watermark
                    entityViewModel = new EntityDesignerViewModel(partition);
                    entityViewModel.EditingContext = _editingContext;
                }
            }

            return entityViewModel;
        }
        internal override DslModeling.ModelElement SynchronizeSingleDslModelElement(
            DslModeling.ModelElement parentViewModel, EFObject modelElement)
        {
            var t = modelElement.GetType();
            if (t == typeof(ConceptualEntityType))
            {
                return TranslateEntityType(parentViewModel as EntityDesignerViewModel, modelElement as ConceptualEntityType);
            }
            else if (t == typeof(EntityTypeBaseType))
            {
                return TranslateBaseType(parentViewModel as EntityDesignerViewModel, (modelElement).Parent as ConceptualEntityType);
            }
            else if (t == typeof(ModelNavigationProperty))
            {
                return TranslateNavigationProperty(parentViewModel as ViewModelEntityType, modelElement as ModelNavigationProperty);
            }
            else if (t == typeof(ComplexConceptualProperty)
                     || t == typeof(ConceptualProperty))
            {
                return TranslateProperty(parentViewModel as ViewModelEntityType, modelElement as ModelProperty);
            }
            else if (t == typeof(ModelAssociation))
            {
                return TranslateAssociation(parentViewModel as EntityDesignerViewModel, modelElement as ModelAssociation);
            }
            else if (t == typeof(DesignerModel.Diagram))
            {
                return TranslateDiagramValues(parentViewModel as EntityDesignerViewModel, modelElement as DesignerModel.Diagram);
            }

            Debug.Assert(false, "modelElement with type= " + t.Name + " is not supported");

            return null;
        }
 /// <summary>
 ///     Synchronize DSL Model with the value from modelElement.
 /// </summary>
 /// <param name="parentViewModel"></param>
 /// <param name="modelElement"></param>
 /// <returns></returns>
 internal abstract DslModeling.ModelElement SynchronizeSingleDslModelElement(
     DslModeling.ModelElement parentViewModel, EFObject modelElement);
		/// <summary>
        /// Called on a role player changing.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnElementTypeChanged(DslModeling::RolePlayerChangedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType con = args.ElementLink as global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType;
            if (con != null)
            {
                if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType.DomainElementDomainRoleId)
                {
                    if (args.OldRolePlayerId == this.Element.Id)
                       DeleteElementType(con.DEType);

                    if (args.NewRolePlayerId == this.Element.Id)
                        AddElementType(con.DEType);
                }
				else if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.DomainElementReferencesDEType.DETypeDomainRoleId)
				{
					if( args.OldRolePlayer != null )
                        DeleteElementType(args.OldRolePlayer as global::Tum.PDE.ModelingDSL.DEType);

                    if( args.NewRolePlayer != null )
                        AddElementType(args.NewRolePlayer as global::Tum.PDE.ModelingDSL.DEType);
				}
            }
		}
		/// <summary>
        /// Called whenever a relationship of type AttributedDomainElementHasDomainProperty is deleted and
        /// the element hosted by this model is the source.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnDomainPropertyRemoved(DslModeling::ElementDeletedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty con = args.ModelElement as global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty;
            if (con != null)
            {
                DeleteDomainProperty(con.DomainProperty);
            }
		}
		/// <summary>
        /// Called whenever properties change.
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnElementPropertyChanged(DslModeling::ElementPropertyChangedEventArgs args)
        {
        }
		/// <summary>
        /// Called on a role player beeing moved.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnDomainPropertyMoved(DslModeling::RolePlayerOrderChangedEventArgs args)
		{
			this.HandleRolePlayerMoved<Tum.PDE.ModelingDSL.ViewModel.DomainPropertySpecificViewModel>(args, this.DomainPropertyVMs);
				/*
			if (args.SourceElement == this.Element)
                this.DomainPropertyVMs.Move(args.OldOrdinal, args.NewOrdinal);
				*/
		}
		/// <summary>
        /// Called on a role player beeing moved.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnTargetsMoved(DslModeling::RolePlayerOrderChangedEventArgs args)
		{
			this.HandleRolePlayerMoved<Tum.PDE.ModelingDSL.ViewModel.ReferenceableElementSpecificViewModel>(args, this.TargetsVMs);
				/*
			if (args.SourceElement == this.Element)
                this.TargetsVMs.Move(args.OldOrdinal, args.NewOrdinal);
				*/
		}
		/// <summary>
        /// Called on a role player changing.
        /// </summary>
        /// <param name="args">Arguments.</param>
		protected virtual void OnDomainPropertyChanged(DslModeling::RolePlayerChangedEventArgs args)
		{
			global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty con = args.ElementLink as global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty;
            if (con != null)
            {
                if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty.AttributedDomainElementDomainRoleId)
                {
                    if (args.OldRolePlayerId == this.Element.Id)
                       DeleteDomainProperty(con.DomainProperty);

                    if (args.NewRolePlayerId == this.Element.Id)
                        AddDomainProperty(con.DomainProperty);
                }
				else if (args.DomainRole.Id == global::Tum.PDE.ModelingDSL.AttributedDomainElementHasDomainProperty.DomainPropertyDomainRoleId)
				{
					if( args.OldRolePlayer != null )
                        DeleteDomainProperty(args.OldRolePlayer as global::Tum.PDE.ModelingDSL.DomainProperty);

                    if( args.NewRolePlayer != null )
                        AddDomainProperty(args.NewRolePlayer as global::Tum.PDE.ModelingDSL.DomainProperty);
				}
            }
		}
		/// <summary>
        /// Called whenever properties change.
        /// </summary>
        /// <param name="args"></param>
        protected override void OnElementPropertyChanged(DslModeling::ElementPropertyChangedEventArgs args)
        {
			base.OnElementPropertyChanged(args);
			
        }
 /// <summary>
 /// Reads the model into the given store and returns it.
 /// </summary>
 public static IProductState Read(Dsl.SerializationResult result, Dsl.Store store, string modelFile)
 {
     return ProductStateStoreSerializationHelper.Instance.LoadModel(result, store, modelFile, null, null, null);
 }