/// <summary>
		/// Decides whether the element can be pasted or not based on the operation.
		/// </summary>
		/// <param name="protoGroupOperation">Proto group operation.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public override bool ModelIsPasteAllowed(DslEditorModeling::ModelProtoGroupOperation protoGroupOperation)
		{
			if( protoGroupOperation == DslEditorModeling.ModelProtoGroupOperation.Move )
				return ModelIsMoveAllowed();
		
			if( !base.ModelIsPasteAllowed(protoGroupOperation) )
				return false;
		
			return true;
		}
		/// <summary>
		/// Create a proto element representation of the element, which can be used for paste later.
		/// </summary>
		/// <param name="protoGroup">Proto group to add the element to.</param>
		/// <returns>Proto element representation of the element.</returns>
		public override DslEditorModeling::ModelProtoElement ModelCreateMergeCopy(DslEditorModeling::ModelProtoGroup protoGroup)
		{
			if (protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Copy)
		        if (!ModelIsCopyAllowed())
		            return null;
		
		    if (protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move)
		    	return null;
		
			DslEditorModeling::ModelProtoElement protoElement = new DslEditorModeling::ModelProtoElement(this);
			protoGroup.AddNewElement(protoElement);
			ModelProcessMergeCopy(protoElement, protoGroup);
			
			return protoElement;
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
			// DomainClassReferencesBaseClass
			foreach (global::Tum.PDE.LanguageDSL.DomainClassReferencesBaseClass link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainClassReferencesBaseClass>(this, global::Tum.PDE.LanguageDSL.DomainClassReferencesBaseClass.DerivedClassDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
		}
		/// <summary>
		/// Adds a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		/// <param name="isRoot">Root element?</param>
		public override void ModelMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger, bool isRoot)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergePasteDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to RelationshipShapeClass because paste is not allowed."));
				return;
			}
		
			base.ModelMerge(protoElement, groupMerger, isRoot);
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
			// RelationshipShapeClassReferencesReferenceRelationship
			foreach (global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship>(this, global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.RelationshipShapeClassDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
		}
		/// <summary>
		/// Finalize merge.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public virtual void ModelFinalizeMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
		}
		/// <summary>
		/// Adds a proto link to the current element.
		/// </summary>
		/// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public virtual void ModelMerge(DslEditorModeling::ModelProtoLink protoLink, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
			
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
		}
		/// <summary>
		/// Decides whether the element that is represented by the proto element can be pasted or not.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public virtual bool ModelCanMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			return false;
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
			// DomainEnumerationHasLiterals
			foreach (global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals>(this, global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals.DomainEnumerationDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewEmbeddingLink(protoLink);
				
				DslEditorModeling::ModelProtoElement protoElementRS = new DslEditorModeling::ModelProtoElement(link.EnumerationLiteral);
				protoGroup.AddNewElement(protoElementRS);
				
				// continue with target element
				if( link.EnumerationLiteral is DslEditorModeling::IModelMergeElements )
				{
					(link.EnumerationLiteral as DslEditorModeling::IModelMergeElements).ModelCreateMergeCopy(protoGroup);
				}
			}
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public virtual void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			// DomainTypeReferencesPropertyGridEditor
			foreach (global::Tum.PDE.LanguageDSL.DomainTypeReferencesPropertyGridEditor link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainTypeReferencesPropertyGridEditor>(this, global::Tum.PDE.LanguageDSL.DomainTypeReferencesPropertyGridEditor.DomainTypeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
		}
		/// <summary>
		/// Moves a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelMove(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeMoveDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to MetaModel because move is not allowed."));
				return;
			}
			if (protoElement != null)
			{
				DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.DomainType.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasDomainTypes.DomainTypeDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.Validation.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasValidation.ValidationDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.AdditionalInformation.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasAdditionalInformation.AdditionalInformationDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.MetaModelLibrary.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasMetaModelLibraries.MetaModelLibraryDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.View.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasView.ViewDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.BaseModelContext.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasModelContexts.BaseModelContextDomainRoleId, this);
					return;
				}
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.PropertyGridEditor.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.MetaModelHasPropertyGridEditors.PropertyGridEditorDomainRoleId, this);
					return;
				}
			}
		
			base.ModelMove(protoElement, groupMerger);
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
			// TreeNodeReferencesDomainElement
			foreach (global::Tum.PDE.LanguageDSL.TreeNodeReferencesDomainElement link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.TreeNodeReferencesDomainElement>(this, global::Tum.PDE.LanguageDSL.TreeNodeReferencesDomainElement.TreeNodeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// TreeNodeReferencesEmbeddingRSNodes
			foreach (global::Tum.PDE.LanguageDSL.TreeNodeReferencesEmbeddingRSNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.TreeNodeReferencesEmbeddingRSNodes>(this, global::Tum.PDE.LanguageDSL.TreeNodeReferencesEmbeddingRSNodes.TreeNodeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// TreeNodeReferencesInheritanceNodes
			foreach (global::Tum.PDE.LanguageDSL.TreeNodeReferencesInheritanceNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.TreeNodeReferencesInheritanceNodes>(this, global::Tum.PDE.LanguageDSL.TreeNodeReferencesInheritanceNodes.TreeNodeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// TreeNodeReferencesReferenceRSNodes
			foreach (global::Tum.PDE.LanguageDSL.TreeNodeReferencesReferenceRSNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.TreeNodeReferencesReferenceRSNodes>(this, global::Tum.PDE.LanguageDSL.TreeNodeReferencesReferenceRSNodes.TreeNodeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// TreeNodeReferencesShapeClassNodes
			foreach (global::Tum.PDE.LanguageDSL.TreeNodeReferencesShapeClassNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.TreeNodeReferencesShapeClassNodes>(this, global::Tum.PDE.LanguageDSL.TreeNodeReferencesShapeClassNodes.TreeNodeDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public override void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			base.ModelProcessMergeCopy(protoElement, protoGroup);
		
			// DomainRoleReferencesOpposite
			foreach (global::Tum.PDE.LanguageDSL.DomainRoleReferencesOpposite link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainRoleReferencesOpposite>(this, global::Tum.PDE.LanguageDSL.DomainRoleReferencesOpposite.SourceDomainRoleDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// DomainRoleReferencesRolePlayer
			foreach (global::Tum.PDE.LanguageDSL.DomainRoleReferencesRolePlayer link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainRoleReferencesRolePlayer>(this, global::Tum.PDE.LanguageDSL.DomainRoleReferencesRolePlayer.DomainRoleDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// DomainRoleReferencesCustomPropertyGridEditor
			foreach (global::Tum.PDE.LanguageDSL.DomainRoleReferencesCustomPropertyGridEditor link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainRoleReferencesCustomPropertyGridEditor>(this, global::Tum.PDE.LanguageDSL.DomainRoleReferencesCustomPropertyGridEditor.DomainRoleDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
		}
		/// <summary>
		/// Adds a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		/// <param name="isRoot">Root element?</param>
		public virtual void ModelMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger, bool isRoot)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergePasteDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DiagramClassView because paste is not allowed."));
				return;
			}
			if (protoElement != null)
			{
				DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId)) 
				{
					// get element id
					System.Guid newElementId = System.Guid.NewGuid();
					
					// create property assignments
					DslModeling::PropertyAssignment[] propertyAssignemnts = protoElement.GetPropertyAssignments(this.Store.DefaultPartition, newElementId);
					
		            // create the actual model element
					global::Tum.PDE.LanguageDSL.RootDiagramNode element = null;			
					if( global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId == elementDomainInfo.Id )
						element = new global::Tum.PDE.LanguageDSL.RootDiagramNode(this.Store, propertyAssignemnts);
					if( element == null )
						throw new System.ArgumentNullException("Element is null in ModelMerge: " + elementDomainInfo.Name);
					
					if( !element.ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
					{
						// add warning message
						groupMerger.MergeResult.AddMessage(new DslEditorModeling.ValidationMessage("ModelMergePasteDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DiagramClassView because paste is not allowed."));
						
						element.Delete();
						return;
		 			}
					
					if( isRoot && groupMerger.ProtoGroup.Operation != DslEditorModeling.ModelProtoGroupOperation.Move)
					{
						//element.Name = "Copy of " + element.Name;
					}
					
					// update id mapping
					groupMerger.SetIdMapping(protoElement.ElementId, newElementId);
					
					// add child element
					GetRoleCollection<DslModeling::LinkedElementCollection<global::Tum.PDE.LanguageDSL.RootDiagramNode>, global::Tum.PDE.LanguageDSL.RootDiagramNode>(global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes.DiagramClassViewDomainRoleId).Add(element);
		
					// continue with child elements (Embedding Relationship)
					System.Collections.Generic.List<DslEditorModeling::ModelProtoElement> embeddedProtoElements = groupMerger.GetEmbeddedElements(this.Store.DefaultPartition, protoElement);
					if( embeddedProtoElements.Count > 0 )
					{
						foreach (DslEditorModeling::ModelProtoElement p in embeddedProtoElements)
							(element as DslEditorModeling::IModelMergeElements).ModelMerge(p, groupMerger, false);
					}
				}
			}
		}
		/// <summary>
		/// Decides whether the element that is represented by the proto element can be pasted or not.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public override bool ModelCanMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			if (protoElement != null)
			{
				DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.EnumerationLiteral.DomainClassId)) 
				{
					if( protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move )
					{
						foreach (global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals>(this, global::Tum.PDE.LanguageDSL.DomainEnumerationHasLiterals.DomainEnumerationDomainRoleId))				
							if( link.EnumerationLiteral.Id == protoElement.ElementId )
								return false;
					}
					return true;
				}
			}
			return base.ModelCanMerge(protoElement, protoGroup);
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public virtual void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
		}
		/// <summary>
		/// Adds a proto link to the current element.
		/// </summary>
		/// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelMerge(DslEditorModeling::ModelProtoLink protoLink, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
		
			base.ModelMerge(protoLink, groupMerger);
			
		}
		/// <summary>
		/// Moves a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public virtual void ModelMove(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeMoveDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DiagramClassView because move is not allowed."));
				return;
			}
			if (protoElement != null)
			{
				DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId)) 
				{
		            DslModeling::ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
		            if( modelElement == null )
		            {
		                groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementMissingOnMoveId",
				             DslEditorModeling.ModelValidationViolationType.Error, "Element exists although the operation = Move."));
		                return;
					}
		
					// change parent
					DslModeling::DomainRoleInfo.SetLinkedElement(modelElement, global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes.RootDiagramNodeDomainRoleId, this);
					return;
				}
			}
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public virtual void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			// DiagramClassHasPresentationElements
			foreach (global::Tum.PDE.LanguageDSL.DiagramClassHasPresentationElements link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DiagramClassHasPresentationElements>(this, global::Tum.PDE.LanguageDSL.DiagramClassHasPresentationElements.DiagramClassDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewEmbeddingLink(protoLink);
				
				DslEditorModeling::ModelProtoElement protoElementRS = new DslEditorModeling::ModelProtoElement(link.PresentationElementClass);
				protoGroup.AddNewElement(protoElementRS);
				
				// continue with target element
				if( link.PresentationElementClass is DslEditorModeling::IModelMergeElements )
				{
					(link.PresentationElementClass as DslEditorModeling::IModelMergeElements).ModelCreateMergeCopy(protoGroup);
				}
			}
		}
		/// <summary>
		/// Adds a proto link to the current element.
		/// </summary>
		/// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelMerge(DslEditorModeling::ModelProtoLink protoLink, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
		
			DslModeling::DomainRelationshipInfo linkDomainInfo = null;
			if (protoLink != null)
			{
				linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(protoLink.DomainClassId);
			}
			else
			{
				// try getting the linkDomainInfo from name
			}
			
			if( linkDomainInfo == null )
			{
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementLinkDomainTypeMissing",
					             DslEditorModeling.ModelValidationViolationType.Error, "Element link can not be created as the corresponding domain type is missing."));
				return;
			}
		
		
			base.ModelMerge(protoLink, groupMerger);
			
		}
		/// <summary>
		/// Decides whether the element can be pasted or not based on the operation.
		/// </summary>
		/// <param name="protoGroupOperation">Proto group operation.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public virtual bool ModelIsPasteAllowed(DslEditorModeling::ModelProtoGroupOperation protoGroupOperation)
		{
			if( protoGroupOperation == DslEditorModeling.ModelProtoGroupOperation.Move )
				return ModelIsMoveAllowed();
		
			return true;
		}
		/// <summary>
		/// Moves a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public virtual void ModelMove(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeMoveDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DomainElement because move is not allowed."));
				return;
			}
		}
		/// <summary>
		/// Create a proto element representation of the element, which can be used for paste later.
		/// </summary>
		/// <param name="protoGroup">Proto group to add the element to.</param>
		/// <returns>Proto element representation of the element.</returns>
		public virtual DslEditorModeling::ModelProtoElement ModelCreateMoveCopy(DslEditorModeling::ModelProtoGroup protoGroup)
		{
			if (protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move)
		        if (!ModelIsMoveAllowed())
		            return null;
					
			if (protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Copy)
				return null;
				
			DslEditorModeling::ModelProtoElement protoElement = new DslEditorModeling::ModelProtoElement(this);
			protoGroup.AddNewElement(protoElement);
			
			return protoElement;		
		}
		/// <summary>
		/// Finalize merge.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelFinalizeMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
		
			base.ModelFinalizeMerge(protoElement, groupMerger);
		}
		/// <summary>
		/// Processes a proto element representation of the element and adds required proto links. 
		/// This method is called on base classes from derived classes.
		/// 
		/// Hint: Properties do not need to be added in this method.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		public virtual void ModelProcessMergeCopy(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			// DiagramClassViewReferencesDiagramClass
			foreach (global::Tum.PDE.LanguageDSL.DiagramClassViewReferencesDiagramClass link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DiagramClassViewReferencesDiagramClass>(this, global::Tum.PDE.LanguageDSL.DiagramClassViewReferencesDiagramClass.DiagramClassViewDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewReferenceLink(protoLink);
			}
			// DiagramClassViewHasRootDiagramNodes
			foreach (global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes>(this, global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes.DiagramClassViewDomainRoleId))
			{
				DslEditorModeling::ModelProtoLink protoLink = new DslEditorModeling::ModelProtoLink(link);
				protoGroup.AddNewEmbeddingLink(protoLink);
				
				DslEditorModeling::ModelProtoElement protoElementRS = new DslEditorModeling::ModelProtoElement(link.RootDiagramNode);
				protoGroup.AddNewElement(protoElementRS);
				
				// continue with target element
				if( link.RootDiagramNode is DslEditorModeling::IModelMergeElements )
				{
					(link.RootDiagramNode as DslEditorModeling::IModelMergeElements).ModelCreateMergeCopy(protoGroup);
				}
			}
		}
		/// <summary>
		/// Decides whether the element that is represented by the proto element can be pasted or not.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public override bool ModelCanMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			return base.ModelCanMerge(protoElement, protoGroup);
		}
		/// <summary>
		/// Decides whether the element that is represented by the proto element can be pasted or not.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element.</param>
		/// <param name="protoGroup">Proto group the proto element belongs to.</param>
		/// <returns>True if the element can be pasted. False otherwise.</returns>
		public virtual bool ModelCanMerge(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroup protoGroup)
		{
			if (protoElement != null)
			{
				DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
				if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId)) 
				{
					if( protoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move )
					{
						foreach (global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes link in DslModeling::DomainRoleInfo.GetElementLinks<global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes>(this, global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes.DiagramClassViewDomainRoleId))				
							if( link.RootDiagramNode.Id == protoElement.ElementId )
								return false;
					}
					return true;
				}
			}
			return false;
		}
		/// <summary>
		/// Adds a proto link to the current element.
		/// </summary>
		/// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelMerge(DslEditorModeling::ModelProtoLink protoLink, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
		
			DslModeling::DomainRelationshipInfo linkDomainInfo = null;
			if (protoLink != null)
			{
				linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(protoLink.DomainClassId);
			}
			else
			{
				// try getting the linkDomainInfo from name
				if( protoLink.Name == "RelationshipShapeClassReferencesReferenceRelationship" && linkDomainInfo == null)
				{
					linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(RelationshipShapeClassReferencesReferenceRelationship.DomainClassId);
				}
			}
			
			if( linkDomainInfo == null )
			{
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementLinkDomainTypeMissing",
					             DslEditorModeling.ModelValidationViolationType.Error, "Element link can not be created as the corresponding domain type is missing."));
				return;
			}
		
				if (linkDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.DomainClassId)) 
				{
					// see if this element is taking part in this role
					bool bTakesPart = false;
					
					DslEditorModeling::ModelProtoRolePlayer sourceRolePlayer = protoLink.GetSourceRolePlayer(this.Store.DefaultPartition);
					DslEditorModeling::ModelProtoElement sourceProtoElement = groupMerger.GetElementById(sourceRolePlayer.RolePlayerId);
					System.Guid mappedSourceIdTP = System.Guid.Empty;
					if( sourceProtoElement != null )
					{
						mappedSourceIdTP = groupMerger.GetIdMapping(sourceRolePlayer.RolePlayerId);
						if( mappedSourceIdTP == this.Id )
							bTakesPart = true;
					}
		
					if( bTakesPart )
					{		
						bool bExists = true;
		        	    if( this.Store.ElementDirectory.FindElement(protoLink.ElementId) == null )
		        	        bExists = false;
							
						if( bExists && groupMerger.ProtoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move )
		        	    {
		        	        groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementLinkExistsOnMoveId",
					             DslEditorModeling.ModelValidationViolationType.Error, "Element link exists although the operation = Move."));
						}
						
						#region Target
						// see if target element was copied
						DslEditorModeling::ModelProtoRolePlayer targetRolePlayer = protoLink.GetTargetRolePlayer(this.Store.DefaultPartition);
						DslEditorModeling::ModelProtoElement targetProtoElement = groupMerger.GetElementById(targetRolePlayer.RolePlayerId);
						System.Guid mappedTargetId = System.Guid.Empty;
						if( targetProtoElement != null )
						{
						 	mappedTargetId= groupMerger.GetIdMapping(targetRolePlayer.RolePlayerId);
						}
						
						if( mappedTargetId == System.Guid.Empty )
						{
							// try creating relationship to existing element
							mappedTargetId = targetRolePlayer.RolePlayerId;
						}
						
						if( mappedTargetId == System.Guid.Empty )
						{
							// try creating relationship to existing element with the same name as the previous element
							// TODO
						}
		
						if( mappedTargetId == System.Guid.Empty )
						{
							// log warning
		        	        groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkElementNotCopiedId",
					             DslEditorModeling.ModelValidationViolationType.Error, "Referenced model element was not copied. Relationship: RelationshipShapeClassReferencesReferenceRelationship"));
						}
						else
						{
							DslModeling::ModelElement targetElement = this.Store.ElementDirectory.FindElement(mappedTargetId);
							if( targetElement == null )
							{
								// log error
		        	        	groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkElementNotFoundId",
					            	DslEditorModeling.ModelValidationViolationType.Error, "Referenced model element was not found. Relationship: RelationshipShapeClassReferencesReferenceRelationship"));
							}
							else
							{
								bool bContinue = true;
		
								// check cardinalities, so we don't violate them by additing a new relationship
								if( DslModeling::DomainRoleInfo.GetLinkedElement(this, global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.RelationshipShapeClassDomainRoleId) != null )
								{
									// log warning
		        	        		groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkCreationViolatesMultiplicityId",
					            		DslEditorModeling.ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: RelationshipShapeClassReferencesReferenceRelationship"));
									
									bContinue = false;
								}
								
								if( bContinue )
								{
									// create property assignments
									DslModeling::PropertyAssignment[] propertyAssignemnts = protoLink.GetPropertyAssignments(this.Store.DefaultPartition, 
										System.Guid.NewGuid());
								
									// create role assignments
									DslModeling.RoleAssignment[] roleAssignments = new DslModeling.RoleAssignment[2];
		                	        roleAssignments[0] = new DslModeling.RoleAssignment(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.RelationshipShapeClassDomainRoleId, this);
									roleAssignments[1] = new DslModeling.RoleAssignment(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.DomainRelationshipDomainRoleId, targetElement);
									
									// create new relationship
									new global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship(this.Store, roleAssignments, propertyAssignemnts);
								}
							}
						}
						#endregion
					}
				}
		
			base.ModelMerge(protoLink, groupMerger);
			
		}
		/// <summary>
		/// Moves a proto element to the current element.
		/// </summary>
		/// <param name="protoElement">Proto element representation of the element that is to be added.</param>
		/// <param name="groupMerger">
		/// Group merger class used to track id mapping, merge errors/warnings and 
		/// postprocess merging by rebuilding reference relationships.
		/// </param>
		public override void ModelMove(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger)
		{
			if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) )
			{
				// add warning message
				groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeMoveDisallowedId",
		                     DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to RestorableTemplatedDiagramVMOnly because move is not allowed."));
				return;
			}
		
			base.ModelMove(protoElement, groupMerger);
		}