/// <summary>
        /// Validates the specified document.
        /// </summary>
        /// <param name="openXmlPackage">The target WordprocessingDocument, SpreadsheetDocument or PresentationDocument.</param>
        /// <returns>A set of validation erros.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the "openXmlPackage" parameter is null.</exception>
        public IEnumerable <ValidationErrorInfo> Validate(OpenXmlPackage openXmlPackage)
        {
            if (openXmlPackage == null)
            {
                throw new ArgumentNullException(nameof(openXmlPackage));
            }

            if (openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.ProcessMode != MarkupCompatibilityProcessMode.NoProcess &&
                openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.TargetFileFormatVersions != this.FileFormat)
            {
                string exceptionMessage = string.Format(System.Globalization.CultureInfo.CurrentUICulture,
                                                        ExceptionMessages.DocumentFileFormatVersionMismatch,
                                                        openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.TargetFileFormatVersions, this.FileFormat);

                throw new InvalidOperationException(exceptionMessage);
            }

            // Do NOT use "yield return" in this method, as "yield return" are deferred executed.
            // Otherwise, the null check is not performed when the method is called, but rather, when the returned enumerator is moved for the first time.
            // That means that the exception isn't thrown until possibly far, far away from the actual site of the error, which is potentially confusing.

            ValidationResult validationResult = null;

            switch (DocumentTypeDetector.GetDocumentType(openXmlPackage))
            {
            case OpenXmlDocumentType.Spreadsheet:
                validationResult = this.SpreadsheetDocumentValidator.Validate(openXmlPackage as SpreadsheetDocument);
                break;

            case OpenXmlDocumentType.Wordprocessing:
                validationResult = this.WordprocessingDocumentValidator.Validate(openXmlPackage as WordprocessingDocument);
                break;

            case OpenXmlDocumentType.Presentation:
                validationResult = this.PresentationDocumentValidator.Validate(openXmlPackage as PresentationDocument);
                break;

            default:
                throw new System.IO.InvalidDataException(ExceptionMessages.UnknownPackage);
            }

            return(this.YieldResult(validationResult));
        }
        /// <summary>
        /// Validates the specified content in the OpenXmlPart.
        /// </summary>
        /// <param name="openXmlPart">The target OpenXmlPart.</param>
        /// <returns>A set of validation erros.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the "openXmlPart" parameter is null.</exception>
        /// <exception cref="InvalidOperationException">Throw when the specified part is not a defined part in the specified FileFormat version.</exception>
        public IEnumerable <ValidationErrorInfo> Validate(OpenXmlPart openXmlPart)
        {
            if (openXmlPart == null)
            {
                throw new ArgumentNullException(nameof(openXmlPart));
            }

            var openXmlPackage = openXmlPart.OpenXmlPackage;

            if (openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.ProcessMode != MarkupCompatibilityProcessMode.NoProcess &&
                openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.TargetFileFormatVersions != this.FileFormat)
            {
                string exceptionMessage = string.Format(System.Globalization.CultureInfo.CurrentUICulture,
                                                        ExceptionMessages.DocumentFileFormatVersionMismatch,
                                                        openXmlPackage.OpenSettings.MarkupCompatibilityProcessSettings.TargetFileFormatVersions, this.FileFormat);

                throw new InvalidOperationException(exceptionMessage);
            }

            if (!openXmlPart.IsInVersion(this.FileFormat))
            {
                if (openXmlPart is ExtendedPart)
                {
                    throw new InvalidOperationException(ExceptionMessages.PartNotInVersion);
                }
                else
                {
                    string strMessage;

                    // All Office 2007 and 2010 parts are allowed in Office 2013.

                    switch (this.FileFormat)
                    {
                    case FileFormatVersions.Office2007:
                        strMessage = ExceptionMessages.PartIsNotInOffice2007;
                        break;

                    case FileFormatVersions.Office2010:
                        strMessage = ExceptionMessages.PartIsNotInOffice2010;
                        break;

                    case FileFormatVersions.Office2013:     // Falls through...
                    default:
                        strMessage = ExceptionMessages.PartIsNotInOffice2013;
                        break;
                    }

                    throw new InvalidOperationException(strMessage);
                }
            }

            // Do NOT use "yield return" in this method, as "yield return" are deferred executed.
            // Otherwise, the null check is not performed when the method is called, but rather, when the returned enumerator is moved for the first time.
            // That means that the exception isn't thrown until possibly far, far away from the actual site of the error, which is potentially confusing.

            OpenXmlPackage package = openXmlPart.OpenXmlPackage;

            Debug.Assert(package != null);

            ValidationResult validationResult = null;

            switch (DocumentTypeDetector.GetDocumentType(package))
            {
            case OpenXmlDocumentType.Spreadsheet:
                validationResult = this.SpreadsheetDocumentValidator.Validate(openXmlPart);
                break;

            case OpenXmlDocumentType.Wordprocessing:
                validationResult = this.WordprocessingDocumentValidator.Validate(openXmlPart);
                break;

            case OpenXmlDocumentType.Presentation:
                validationResult = this.PresentationDocumentValidator.Validate(openXmlPart);
                break;

            default:
                throw new System.IO.InvalidDataException(ExceptionMessages.UnknownPackage);
            }

            return(this.YieldResult(validationResult));
        }