//=====================================================================

        /// <summary>
        /// Private copy constructor
        /// </summary>
        /// <param name="clone">The transform component argument to clone</param>
        private TransformComponentArgument(TransformComponentArgument clone)
        {
            this.Key = clone.Key;
            this.IsForConceptualBuild = clone.IsForConceptualBuild;
            this.IsForReferenceBuild = clone.IsForReferenceBuild;
            this.Description = clone.Description;
            this.Value = clone.Value;

            if(this.Value == null && this.Content != null)
                this.Content = new XElement(clone.Content);
        }
        //=====================================================================

        /// <summary>
        /// Private copy constructor
        /// </summary>
        /// <param name="clone">The transform component argument to clone</param>
        private TransformComponentArgument(TransformComponentArgument clone)
        {
            this.Key = clone.Key;
            this.IsForConceptualBuild = clone.IsForConceptualBuild;
            this.IsForReferenceBuild  = clone.IsForReferenceBuild;
            this.Description          = clone.Description;
            this.Value = clone.Value;

            if (this.Value == null && this.Content != null)
            {
                this.Content = new XElement(clone.Content);
            }
        }
        /// <inheritdoc />
        protected override bool BindControlValue(Control control)
        {
            PresentationStyleSettings pss = null;
            ProjectProperty argsProp, styleProp;
            TransformComponentArgument tca, clone;
            TreeNode t;

#if !STANDALONEGUI
            SandcastleProject currentProject = null;

            if(base.ProjectMgr != null)
                currentProject = ((SandcastleBuilderProjectNode)base.ProjectMgr).SandcastleProject;

            if(presentationStyles == null || currentProject == null || currentProject.Filename != lastProjectName)
                this.LoadAvailablePresentationStyles();

            if(base.ProjectMgr == null || currentProject == null)
            {
                tvArguments.Nodes.Clear();
                return false;
            }

            argsProp = this.ProjectMgr.BuildProject.GetProperty("TransformComponentArguments");
            styleProp = this.ProjectMgr.BuildProject.GetProperty("PresentationStyle");
#else
            if(presentationStyles == null || base.CurrentProject == null || base.CurrentProject.Filename != lastProjectName)
                this.LoadAvailablePresentationStyles();

            if(this.CurrentProject == null)
            {
                tvArguments.Nodes.Clear();
                return false;
            }

            argsProp = this.CurrentProject.MSBuildProject.GetProperty("TransformComponentArguments");
            styleProp = this.CurrentProject.MSBuildProject.GetProperty("PresentationStyle");
#endif
            if((styleProp == null && lastStyle != null) || (styleProp != null &&
              !String.IsNullOrEmpty(styleProp.UnevaluatedValue) &&
              styleProp.UnevaluatedValue.Equals(lastStyle, StringComparison.OrdinalIgnoreCase)))
                return true;

            tvArguments.Nodes.Clear();

            var transformComponentArgs = new Dictionary<string, TransformComponentArgument>();

            try
            {
                // Get the transform component arguments defined in the project if any
                if(argsProp != null && !String.IsNullOrEmpty(argsProp.UnevaluatedValue))
                {
                    using(var xr = new XmlTextReader("<Args>" + argsProp.UnevaluatedValue + "</Args>",
                      XmlNodeType.Element, new XmlParserContext(null, null, null, XmlSpace.Preserve)))
                    {
                        xr.Namespaces = false;
                        xr.MoveToContent();

                        foreach(var arg in XElement.Load(xr, LoadOptions.PreserveWhitespace).Descendants("Argument"))
                        {
                            tca = new TransformComponentArgument(arg);
                            transformComponentArgs.Add(tca.Key, tca);
                        }
                    }
                }

                if(styleProp != null && !String.IsNullOrWhiteSpace(styleProp.UnevaluatedValue))
                {
                    var style = presentationStyles.FirstOrDefault(s => s.Metadata.Id.Equals(
                        styleProp.UnevaluatedValue, StringComparison.OrdinalIgnoreCase));

                    if(style != null)
                        pss = style.Value;
                }

                if(pss == null)
                {
                    var style = presentationStyles.FirstOrDefault(s => s.Metadata.Id.Equals(
                        Constants.DefaultPresentationStyle, StringComparison.OrdinalIgnoreCase));

                    if(style != null)
                        pss = style.Value;
                    else
                        pss = presentationStyles.First().Value;
                }

                lastStyle = (styleProp != null) ? styleProp.UnevaluatedValue : Constants.DefaultPresentationStyle;

                // Create an entry for each transform component argument in the presentation style
                foreach(var arg in pss.TransformComponentArguments)
                {
                    t = tvArguments.Nodes.Add(arg.Key);
                    t.Tag = clone = arg.Clone();

                    // Use the value from the project or the cloned default if not present
                    if(transformComponentArgs.TryGetValue(arg.Key, out tca))
                    {
                        clone.Value = tca.Value;
                        clone.Content = tca.Content;
                    }
                }
            }
            catch(Exception ex)
            {
#if !STANDALONEGUI
                MessageBox.Show("Unable to load transform component arguments.  Error " + ex.Message,
                    Resources.PackageTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
#else
                MessageBox.Show("Unable to load transform component arguments.  Error " + ex.Message,
                    Sandcastle.Core.Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
            }

            if(tvArguments.Nodes.Count != 0)
            {
                tvArguments.SelectedNode = tvArguments.Nodes[0];
                txtValue.Enabled = true;
            }
            else
                txtValue.Enabled = false;

            return true;
        }
        /// <summary>
        /// This is called when the component cache has finished being loaded and is available for use
        /// </summary>
        /// <param name="sender">The sender of the event</param>
        /// <param name="e">The event arguments</param>
        private void componentCache_ComponentContainerLoaded(object sender, EventArgs e)
        {
            PresentationStyleSettings pss = null;
            ProjectProperty argsProp, styleProp;
            TransformComponentArgument tca, clone;
            TreeNode t;

#if !STANDALONEGUI
            if(this.IsDisposed || this.ProjectMgr == null)
                return;

            argsProp = this.ProjectMgr.BuildProject.GetProperty("TransformComponentArguments");
            styleProp = this.ProjectMgr.BuildProject.GetProperty("PresentationStyle");
#else
            if(this.IsDisposed || this.CurrentProject == null)
                return;

            argsProp = this.CurrentProject.MSBuildProject.GetProperty("TransformComponentArguments");
            styleProp = this.CurrentProject.MSBuildProject.GetProperty("PresentationStyle");
#endif
            // Skip it if already loaded and nothing changed
            if((styleProp == null && lastStyle != null) || (styleProp != null &&
              !String.IsNullOrEmpty(styleProp.UnevaluatedValue) &&
              styleProp.UnevaluatedValue.Equals(lastStyle, StringComparison.OrdinalIgnoreCase)))
                return;

            tvArguments.Enabled = true;
            tvArguments.Nodes.Clear();

            var transformComponentArgs = new Dictionary<string, TransformComponentArgument>();

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                tvArguments.BeginUpdate();

                HashSet<string> presentationStyleIds = new HashSet<string>();

                presentationStyles = new List<Lazy<PresentationStyleSettings, IPresentationStyleMetadata>>();

                // There may be duplicate presentation style IDs across the assemblies found.  See
                // BuildComponentManger.GetComponentContainer() for the folder search precedence.  Only the
                // first component for a unique ID will be used.
                foreach(var style in componentCache.ComponentContainer.GetExports<PresentationStyleSettings,
                  IPresentationStyleMetadata>())
                    if(!presentationStyleIds.Contains(style.Metadata.Id))
                    {
                        presentationStyles.Add(style);
                        presentationStyleIds.Add(style.Metadata.Id);
                    }

                // Get the transform component arguments defined in the project if any
                if(argsProp != null && !String.IsNullOrEmpty(argsProp.UnevaluatedValue))
                {
                    using(var xr = new XmlTextReader("<Args>" + argsProp.UnevaluatedValue + "</Args>",
                      XmlNodeType.Element, new XmlParserContext(null, null, null, XmlSpace.Preserve)))
                    {
                        xr.Namespaces = false;
                        xr.MoveToContent();

                        foreach(var arg in XElement.Load(xr, LoadOptions.PreserveWhitespace).Descendants("Argument"))
                        {
                            tca = new TransformComponentArgument(arg);
                            transformComponentArgs.Add(tca.Key, tca);
                        }
                    }
                }

                if(styleProp != null && !String.IsNullOrWhiteSpace(styleProp.UnevaluatedValue))
                {
                    var style = presentationStyles.FirstOrDefault(s => s.Metadata.Id.Equals(
                        styleProp.UnevaluatedValue, StringComparison.OrdinalIgnoreCase));

                    if(style != null)
                        pss = style.Value;
                }

                if(pss == null)
                {
                    var style = presentationStyles.FirstOrDefault(s => s.Metadata.Id.Equals(
                        Constants.DefaultPresentationStyle, StringComparison.OrdinalIgnoreCase));

                    if(style != null)
                        pss = style.Value;
                    else
                        pss = presentationStyles.First().Value;
                }

                lastStyle = (styleProp != null) ? styleProp.UnevaluatedValue : Constants.DefaultPresentationStyle;

                // Create an entry for each transform component argument in the presentation style
                foreach(var arg in pss.TransformComponentArguments)
                {
                    t = tvArguments.Nodes.Add(arg.Key);
                    t.Tag = clone = arg.Clone();

                    // Use the value from the project or the cloned default if not present
                    if(transformComponentArgs.TryGetValue(arg.Key, out tca))
                    {
                        clone.Value = tca.Value;
                        clone.Content = tca.Content;
                    }
                }
            }
            catch(Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);

                MessageBox.Show("Unable to load transform component arguments.  Error " + ex.Message,
                    messageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                tvArguments.EndUpdate();
                Cursor.Current = Cursors.Default;
            }

            if(tvArguments.Nodes.Count != 0)
            {
                tvArguments.SelectedNode = tvArguments.Nodes[0];
                txtValue.Enabled = true;
            }
            else
                txtValue.Enabled = false;

            loadingInfo = false;
        }