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