/// <summary>
        /// GetComponentInfo returns metadata about the variables/types (and optionally dialogs and mapping info)
        /// for the indicated template's interview.
        /// </summary>
        /// <param name="template">The template for which to return a ComponentInfo object.</param>
        /// <param name="includeDialogs">True if dialog components are to be included in the returned <c>ComponentInfo</c>.</param>
        /// <include file="../../Shared/Help.xml" path="Help/string/param[@name='logRef']"/>
        /// <returns></returns>
        public ComponentInfo GetComponentInfo(Template template, bool includeDialogs, string logRef)
        {
            string logStr = logRef == null ? string.Empty : logRef;

            // Validate input parameters, creating defaults as appropriate.
            if (template == null)
                throw new ArgumentNullException("template", @"Local.Services.GetInterviewFile: the ""template"" parameter passed in was null or empty, logRef: " + logStr);

            string templateFilePath = template.GetFullPath();

            //Get the hvc path. GetHvcPath will also validate the template file name.
            string hvcPath;
            GetHvcPath(templateFilePath, out hvcPath);
            if (hvcPath.Length == 0)
                throw new Exception("Invalid template path.");
            if (!File.Exists(hvcPath))
                throw new HotDocs.Server.HotDocsServerException("You do not have read access to the variable collection file (.hvc)");

            // Instantiate a ComponentInfo object to hold the data to be returned
            ComponentInfo cmpInfo = new ComponentInfo();

            // Load the HVC variable collection
            using (HotDocs.Server.VariableCollection varCol = new HotDocs.Server.VariableCollection(hvcPath))
            {
                for (int i = 0; i < varCol.Count; i++)
                    cmpInfo.AddVariable(new Contracts.VariableInfo { Name = varCol.VarName(i), Type = AnsTypeToString(varCol.VarType(i)) });
            }

            // Load the Dialogs (if requested)
            if (includeDialogs)
            {
                // Load the component collection from disk
                using (var cmpColl = new HotDocs.Server.ComponentCollection())
                {
                    cmpColl.Open(templateFilePath, hdsi.CMPOpenOptions.LoadAllCompLibs);
                    // Iterate through the component collection and add dialogs to ComponentInfo
                    foreach (HotDocs.Server.Component cmp in cmpColl)
                    {
                        if (cmp.Type == hdsi.hdCmpType.hdDialog)
                        {
                            // Fetch dialog properties (AnswerSource, Repeat, variable list and mappingNames) from the component collection
                            object[] variableNames = null;
                            object[] mappingNames = null;
                            DialogInfo dlgInfo = new DialogInfo();
                            dlgInfo.Name = cmp.Name;

                            using (HotDocs.Server.ComponentProperties properties = cmp.Properties)
                            {
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["Variables"])
                                {
                                    variableNames = (object[])p.Value;
                                };
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["IsRepeated"])
                                using (HotDocs.Server.ComponentProperty p2 = (HotDocs.Server.ComponentProperty)properties["IsSpread"])
                                {
                                    dlgInfo.Repeat = (bool)p.Value || (bool)p2.Value;
                                };
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["AnswerSource"])
                                {
                                    dlgInfo.AnswerSource = ((p != null) && (!String.IsNullOrWhiteSpace((string)p.Value))) ? (string)p.Value : null;
                                };
                                if (dlgInfo.AnswerSource != null)
                                {
                                    using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["MappingNames"])
                                    {
                                        mappingNames = (object[])p.Value;
                                    };
                                }
                            }

                            // Add the mapping information to the dialog
                            // Note that variableNames.Length is always equal to mappingNames.Length if mappingNames.Length is not null.
                            for (int i = 0; i < variableNames.Length; i++)
                            {
                                string variableName = variableNames[i].ToString();
                                if (cmpInfo.IsDefinedVariable(variableName))
                                {
                                    //The i < mappingNames.Length test here is strictly defensive.
                                    string mappingName = (mappingNames != null && i < mappingNames.Length) ? mappingNames[i].ToString() : null;

                                    dlgInfo.Items.Add(new DialogItemInfo
                                    {
                                        Name = variableName,
                                        Mapping = String.IsNullOrWhiteSpace(mappingName) ? null : mappingName
                                    });
                                }
                            }

                            // Adds the dialog to ComponentInfo object IF it contains any variables that were in the HVC
                            if (dlgInfo.Items.Count > 0)
                                cmpInfo.AddDialog(dlgInfo);
                        }
                    }
                }
            }
            return cmpInfo;
        }
        /// <summary>
        /// GetComponentInfo returns metadata about the variables/types (and optionally dialogs and mapping info)
        /// for the indicated template's interview.
        /// </summary>
        /// <param name="template">The template for which to return a ComponentInfo object.</param>
        /// <param name="includeDialogs">True if dialog components are to be included in the returned <c>ComponentInfo</c>.</param>
        /// <include file="../../Shared/Help.xml" path="Help/string/param[@name='logRef']"/>
        /// <returns></returns>
        public ComponentInfo GetComponentInfo(Template template, bool includeDialogs, string logRef)
        {
            string logStr = logRef == null ? string.Empty : logRef;

            // Validate input parameters, creating defaults as appropriate.
            if (template == null)
            {
                throw new ArgumentNullException("template", @"Local.Services.GetInterviewFile: the ""template"" parameter passed in was null or empty, logRef: " + logStr);
            }

            string templateFilePath = template.GetFullPath();

            //Get the hvc path. GetHvcPath will also validate the template file name.
            string hvcPath;

            GetHvcPath(templateFilePath, out hvcPath);
            if (hvcPath.Length == 0)
            {
                throw new Exception("Invalid template path.");
            }
            if (!File.Exists(hvcPath))
            {
                throw new HotDocs.Server.HotDocsServerException("You do not have read access to the variable collection file (.hvc)");
            }

            // Instantiate a ComponentInfo object to hold the data to be returned
            ComponentInfo cmpInfo = new ComponentInfo();

            // Load the HVC variable collection
            using (HotDocs.Server.VariableCollection varCol = new HotDocs.Server.VariableCollection(hvcPath))
            {
                for (int i = 0; i < varCol.Count; i++)
                {
                    cmpInfo.AddVariable(new Contracts.VariableInfo {
                        Name = varCol.VarName(i), Type = AnsTypeToString(varCol.VarType(i))
                    });
                }
            }

            // Load the Dialogs (if requested)
            if (includeDialogs)
            {
                // Load the component collection from disk
                using (var cmpColl = new HotDocs.Server.ComponentCollection())
                {
                    cmpColl.Open(templateFilePath, hdsi.CMPOpenOptions.LoadAllCompLibs);
                    // Iterate through the component collection and add dialogs to ComponentInfo
                    foreach (HotDocs.Server.Component cmp in cmpColl)
                    {
                        if (cmp.Type == hdsi.hdCmpType.hdDialog)
                        {
                            // Fetch dialog properties (AnswerSource, Repeat, variable list and mappingNames) from the component collection
                            object[]   variableNames = null;
                            object[]   mappingNames  = null;
                            DialogInfo dlgInfo       = new DialogInfo();
                            dlgInfo.Name = cmp.Name;

                            using (HotDocs.Server.ComponentProperties properties = cmp.Properties)
                            {
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["Variables"])
                                {
                                    variableNames = (object[])p.Value;
                                };
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["IsRepeated"])
                                    using (HotDocs.Server.ComponentProperty p2 = (HotDocs.Server.ComponentProperty)properties["IsSpread"])
                                    {
                                        dlgInfo.Repeat = (bool)p.Value || (bool)p2.Value;
                                    };
                                using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["AnswerSource"])
                                {
                                    dlgInfo.AnswerSource = ((p != null) && (!String.IsNullOrWhiteSpace((string)p.Value))) ? (string)p.Value : null;
                                };
                                if (dlgInfo.AnswerSource != null)
                                {
                                    using (HotDocs.Server.ComponentProperty p = (HotDocs.Server.ComponentProperty)properties["MappingNames"])
                                    {
                                        mappingNames = (object[])p.Value;
                                    };
                                }
                            }

                            // Add the mapping information to the dialog
                            // Note that variableNames.Length is always equal to mappingNames.Length if mappingNames.Length is not null.
                            for (int i = 0; i < variableNames.Length; i++)
                            {
                                string variableName = variableNames[i].ToString();
                                if (cmpInfo.IsDefinedVariable(variableName))
                                {
                                    //The i < mappingNames.Length test here is strictly defensive.
                                    string mappingName = (mappingNames != null && i < mappingNames.Length) ? mappingNames[i].ToString() : null;

                                    dlgInfo.Items.Add(new DialogItemInfo
                                    {
                                        Name    = variableName,
                                        Mapping = String.IsNullOrWhiteSpace(mappingName) ? null : mappingName
                                    });
                                }
                            }

                            // Adds the dialog to ComponentInfo object IF it contains any variables that were in the HVC
                            if (dlgInfo.Items.Count > 0)
                            {
                                cmpInfo.AddDialog(dlgInfo);
                            }
                        }
                    }
                }
            }
            return(cmpInfo);
        }