/// <summary>
 /// Creates a new vertex update definition
 /// </summary>
 /// <param name="myCommentUpdate">The comment update</param>
 /// <param name="myUpdatedStructuredProperties">The update for the structured properties</param>
 /// <param name="myUpdatedUnstructuredProperties">The update for the unstructured properties</param>
 /// <param name="myUpdatedBinaryProperties">The update for the binary properties</param>
 /// <param name="mySingleEdgeUpdate">The update for the single edges</param>
 /// <param name="myHyperEdgeUpdate">The update for the hyper edges</param>
 /// <param name="myToBeAddedIncomingEdges">The incoming edges that should be added to the vertex</param>
 public VertexUpdateDefinition(
     String myCommentUpdate = null,
     StructuredPropertiesUpdate myUpdatedStructuredProperties = null,
     UnstructuredPropertiesUpdate myUpdatedUnstructuredProperties = null,
     BinaryPropertiesUpdate myUpdatedBinaryProperties = null,
     SingleEdgeUpdate mySingleEdgeUpdate = null,
     HyperEdgeUpdate myHyperEdgeUpdate = null,
     IEnumerable<IncomingEdgeAddDefinition> myToBeAddedIncomingEdges = null)
     : base(myCommentUpdate, myUpdatedStructuredProperties, myUpdatedUnstructuredProperties)
 {
     UpdatedBinaryProperties = myUpdatedBinaryProperties;
     UpdatedSingleEdges = mySingleEdgeUpdate;
     UpdateHyperEdges = myHyperEdgeUpdate;
     ToBeAddedIncomingEdges = myToBeAddedIncomingEdges;
 }
        public override void Delete(RequestDelete myDeleteRequest, SecurityToken mySecurityToken, Int64 myTransactionToken)
        {
            var toBeProcessedVertices = GetVertices(myDeleteRequest.ToBeDeletedVertices, myTransactionToken, mySecurityToken);

            if (myDeleteRequest.ToBeDeletedAttributes.IsNotNullOrEmpty())
            {
                List<long> toBeDeletedStructuredPropertiesUpdate = new List<long>();
                List<String> tobeDeletedUnstructuredProperties = new List<String>();
                List<long> toBeDeletedBinaryProperties = new List<long>();
                List<long> toBeDeletedSingleEdges = new List<long>();
                List<long> toBeDeletedHyperEdges = new List<long>();
                Dictionary<Int64, IPropertyDefinition> toBeDeletedProperties = new Dictionary<long, IPropertyDefinition>();
                Dictionary<Int64, IOutgoingEdgeDefinition> toBeDeletedEdges = new Dictionary<long, IOutgoingEdgeDefinition>();
                Dictionary<Int64, IBinaryPropertyDefinition> toBeDeletedBinaries = new Dictionary<long, IBinaryPropertyDefinition>();
                HashSet<String> toBeDeletedUndefinedAttributes = new HashSet<string>();

                //remove the attributes
                foreach (var aVertexTypeGroup in toBeProcessedVertices.GroupBy(_ => _.VertexTypeID))
                {
                    var vertexType = _vertexTypeManager.ExecuteManager.GetType(aVertexTypeGroup.Key, myTransactionToken, mySecurityToken);

                    #region prepare update definition

                    toBeDeletedStructuredPropertiesUpdate.Clear();
                    StructuredPropertiesUpdate structuredProperties = new StructuredPropertiesUpdate(null, toBeDeletedStructuredPropertiesUpdate);

                    tobeDeletedUnstructuredProperties.Clear();
                    UnstructuredPropertiesUpdate unstructuredProperties = new UnstructuredPropertiesUpdate(null, tobeDeletedUnstructuredProperties);

                    toBeDeletedBinaryProperties.Clear();
                    BinaryPropertiesUpdate binaryProperties = new BinaryPropertiesUpdate(null, toBeDeletedBinaryProperties);

                    toBeDeletedSingleEdges.Clear();
                    SingleEdgeUpdate singleEdges = new SingleEdgeUpdate(null, toBeDeletedSingleEdges);

                    toBeDeletedHyperEdges.Clear();
                    HyperEdgeUpdate hyperEdges = new HyperEdgeUpdate(null, toBeDeletedHyperEdges);

                    VertexUpdateDefinition update = new VertexUpdateDefinition(null, structuredProperties, unstructuredProperties, binaryProperties, singleEdges, hyperEdges);

                    #endregion

                    #region sorting attributes

                    toBeDeletedProperties.Clear();
                    toBeDeletedEdges.Clear();
                    toBeDeletedBinaries.Clear();
                    toBeDeletedUndefinedAttributes.Clear();

                    foreach (var aToBeDeleted in myDeleteRequest.ToBeDeletedAttributes)
                    {
                        if (!vertexType.HasAttribute(aToBeDeleted))
                        {
                            toBeDeletedUndefinedAttributes.Add(aToBeDeleted);
                        }

                        var attribute = vertexType.GetAttributeDefinition(aToBeDeleted);
                        myDeleteRequest.AddDeletedAttribute(attribute.ID);

                        switch (attribute.Kind)
                        {
                            case AttributeType.Property:
                                toBeDeletedProperties.Add(attribute.ID, (IPropertyDefinition)attribute);
                                break;

                            case AttributeType.OutgoingEdge:
                                toBeDeletedEdges.Add(attribute.ID, (IOutgoingEdgeDefinition)attribute);
                                break;

                            case AttributeType.BinaryProperty:
                                toBeDeletedBinaries.Add(attribute.ID, (IBinaryPropertyDefinition)attribute);
                                break;
                        }
                    }

                    #endregion

                    foreach (var aVertex in aVertexTypeGroup.ToList())
                    {
                        #region fetch to be deleted attributes

                        #region properties

                        foreach (var aToBeDeletedProperty in toBeDeletedProperties)
                        {
                            foreach (var aIndexDefinition in aToBeDeletedProperty.Value.InIndices)
                            {
                                RemoveFromIndices(aVertex, 
                                    _indexManager.GetIndices(vertexType, aIndexDefinition.IndexedProperties, mySecurityToken, myTransactionToken));
                            }
                            toBeDeletedStructuredPropertiesUpdate.Add(aToBeDeletedProperty.Key);
                        }

                        #endregion

                        #region edges

                        foreach (var aToBeDeltedEdge in toBeDeletedEdges)
                        {
                            if (aVertex.HasOutgoingEdge(aToBeDeltedEdge.Key))
                            {
                                switch (aToBeDeltedEdge.Value.Multiplicity)
                                {
                                    case EdgeMultiplicity.SingleEdge:

                                        toBeDeletedSingleEdges.Add(aToBeDeltedEdge.Key);

                                        break;
                                    case EdgeMultiplicity.MultiEdge:
                                    case EdgeMultiplicity.HyperEdge:

                                        toBeDeletedHyperEdges.Add(aToBeDeltedEdge.Key);

                                        break;
                                }
                            }
                        }

                        #endregion

                        #region binaries

                        foreach (var aBinaryProperty in toBeDeletedBinaryProperties)
                        {
                            //TODO: Add HasBinaryProperty to IVertex
                            if (aVertex.GetAllBinaryProperties((_, __) => _ == aBinaryProperty).Count() > 0)
                            {
                                toBeDeletedBinaryProperties.Add(aBinaryProperty);
                            }
                        }

                        #endregion

                        #region undefined data

                        foreach (var aUnstructuredProperty in toBeDeletedUndefinedAttributes)
                        {
                            if (aVertex.HasUnstructuredProperty(aUnstructuredProperty))
                            {
                                tobeDeletedUnstructuredProperties.Add(aUnstructuredProperty);
                            }
                        }

                        #endregion

                        #endregion

                        _vertexStore.UpdateVertex(mySecurityToken, myTransactionToken, aVertex.VertexID, aVertex.VertexTypeID, update, true, aVertex.EditionName, aVertex.VertexRevisionID, false);
                    }
                }
            }
            else
            {
                //remove the nodes
                foreach (var aVertexTypeGroup in toBeProcessedVertices.GroupBy(_ => _.VertexTypeID))
                {
                    var vertexType = _vertexTypeManager.ExecuteManager.GetType(aVertexTypeGroup.Key, myTransactionToken, mySecurityToken);

                    foreach (var aVertex in aVertexTypeGroup.ToList())
                    {
                        myDeleteRequest.AddDeletedVertex(aVertex.VertexID);
                        RemoveVertex(aVertex, vertexType, mySecurityToken, myTransactionToken);
                    }
                }
            }
        }