Storage Manifest data element
Inheritance: DataElementData
        /// <summary>
        /// This method is used to get the list of object group data element from a list of data element.
        /// </summary>
        /// <param name="dataElements">Specify the data element list.</param>
        /// <param name="storageIndexExGuid">Specify the storage index extended GUID.</param>
        /// <param name="rootExGuid">Output parameter to represent the root node object.</param>
        /// <returns>Return the list of object group data elements.</returns>
        public static List <ObjectGroupDataElementData> GetDataObjectDataElementData(List <DataElement> dataElements, ExGuid storageIndexExGuid, out ExGuid rootExGuid)
        {
            ExGuid manifestMappingGuid;
            Dictionary <CellID, ExGuid> cellIDMappings;
            Dictionary <ExGuid, ExGuid> revisionIDMappings;

            AnalyzeStorageIndexDataElement(dataElements, storageIndexExGuid, out manifestMappingGuid, out cellIDMappings, out revisionIDMappings);
            StorageManifestDataElementData manifestData = GetStorageManifestDataElementData(dataElements, manifestMappingGuid);

            if (manifestData == null)
            {
                throw new InvalidOperationException("Cannot find the storage manifest data element with ExGuid " + manifestMappingGuid.GUID.ToString());
            }

            CellManifestDataElementData     cellData     = GetCellManifestDataElementData(dataElements, manifestData, cellIDMappings);
            RevisionManifestDataElementData revisionData = GetRevisionManifestDataElementData(dataElements, cellData, revisionIDMappings);

            return(GetDataObjectDataElementData(dataElements, revisionData, out rootExGuid));
        }
        /// <summary>
        /// This method is used to create the storage manifest data element.
        /// </summary>
        /// <param name="cellIDMapping">Specify the mapping of cell manifest.</param>
        /// <returns>Return the storage manifest data element.</returns>
        public static DataElement CreateStorageManifestDataElement(Dictionary <CellID, ExGuid> cellIDMapping)
        {
            StorageManifestDataElementData data = new StorageManifestDataElementData();

            data.StorageManifestSchemaGUID = new StorageManifestSchemaGUID()
            {
                GUID = SchemaGuid
            };

            foreach (KeyValuePair <CellID, ExGuid> kv in cellIDMapping)
            {
                StorageManifestRootDeclare manifestRootDeclare = new StorageManifestRootDeclare();
                manifestRootDeclare.RootExtendedGUID = new ExGuid(2u, RootExGuid);
                manifestRootDeclare.CellID           = new CellID(kv.Key);
                data.StorageManifestRootDeclareList.Add(manifestRootDeclare);
            }

            return(new DataElement(DataElementType.StorageManifestDataElementData, data));
        }
        /// <summary>
        /// This method is used to get cell manifest data element from a list of data element.
        /// </summary>
        /// <param name="dataElements">Specify the data element list.</param>
        /// <param name="manifestDataElementData">Specify the manifest data element.</param>
        /// <param name="cellIDMappings">Specify mapping of cell id.</param>
        /// <returns>Return the cell manifest data element.</returns>
        public static CellManifestDataElementData GetCellManifestDataElementData(List<DataElement> dataElements, StorageManifestDataElementData manifestDataElementData, Dictionary<CellID, ExGuid> cellIDMappings)
        {
            CellID cellID = new CellID(new ExGuid(1u, RootExGuid), new ExGuid(1u, CellSecondExGuid));

            foreach (StorageManifestRootDeclare kv in manifestDataElementData.StorageManifestRootDeclareList)
            {
                if (kv.RootExtendedGUID.Equals(new ExGuid(2u, RootExGuid)) && kv.CellID.Equals(cellID))
                {
                    if (!cellIDMappings.ContainsKey(kv.CellID))
                    {
                        throw new InvalidOperationException(string.Format("Cannot fin the Cell ID {0} in the cell id mapping", cellID.ToString()));
                    }

                    ExGuid cellMappingID = cellIDMappings[kv.CellID];

                    DataElement dataElement = dataElements.Find(element => element.DataElementExtendedGUID.Equals(cellMappingID));
                    if (dataElement == null)
                    {
                        throw new InvalidOperationException("Cannot find the  cell data element with ExGuid " + cellMappingID.GUID.ToString());
                    }

                    return dataElement.GetData<CellManifestDataElementData>();
                }
            }

            throw new InvalidOperationException("Cannot find the CellManifestDataElement");
        }
        /// <summary>
        /// This method is used to create the storage manifest data element.
        /// </summary>
        /// <param name="cellIDMapping">Specify the mapping of cell manifest.</param>
        /// <returns>Return the storage manifest data element.</returns>
        public static DataElement CreateStorageManifestDataElement(Dictionary<CellID, ExGuid> cellIDMapping)
        {
            StorageManifestDataElementData data = new StorageManifestDataElementData();
            data.StorageManifestSchemaGUID = new StorageManifestSchemaGUID() { GUID = SchemaGuid };

            foreach (KeyValuePair<CellID, ExGuid> kv in cellIDMapping)
            {
                StorageManifestRootDeclare manifestRootDeclare = new StorageManifestRootDeclare();
                manifestRootDeclare.RootExtendedGUID = new ExGuid(2u, RootExGuid);
                manifestRootDeclare.CellID = new CellID(kv.Key);
                data.StorageManifestRootDeclareList.Add(manifestRootDeclare);
            }

            return new DataElement(DataElementType.StorageManifestDataElementData, data);
        }
        /// <summary>
        /// This method is used to get cell manifest data element from a list of data element.
        /// </summary>
        /// <param name="dataElements">Specify the data element list.</param>
        /// <param name="manifestDataElementData">Specify the manifest data element.</param>
        /// <param name="cellIDMappings">Specify mapping of cell id.</param>
        /// <returns>Return the cell manifest data element.</returns>
        public static CellManifestDataElementData GetCellManifestDataElementData(List <DataElement> dataElements, StorageManifestDataElementData manifestDataElementData, Dictionary <CellID, ExGuid> cellIDMappings)
        {
            CellID cellID = new CellID(new ExGuid(1u, RootExGuid), new ExGuid(1u, CellSecondExGuid));

            foreach (StorageManifestRootDeclare kv in manifestDataElementData.StorageManifestRootDeclareList)
            {
                if (kv.RootExtendedGUID.Equals(new ExGuid(2u, RootExGuid)) && kv.CellID.Equals(cellID))
                {
                    if (!cellIDMappings.ContainsKey(kv.CellID))
                    {
                        throw new InvalidOperationException(string.Format("Cannot fin the Cell ID {0} in the cell id mapping", cellID.ToString()));
                    }

                    ExGuid cellMappingID = cellIDMappings[kv.CellID];

                    DataElement dataElement = dataElements.Find(element => element.DataElementExtendedGUID.Equals(cellMappingID));
                    if (dataElement == null)
                    {
                        throw new InvalidOperationException("Cannot find the  cell data element with ExGuid " + cellMappingID.GUID.ToString());
                    }

                    return(dataElement.GetData <CellManifestDataElementData>());
                }
            }

            throw new InvalidOperationException("Cannot find the CellManifestDataElement");
        }
        /// <summary>
        /// This method is used to try to analyze the returned whether data elements are complete.
        /// </summary>
        /// <param name="dataElements">Specify the data elements list.</param>
        /// <param name="storageIndexExGuid">Specify the storage index extended GUID.</param>
        /// <returns>If the data elements start with the specified storage index extended GUID are complete, return true. Otherwise return false.</returns>
        public static bool TryAnalyzeWhetherFullDataElementList(List <DataElement> dataElements, ExGuid storageIndexExGuid)
        {
            ExGuid manifestMappingGuid;
            Dictionary <CellID, ExGuid> cellIDMappings;
            Dictionary <ExGuid, ExGuid> revisionIDMappings;

            if (!AnalyzeStorageIndexDataElement(dataElements, storageIndexExGuid, out manifestMappingGuid, out cellIDMappings, out revisionIDMappings))
            {
                return(false);
            }

            if (cellIDMappings.Count == 0)
            {
                return(false);
            }

            if (revisionIDMappings.Count == 0)
            {
                return(false);
            }

            StorageManifestDataElementData manifestData = GetStorageManifestDataElementData(dataElements, manifestMappingGuid);

            if (manifestData == null)
            {
                return(false);
            }

            foreach (StorageManifestRootDeclare kv in manifestData.StorageManifestRootDeclareList)
            {
                if (!cellIDMappings.ContainsKey(kv.CellID))
                {
                    throw new InvalidOperationException(string.Format("Cannot fin the Cell ID {0} in the cell id mapping", kv.CellID.ToString()));
                }

                ExGuid      cellMappingID = cellIDMappings[kv.CellID];
                DataElement dataElement   = dataElements.Find(element => element.DataElementExtendedGUID.Equals(cellMappingID));
                if (dataElement == null)
                {
                    return(false);
                }

                CellManifestDataElementData cellData = dataElement.GetData <CellManifestDataElementData>();
                ExGuid currentRevisionExGuid         = cellData.CellManifestCurrentRevision.CellManifestCurrentRevisionExtendedGUID;
                if (!revisionIDMappings.ContainsKey(currentRevisionExGuid))
                {
                    throw new InvalidOperationException(string.Format("Cannot find the revision id {0} in the revisionMapping", currentRevisionExGuid.ToString()));
                }

                ExGuid revisionMapping = revisionIDMappings[currentRevisionExGuid];
                dataElement = dataElements.Find(element => element.DataElementExtendedGUID.Equals(revisionMapping));
                if (dataElement == null)
                {
                    return(false);
                }

                RevisionManifestDataElementData revisionData = dataElement.GetData <RevisionManifestDataElementData>();
                foreach (RevisionManifestObjectGroupReferences reference in revisionData.RevisionManifestObjectGroupReferencesList)
                {
                    dataElement = dataElements.Find(element => element.DataElementExtendedGUID.Equals(reference.ObjectGroupExtendedGUID));
                    if (dataElement == null)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }