public DeleteResult DeleteNodePromoteTransclusion(Guid domainId, Guid mapIdToDeleteFrom, Guid nodeIdToDelete)
        {
            lock (deleteLock)
            {
                DeleteResult result = new DeleteResult() { DeleteSuccessful = true };
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (MappingToolDatabaseDataContext mappingDb = new MappingToolDatabaseDataContext())
                    {
                        Dictionary<string, SoapNodeType> soapNodeTypes;
                        Dictionary<string, SoapRelationshipType> soapRelTypes;
                        Dictionary<string, SoapMetadataType> soapMetaTypes;
                        Dictionary<string, SoapDescriptorType> soapDescTypes;
                        GetSoapTypes(out soapNodeTypes, out soapRelTypes, out soapMetaTypes, out soapDescTypes);

                        var deleteNodes = from nodes in mappingDb.Nodes
                                          where nodes.NodeUid == nodeIdToDelete && nodes.DomainUid == domainId
                                          select nodes;

                        //if the node existed it'll be the only one and delete just the transclusion relationship
                        if (deleteNodes.Count() > 0)
                        {
                            DescriptorType fromDescriptorType = null;
                            var fromDecriptorTypes = from dbDescriptorTypes in mappingDb.DescriptorTypes
                                                     where dbDescriptorTypes.DescriptorTypeName.ToLower() == "from"
                                                     select dbDescriptorTypes;
                            if (fromDecriptorTypes.Count() != 1)
                            {
                                result.DeleteSuccessful = false;

                            }
                            else
                            {
                                fromDescriptorType = fromDecriptorTypes.First();

                                bool promotionCompleted = false;
                                bool deletedOriginalMapContainer = false;

                                // Delete the appropriate relationships from the node and promote a transclusion relationship
                                var deletedNodesDescriptors = from descriptors in mappingDb.Descriptors
                                                        where descriptors.NodeUid == nodeIdToDelete
                                                        select descriptors;

                                foreach (var descriptor in deletedNodesDescriptors)
                                {
                                    if (descriptor.Relationship != null)
                                    {
                                        //Delete the Map Container Relationship
                                        if (descriptor.Relationship.RelationshipType.RelationshipTypeName == "MapContainerRelationship" && !deletedOriginalMapContainer)
                                        {
                                            foreach (Descriptor relDescriptor in descriptor.Relationship.Descriptors)
                                            {
                                                if (relDescriptor.DescriptorType.DescriptorTypeName == "To")
                                                {
                                                    if (mapIdToDeleteFrom == relDescriptor.NodeUid)
                                                    {
                                                        //Delete the map container relationship and all associated metadata
                                                        DeleteResult relationshipDeleteResult = DeleteRelationship(domainId, descriptor.RelationshipUid.Value);
                                                        if (!relationshipDeleteResult.DeleteSuccessful)
                                                        {
                                                            result.DeleteSuccessful = false;
                                                        }
                                                    }
                                                    break;
                                                }
                                            }
                                            deletedOriginalMapContainer = true;
                                        }

                                        else if (descriptor.Relationship.RelationshipType.RelationshipTypeName == "TransclusionRelationship" && !promotionCompleted)
                                        {
                                            string xPos = null;
                                            string yPos = null;
                                            foreach (Descriptor d1 in descriptor.Relationship.Descriptors)
                                            {
                                                if (d1.NodeUid == nodeIdToDelete)
                                                {
                                                    foreach (Metadata metadata in d1.Node.Metadatas)
                                                    {
                                                        if (metadata.MetadataName == "XPosition" && metadata.RelationshipUid == descriptor.RelationshipUid)
                                                        {
                                                            xPos = metadata.MetadataValue;
                                                        }
                                                        else if (metadata.MetadataName == "YPosition" && metadata.RelationshipUid == descriptor.RelationshipUid)
                                                        {
                                                            yPos = metadata.MetadataValue;
                                                        }
                                                        if (xPos != null && yPos != null)
                                                        {
                                                            //found both values
                                                            break;
                                                        }
                                                    }
                                                    break;
                                                }
                                            }

                                            Guid newRootMapId = Guid.Empty;
                                            foreach (Descriptor altDescriptor in descriptor.Relationship.Descriptors)
                                            {
                                                if (altDescriptor.DescriptorType.DescriptorTypeName == "TransclusionMap")
                                                {
                                                    newRootMapId = altDescriptor.NodeUid.Value;
                                                    break;
                                                }
                                            }

                                            //Delete the transclusion relationship and all associated metadata
                                            DeleteResult relationshipDeleteResult = DeleteRelationship(domainId, descriptor.RelationshipUid.Value);
                                            if (!relationshipDeleteResult.DeleteSuccessful)
                                            {
                                                result.DeleteSuccessful = false;
                                            }

                                            if (xPos != null && yPos != null)
                                            {
                                                //Connect the Map Container Relationship between what was the transclusion map and the transcluded node (promotion to original map and original node)
                                                if (newRootMapId != Guid.Empty)
                                                {
                                                    ConnectedNodesResult connectResult = ConnectToMap(domainId, newRootMapId, nodeIdToDelete, soapDescTypes, soapRelTypes);
                                                    if (connectResult != null)
                                                    {
                                                        UpdateNodeMetadata(domainId, nodeIdToDelete, connectResult.Relationship.Id,
                                                                soapDescTypes["From"], "XPosition", xPos, soapMetaTypes["double"]);
                                                        UpdateNodeMetadata(domainId, nodeIdToDelete, connectResult.Relationship.Id,
                                                                soapDescTypes["From"], "YPosition", yPos, soapMetaTypes["double"]);

                                                        SoapNode promotedNode = connectResult.Nodes[nodeIdToDelete];
                                                        List<Guid> relationshipsToConvert = new List<Guid>();
                                                        foreach (SoapRelationship relationship in promotedNode.Relationships.Values)
                                                        {
                                                            //find all Transclusion relationships for the promotoed node on the transclusion map
                                                            if (relationship.RelationshipType.Name == "TransclusionRelationship")
                                                            {
                                                                Guid mapNodeId = relationship.Nodes.Where(d => d.Key.Name == "TransclusionMap").First().Value;
                                                                if (mapNodeId == newRootMapId)
                                                                {
                                                                    relationshipsToConvert.Add(relationship.Id);
                                                                }
                                                            }
                                                        }

                                                        foreach (Guid relationshipId in relationshipsToConvert)
                                                        {
                                                            if (promotedNode.Relationships[relationshipId].Nodes.Where(pair => pair.Key.Name == "From").Count() > 0)
                                                            {
                                                                Guid fromNodeId = promotedNode.Relationships[relationshipId].Nodes.Where(pair => pair.Key.Name == "From").First().Value;
                                                                Guid toNodeId = promotedNode.Relationships[relationshipId].Nodes.Where(pair => pair.Key.Name == "To").First().Value;
                                                                Dictionary<SoapDescriptorType, Guid> nodes = new Dictionary<SoapDescriptorType, Guid>();
                                                                nodes.Add(soapDescTypes["From"], fromNodeId);
                                                                nodes.Add(soapDescTypes["To"], toNodeId);
                                                                ConnectNodes(domainId, nodes, soapRelTypes["FromToRelationship"], relationshipId.ToString());
                                                                DeleteRelationship(domainId, relationshipId);
                                                            }
                                                        }
                                                    }
                                                    promotionCompleted = true;
                                                }
                                            }
                                        }

                                        else if (descriptor.Relationship.RelationshipType.RelationshipTypeName == "FromToRelationship")
                                        {
                                            DeleteRelationship(domainId, descriptor.RelationshipUid.Value);
                                        }
                                    }
                                }
                            }
                        }
                    }
                });
                result.DeletedId = nodeIdToDelete;
                return result;
            }
        }
        public DeleteResult DeleteNodeTransclusion(Guid domainId, Guid mapIdToDeleteFrom, Guid nodeIdToDelete)
        {
            lock (deleteLock)
            {
                DeleteResult result = new DeleteResult() { DeleteSuccessful = true };
                Guid transclusionRelationshipDeleted = Guid.Empty;
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (MappingToolDatabaseDataContext mappingDb = new MappingToolDatabaseDataContext())
                    {
                        var deleteNodes = from nodes in mappingDb.Nodes
                                          where nodes.NodeUid == nodeIdToDelete && nodes.DomainUid == domainId
                                          select nodes;

                        //if the node existed it'll be the only one and delete just the transclusion relationship
                        if (deleteNodes.Count() > 0)
                        {
                            // Delete the descriptors that have the node to be deleted associated with them directly
                            var deleteDescriptors = from descriptors in mappingDb.Descriptors
                                                    where descriptors.NodeUid == nodeIdToDelete
                                                    select descriptors;
                            foreach (var descriptor in deleteDescriptors)
                            {
                                //Delete the Transclusion Relationships
                                if (descriptor.Relationship.RelationshipType.RelationshipTypeName == "TransclusionRelationship")
                                {
                                    foreach (Descriptor relDescriptor in descriptor.Relationship.Descriptors)
                                    {
                                        if (relDescriptor.DescriptorType.DescriptorTypeName == "TransclusionMap")
                                        {
                                            if (mapIdToDeleteFrom == relDescriptor.NodeUid)
                                            {
                                                //Delete the transclusion relationship and all associated metadata
                                                DeleteResult relationshipDeleteResult = DeleteRelationship(domainId, descriptor.RelationshipUid.Value);
                                                if (!relationshipDeleteResult.DeleteSuccessful)
                                                {
                                                    result.DeleteSuccessful = false;
                                                }
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                });
                result.DeletedId = nodeIdToDelete;
                return result;
            }
        }
        public DeleteResult DeleteNode(Guid domainId, Guid nodeId)
        {
            lock (deleteLock)
            {
                List<Guid> relationshipIds = new List<Guid>();
                List<Guid> deletedDescriptors = new List<Guid>();
                DeleteResult result = new DeleteResult() { DeleteSuccessful = false, DeletedId = nodeId };
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (MappingToolDatabaseDataContext mappingDb = new MappingToolDatabaseDataContext())
                    {
                        var deleteNodes = from nodes in mappingDb.Nodes
                                          where nodes.NodeUid == nodeId && nodes.DomainUid == domainId
                                          select nodes;
                        //if the node existed it'll be the only one and delete all associated relationships/descriptors and metadatum
                        if (deleteNodes.Count() > 0)
                        {
                            // Delete the descriptors that have the node to be deleted associated with them directly
                            var deleteDescriptors = from descriptors in mappingDb.Descriptors
                                                    where descriptors.NodeUid == nodeId
                                                    select descriptors;
                            foreach (var descriptor in deleteDescriptors)
                            {
                                relationshipIds.Add(descriptor.RelationshipUid.Value);
                                deletedDescriptors.Add(descriptor.DescriptorUid);
                                mappingDb.Descriptors.DeleteOnSubmit(descriptor);
                            }
                            try
                            {
                                mappingDb.SubmitChanges();
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }

                            foreach (Guid relationshipId in relationshipIds)
                            {
                                var deleteRelationships = from relationships in mappingDb.Relationships
                                                          where relationships.RelationshipUid == relationshipId
                                                          select relationships;
                                if (deleteRelationships.Count() > 0)
                                {
                                    var relationship = deleteRelationships.First();

                                    // Delete the descriptors that dangle off the other side of the relationship just deleted
                                    var deleteAltDescriptors = from descriptors2 in mappingDb.Descriptors
                                                               where descriptors2.RelationshipUid == relationshipId
                                                               select descriptors2;
                                    foreach (var altDescriptor in deleteAltDescriptors)
                                    {
                                        if (!deletedDescriptors.Contains(altDescriptor.DescriptorUid))
                                        {
                                            mappingDb.Descriptors.DeleteOnSubmit(altDescriptor);
                                        }
                                    }

                                    try
                                    {
                                        mappingDb.SubmitChanges();
                                    }
                                    catch (Exception)
                                    {
                                        //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                                    }

                                    // Delete metadata associated with the relationship just deleted
                                    var deleteRelationshipMetadatum = from metadatum in mappingDb.Metadatas
                                                                      where metadatum.RelationshipUid == relationshipId
                                                                      select metadatum;
                                    foreach (var relationshipMetadatum in deleteRelationshipMetadatum)
                                    {
                                        mappingDb.Metadatas.DeleteOnSubmit(relationshipMetadatum);
                                    }
                                    try
                                    {
                                        mappingDb.SubmitChanges();
                                    }
                                    catch (Exception)
                                    {
                                        //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                                    }

                                    mappingDb.Relationships.DeleteOnSubmit(relationship);
                                    try
                                    {
                                        mappingDb.SubmitChanges();
                                    }
                                    catch (Exception)
                                    {
                                        //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                                    }
                                }
                            }

                            var nodeToDelete = deleteNodes.First();
                            var deleteNodeMetadatum = from metadatum in mappingDb.Metadatas
                                                      where metadatum.NodeUid == nodeToDelete.NodeUid
                                                      select metadatum;
                            foreach (var metadatum in deleteNodeMetadatum)
                            {
                                mappingDb.Metadatas.DeleteOnSubmit(metadatum);
                            }
                            try
                            {
                                mappingDb.SubmitChanges();
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }

                            // Delete the actual node, it will only be one
                            mappingDb.Nodes.DeleteOnSubmit(nodeToDelete);
                            try
                            {
                                mappingDb.SubmitChanges();
                                result.DeleteSuccessful = true;
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }
                        }
                    }
                });
                return result;
            }
        }
        public DeleteResult DeleteRelationship(Guid domainId, Guid relationshipId)
        {
            lock (deleteLock)
            {
                DeleteResult result = new DeleteResult() { DeleteSuccessful = false, DeletedId = relationshipId };
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (MappingToolDatabaseDataContext mappingDb = new MappingToolDatabaseDataContext())
                    {
                        var deleteRelationships = from relationships in mappingDb.Relationships
                                                  where relationships.RelationshipUid == relationshipId && relationships.DomainUid == domainId
                                                  select relationships;

                        //if the relationship existed it'll be the only one and can delete all the descriptors and metadatum
                        if (deleteRelationships.Count() > 0)
                        {
                            var relationship = deleteRelationships.First();

                            var deleteDescriptors = from descriptors in mappingDb.Descriptors
                                                    where descriptors.RelationshipUid == relationshipId
                                                    select descriptors;

                            foreach (var descriptor in deleteDescriptors)
                            {
                                mappingDb.Descriptors.DeleteOnSubmit(descriptor);
                            }

                            try
                            {
                                mappingDb.SubmitChanges();
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }

                            // Delete metadata associated with the relationship just deleted
                            var deleteRelationshipMetadatum = from metadatum in mappingDb.Metadatas
                                                              where metadatum.RelationshipUid == relationshipId
                                                              select metadatum;
                            foreach (var relationshipMetadatum in deleteRelationshipMetadatum)
                            {
                                mappingDb.Metadatas.DeleteOnSubmit(relationshipMetadatum);
                            }
                            try
                            {
                                mappingDb.SubmitChanges();
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }

                            mappingDb.Relationships.DeleteOnSubmit(relationship);
                            try
                            {
                                mappingDb.SubmitChanges();
                                result.DeleteSuccessful = true;
                            }
                            catch (Exception)
                            {
                                //Debug.WriteLine("An exception occurred of type: {0}\r\n{1}", e.Message, e);
                            }
                        }
                    }
                });
                return result;
            }
        }
 private static void DeleteMetadata(MetadataContext context, DeleteResult result, MappingToolDatabaseDataContext mappingDb, IQueryable<Metadata> deleteMetadatas)
 {
     if (deleteMetadatas.Count() == 1)
     {
         Metadata metadata = deleteMetadatas.First();
         if (metadata != null)
         {
             mappingDb.Metadatas.DeleteOnSubmit(metadata);
             try
             {
                 mappingDb.SubmitChanges();
                 result.DeleteSuccessful = true;
                 result.DeletedId = metadata.MetadataId;
                 LoggingService.WriteTrace(LoggingService.Categories.WcfServices, TraceSeverity.Verbose,
                     "Deleted metadata with ID: {0} the value was: '{1}'", metadata.MetadataId.ToString(),
                     metadata.MetadataValue);
             }
             catch (Exception e)
             {
                 LoggingService.WriteTrace(LoggingService.Categories.WcfServices, TraceSeverity.Unexpected,
                     "There was an error deleting the metadata with ID: {0} due to {1}: {2}",
                     metadata.MetadataId.ToString(), e.GetType().ToString(), e.Message);
             }
         }
     }
     else
     {
         LoggingService.WriteTrace(LoggingService.Categories.WcfServices, TraceSeverity.Unexpected,
             "There was an error deleting the metadata with the name {0} from the NodeUid: {1}",
             context.MetadataName, context.NodeUid);
     }
 }
        public DeleteResult DeleteMetadata(MetadataContext context)
        {
            DeleteResult result = new DeleteResult() { DeleteSuccessful = false, DeletedId = Guid.Empty };
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (MappingToolDatabaseDataContext mappingDb = new MappingToolDatabaseDataContext())
                {
                    if ((context.RelationshipUid != null && context.RelationshipUid.HasValue) && 
                        (context.DescriptorTypeUid != null && context.DescriptorTypeUid.HasValue))
                    {
                        var deleteMetadatas = from metadata in mappingDb.Metadatas
                                          where metadata.NodeUid.Value == context.NodeUid.Value
                                          && metadata.DescriptorTypeUid.Value == context.DescriptorTypeUid.Value
                                          && metadata.RelationshipUid.Value == context.RelationshipUid.Value
                                          && metadata.MetadataName == context.MetadataName
                                          select metadata;
                        DeleteMetadata(context, result, mappingDb, deleteMetadatas);
                    }
                    else if ((context.RelationshipUid == null || !context.RelationshipUid.HasValue) && 
                        (context.DescriptorTypeUid != null || context.DescriptorTypeUid.HasValue))
                    {
                        var deleteMetadatas = from metadata in mappingDb.Metadatas
                                          where metadata.NodeUid.Value == context.NodeUid.Value
                                          && metadata.DescriptorTypeUid.Value == context.DescriptorTypeUid.Value
                                          && metadata.MetadataName == context.MetadataName
                                          select metadata;
                        DeleteMetadata(context, result, mappingDb, deleteMetadatas);
                    }
                    else if ((context.RelationshipUid != null || context.RelationshipUid.HasValue) &&
                        (context.DescriptorTypeUid == null || !context.DescriptorTypeUid.HasValue))
                    {
                        var deleteMetadatas = from metadata in mappingDb.Metadatas
                                          where metadata.NodeUid.Value == context.NodeUid.Value
                                          && metadata.RelationshipUid.Value == context.RelationshipUid.Value
                                          && metadata.MetadataName == context.MetadataName
                                          select metadata;
                        DeleteMetadata(context, result, mappingDb, deleteMetadatas);
                    }
                    else
                    {
                        var deleteMetadatas = from metadata in mappingDb.Metadatas
                                              where metadata.NodeUid.Value == context.NodeUid.Value
                                              && metadata.MetadataName == context.MetadataName
                                              select metadata;

                        DeleteMetadata(context, result, mappingDb, deleteMetadatas);
                    }

                    
                }
            });
            return result;
        }