/// <summary>
        /// Adds the child resources.
        /// </summary>
        /// <param name="extractionPath">The extraction path.</param>
        /// <param name="document">The document.</param>
        /// <param name="resource">The resource.</param>
        /// <param name="zentityContext">The zentity context.</param>
        private static void AddChildResources(
            string extractionPath,
            MetsDocument document,
            ScholarlyWork resource,
            ZentityContext zentityContext)
        {
            resource.Container = new ScholarlyWorkContainer();
            ScholarlyWorkContainer childContainer = null;

            string[] fileNames = Directory.GetFiles(extractionPath)
                                 .Select(path => GetFileName(path))
                                 .Where(name => SwordConstants.MetsDocumentName != name)
                                 .ToArray();

            if (0 < fileNames.Length)
            {
                childContainer = new ScholarlyWorkContainer();
                resource.Container.ContainedWorks.Add(childContainer);
            }

            // Loop though all files which are extracted.
            foreach (string fileName in fileNames)
            {
                // Get the extension
                int    dotIndex      = fileName.LastIndexOf('.');
                string fileExtension = (0 < dotIndex) ? fileName.Substring(dotIndex + 1) : string.Empty;

                #region Upload Zip File Contents

                // Get Metadata for the specified fileName
                MetadataSection dataSection = document.Files[fileName];

                // Create resource against each type as specified in the METS document.
                ScholarlyWork individualResource = CreateResouceUsingMetsMetadata(dataSection);

                UpdateResourceProeprties(zentityContext, individualResource, dataSection);

                // Create Media and Upload file contents.
                Core.File individualMediaResource = AddFileResource(zentityContext,
                                                                    individualResource,
                                                                    extractionPath + "\\" + fileName);
                individualMediaResource.MimeType      = AtomPubHelper.GetMimeTypeFromFileExtension(fileExtension);
                individualMediaResource.FileExtension = fileExtension;

                // Save file name in notes for future references.
                individualMediaResource.Description = fileName;

                // Associate with the main resource.
                childContainer.ContainedWorks.Add(individualResource);

                #endregion

                AuthenticatedToken authenticatedToken = CoreHelper.GetAuthenticationToken();

                individualResource.GrantDefaultPermissions(zentityContext, authenticatedToken);
                individualMediaResource.GrantDefaultPermissions(zentityContext, authenticatedToken);
            }
        }
        /// <summary>
        /// Update the properties of the resource.
        /// </summary>
        /// <param name="zentityContext">The ZentityContext to which the resource is attached.</param>
        /// <param name="resource">Resource to be update scalar properties.</param>
        /// <param name="dataSection"><typeref name="MetadataSection"/> Metadata which contains property values.</param>
        private static void UpdateResourceProeprties(ZentityContext zentityContext, ScholarlyWork resource,
                                                     MetadataSection dataSection)
        {
            if (null == resource)
            {
                throw new ArgumentNullException("resource");
            }

            if (null == dataSection)
            {
                throw new ArgumentNullException("dataSection");
            }

            resource.DateModified = DateTime.Now;

            PropertyInfo[] properties = resource.GetType().GetProperties()
                                        .Where(property => PropertyMapper.ResourceProperties.ContainsKey(property.Name))
                                        .ToArray();

            // Loop for each property of the resource.
            foreach (PropertyInfo property in properties)
            {
                ReadOnlyCollection <string> values = GetPropertyValues(property.Name, dataSection);

                // If no values are present for current property, do not process.
                if (null == values || 0 >= values.Count)
                {
                    continue;
                }

                // Check if the property is scalar property or Navigation Property.
                object[] navigationAttr = property.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true);

                if (0 < navigationAttr.Length)
                {
                    UpdateNavigationproperties(zentityContext, resource, property, values);
                }
                else
                {
                    UpdateScalarProperties(resource, property, values);
                }
            }
        }
        /// <summary>
        /// Create resource using metadata.
        /// </summary>
        /// <param name="dataSection">Metadata Section containing metadata of the resource.</param>
        /// <returns>A resource of type ScholarlyWork or its derived type.</returns>
        private static ScholarlyWork CreateResouceUsingMetsMetadata(MetadataSection dataSection)
        {
            if (null == dataSection)
            {
                throw new ArgumentNullException("dataSection");
            }

            ScholarlyWork resource     = null;
            Type          resourceType = null;

            // Get the resource type specified in METS document.
            if (null != dataSection.DescriptiveMetadata && null != dataSection.DescriptiveMetadata.ResourceType &&
                0 < dataSection.DescriptiveMetadata.ResourceType.Count)
            {
                string resourceTypeName = dataSection.DescriptiveMetadata.ResourceType[0];

                // Check if the resource type is derived from ScholarlyWork,
                // as Sword & AtomPub supports only ScholarlyWork and its derivatives.
                if (AtomPubHelper.IsValidCollectionType(resourceTypeName))
                {
                    resourceType = CoreHelper.GetSystemResourceType(resourceTypeName);
                }
            }

            // Take ScholarlyWork as default resource type.
            if (null == resourceType)
            {
                resourceType = typeof(ScholarlyWork);
            }

            // Create resource of type ScholarlyWork or its derived types.
            resource = Activator.CreateInstance(resourceType, false) as ScholarlyWork;
            if (null == resource)
            {
                throw new SwordException(Properties.Resources.UNSUPPORTED_RESOURCE_TYPE);
            }

            return(resource);
        }
        /// <summary>
        /// Gets the property values.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="dataSection">The data section.</param>
        /// <returns>Readonly list of property values.</returns>
        private static ReadOnlyCollection <string> GetPropertyValues(string propertyName, MetadataSection dataSection)
        {
            //Get the equivalent DC property for a resource property.
            string valueKey = PropertyMapper.ResourceProperties[propertyName];
            ReadOnlyCollection <string> values = null; //

            // Get the values for the current DC property
            // Check if the current property is 'Rights' property
            if (SwordConstants.RightsProperty == valueKey)
            {
                values = (null != dataSection.AdministrativeMetadata) ?
                         dataSection.AdministrativeMetadata[valueKey] as ReadOnlyCollection <string> : null;
            }
            else
            {
                values = (null != dataSection.DescriptiveMetadata) ?
                         dataSection.DescriptiveMetadata[valueKey] as ReadOnlyCollection <string> : null;
            }
            return(values);
        }