/// <summary>
        /// Called when [place holder found].
        /// </summary>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        private void OnPlaceHolderFound(OpenXmlElementDataContext openXmlElementDataContext)
        {
            string templateTagPart = string.Empty;
            string tagGuidPart = string.Empty;
            SdtElement element = openXmlElementDataContext.Element as SdtElement;
            GetTagValue(element, out templateTagPart, out tagGuidPart);

            if (this.generationInfo.PlaceHolderTagToTypeCollection.ContainsKey(templateTagPart))
            {
                switch (this.generationInfo.PlaceHolderTagToTypeCollection[templateTagPart])
                {
                    case PlaceHolderType.None:
                        break;
                    case PlaceHolderType.NonRecursive:
                        this.NonRecursivePlaceholderFound(templateTagPart, openXmlElementDataContext);
                        break;
                    case PlaceHolderType.Recursive:
                        this.RecursivePlaceholderFound(templateTagPart, openXmlElementDataContext);
                        break;
                    case PlaceHolderType.Ignore:
                        this.IgnorePlaceholderFound(templateTagPart, openXmlElementDataContext);
                        break;
                    case PlaceHolderType.Container:
                        this.ContainerPlaceholderFound(templateTagPart, openXmlElementDataContext);
                        break;
                }
            }
        }
        /// <summary>
        /// Populates the other open XML elements.
        /// </summary>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        private void PopulateOtherOpenXmlElements(OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (openXmlElementDataContext.Element is OpenXmlCompositeElement && openXmlElementDataContext.Element.HasChildren)
            {
                List<OpenXmlElement> elements = openXmlElementDataContext.Element.Elements().ToList();

                foreach (var element in elements)
                {
                    if (element is OpenXmlCompositeElement)
                    {
                        this.SetContentInPlaceholders(new OpenXmlElementDataContext() { Element = element, DataContext = openXmlElementDataContext.DataContext });
                    }
                }
            }
        }
        /// <summary>
        /// Determines whether [is content control] [the specified open XML element data context].
        /// </summary>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        /// <returns>
        ///   <c>true</c> if [is content control] [the specified open XML element data context]; otherwise, <c>false</c>.
        /// </returns>
        private bool IsContentControl(OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (openXmlElementDataContext == null || openXmlElementDataContext.Element == null)
            {
                return false;
            }

            return openXmlElementDataContext.Element is SdtBlock || openXmlElementDataContext.Element is SdtRun || openXmlElementDataContext.Element is SdtRow || openXmlElementDataContext.Element is SdtCell;
        }
        /// <summary>
        /// Sets the content in placeholders.
        /// </summary>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        protected void SetContentInPlaceholders(OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (IsContentControl(openXmlElementDataContext))
            {
                string templateTagPart = string.Empty;
                string tagGuidPart = string.Empty;
                SdtElement element = openXmlElementDataContext.Element as SdtElement;
                GetTagValue(element, out templateTagPart, out tagGuidPart);

                if (this.generationInfo.PlaceHolderTagToTypeCollection.ContainsKey(templateTagPart))
                {
                    this.OnPlaceHolderFound(openXmlElementDataContext);
                }
                else
                {
                    this.PopulateOtherOpenXmlElements(openXmlElementDataContext);
                }
            }
            else
            {
                this.PopulateOtherOpenXmlElements(openXmlElementDataContext);
            }
        }
 /// <summary>
 /// Recursive placeholder found.
 /// </summary>
 /// <param name="placeholderTag">The placeholder tag.</param>
 /// <param name="openXmlElementDataContext">The open XML element data context.</param>
 protected abstract void RecursivePlaceholderFound(string placeholderTag, OpenXmlElementDataContext openXmlElementDataContext);
 /// <summary>
 /// Container placeholder found.
 /// </summary>
 /// <param name="placeholderTag">The placeholder tag.</param>
 /// <param name="openXmlElementDataContext">The open XML element data context.</param>
 protected abstract void ContainerPlaceholderFound(string placeholderTag, OpenXmlElementDataContext openXmlElementDataContext);
        /// <summary>
        /// Clones the element and set content in placeholders.
        /// </summary>
        /// <param name="openXmlElementDataContext">The open XML element data context.</param>
        /// <returns></returns>
        protected SdtElement CloneElementAndSetContentInPlaceholders(OpenXmlElementDataContext openXmlElementDataContext)
        {
            if (openXmlElementDataContext == null)
            {
                throw new ArgumentNullException("openXmlElementDataContext");
            }

            if (openXmlElementDataContext.Element == null)
            {
                throw new ArgumentNullException("openXmlElementDataContext.element");
            }

            SdtElement clonedSdtElement = null;

            if (openXmlElementDataContext.Element.Parent != null && openXmlElementDataContext.Element.Parent is Paragraph)
            {
                Paragraph clonedPara = openXmlElementDataContext.Element.Parent.InsertBeforeSelf(openXmlElementDataContext.Element.Parent.CloneNode(true) as Paragraph);
                clonedSdtElement = clonedPara.Descendants<SdtElement>().First();
            }
            else
            {
                clonedSdtElement = openXmlElementDataContext.Element.InsertBeforeSelf(openXmlElementDataContext.Element.CloneNode(true) as SdtElement);
            }

            foreach (var v in clonedSdtElement.Elements())
            {
                this.SetContentInPlaceholders(new OpenXmlElementDataContext() { Element = v, DataContext = openXmlElementDataContext.DataContext });
            }

            return clonedSdtElement;
        }