//Generate the Terms collection (of Term) based on an xml document
        //Called by BasicTerms.Create, once from ITATSystem.LoadFromDatabase
 		public static List<Term> Create(XmlNode termsNode, ManagedItem managedItem, Template template)
		{
			List<Term> rtn = new List<Term>(termsNode.ChildNodes.Count);
            int order = 0;
			foreach (XmlNode termNode in termsNode)
			{
				Term t = null;
				switch (termNode.Name.ToString())
				{
					case XMLNames._E_Text:
                        t = new TextTerm(termNode, template, false);
						break;
					case XMLNames._E_Date:
                        t = new DateTerm(termNode, template, false);
						break;
					case XMLNames._E_MSO:
                        t = new MSOTerm(termNode, template, false);
						break;
					case XMLNames._E_Link:
                        t = new LinkTerm(termNode, template, false);
						break;
					case XMLNames._E_Facility:
                        t = new FacilityTerm(termNode, template, false);
						break;
					case XMLNames._E_Renewal:
                        t = new RenewalTerm(termNode, managedItem != null, template, false);
						break;
					case XMLNames._E_PickList:
                        t = new PickListTerm(termNode, template, false);
						break;
					case XMLNames._E_External:
                        t = new ExternalTerm(termNode, managedItem, template, false);
						break;
                    case XMLNames._E_PlaceHolderAttachments:
                        t = new PlaceHolderAttachments(termNode, template, false);
                        break;
                    case XMLNames._E_PlaceHolderComments:
                        t = new PlaceHolderComments(termNode, template, false);
                        break;
                    default:
						throw new XmlException(string.Format("Tried to create undefined term type {0}", termNode.Name.ToString()));
				}
                t.Order = order++;
                rtn.Add(t);
			}
            //If this is not a load of the ITATSystem terms, then ensure that the collection includes the Attachments and Comments terms.
            if (template != null)
            {
                List<Term> placeholderTerms = FindTermsOfType(rtn, (TermType.PlaceHolderAttachments | TermType.PlaceHolderComments));
                if (placeholderTerms == null || (placeholderTerms != null && placeholderTerms.Count == 0))
                {
                    //If this is the first time these are being added, then this should be under Basic Security.
                    Term t = new PlaceHolderAttachments(false, template, false);
                    t.TermGroupID = template.BasicSecurityTermGroupID;
                    t.Order = order++;
                    rtn.Add(t);

                    t = new PlaceHolderComments(false, template, false);
                    t.TermGroupID = template.BasicSecurityTermGroupID;
                    t.Order = order++;
                    rtn.Add(t);
                }
                else if (placeholderTerms.Count != 2)
                {
                    throw new Exception(string.Format("Encountered a PlaceHolder term count of {0:D} when 2 were expected", placeholderTerms.Count));
                }
            }
			return rtn;
		}
        public static Guid AddTemplate(Guid ITATSystemID, string name, string description, bool generatesDocument, bool generateUserDocuments, short status, bool hasAttachments, bool allowComments, bool useDetailedDescription, List<string> validation)
        {
            Guid templateGuid = Guid.Empty;

            ITATSystem itatSystem = ITATSystem.Get(ITATSystemID, validation);
            if (validation != null)
                if (validation.Count > 0)
                    return templateGuid;

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml("<?xml version='1.0' encoding='UTF-8' ?><TemplateDef />");
            XmlElement elementTemplateDef = xmlDoc.DocumentElement;

            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTemplateDef, XMLNames._A_Description, description);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementTemplateDef, XMLNames._A_CanGenerateDocument, generatesDocument);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementTemplateDef, XMLNames._A_CanGenerateUserDocuments, generateUserDocuments);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementTemplateDef, XMLNames._A_Attachments, hasAttachments);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementTemplateDef, XMLNames._A_AllowComments, allowComments);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementTemplateDef, XMLNames._A_UseDetailedDescription, useDetailedDescription);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTemplateDef, XMLNames._A_XMLVersion, CurrentTemplateXMLVersion());
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTemplateDef, XMLNames._A_Version, Guid.NewGuid().ToString());
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTemplateDef, XMLNames._A_SecurityModel, SecurityModel.Basic.ToString());
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTemplateDef, XMLNames._A_RetroModel, Retro.RetroModel.Off.ToString());

            XmlElement elementEvents = xmlDoc.CreateElement(XMLNames._E_Events);
            elementTemplateDef.AppendChild(elementEvents);

            //Add the new TermGroups collection
            XmlElement elementTermGroups = xmlDoc.CreateElement(XMLNames._E_TermGroups);
            XmlElement elementTermGroup = xmlDoc.CreateElement(XMLNames._E_TermGroup);

            Guid basicTermGroupID = Guid.NewGuid();
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTermGroup, XMLNames._A_ID, basicTermGroupID.ToString());
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTermGroup, XMLNames._A_Name, TermGroup._TERM_GROUP_BASIC_NAME);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTermGroup, XMLNames._A_Description, "");
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementTermGroup, XMLNames._A_Type, TermGroup.TermGroupType.BasicSecurity.ToString());
            elementTermGroups.AppendChild(elementTermGroup);
            elementTemplateDef.AppendChild(elementTermGroups);

            XmlElement elementWorkFlows = xmlDoc.CreateElement(XMLNames._E_Workflows);
            XmlElement elementWorkFlow = xmlDoc.CreateElement(XMLNames._E_Workflow);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementWorkFlow, XMLNames._A_Name, "New Workflow");
            string sActiveWorkflowID = Guid.NewGuid().ToString();
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementWorkFlow, XMLNames._A_ID, sActiveWorkflowID);

            XmlElement elementStates = xmlDoc.CreateElement(XMLNames._E_States);
            XmlElement elementState = xmlDoc.CreateElement(XMLNames._E_State);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementState, XMLNames._A_Name, "BaseState");
            //TODO - Should we choose from the list of system Statuses here?
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementState, XMLNames._A_Status, "BaseState Status");
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementState, XMLNames._A_IsDraft, true);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementState, XMLNames._A_IsBase, true);
            Utility.XMLHelper.AddAttributeBool(xmlDoc, elementState, XMLNames._A_IsExit, true);

            //Add the StateTermGroup collection
            XmlElement elementStateTermGroups = xmlDoc.CreateElement(XMLNames._E_StateTermGroups);
            XmlElement elementStateTermGroup = xmlDoc.CreateElement(XMLNames._E_StateTermGroup);

            Utility.XMLHelper.AddAttributeString(xmlDoc, elementStateTermGroup, XMLNames._A_TermGroupID, basicTermGroupID.ToString());
            elementStateTermGroup.AppendChild(xmlDoc.CreateElement(XMLNames._E_Editors));
            elementStateTermGroup.AppendChild(xmlDoc.CreateElement(XMLNames._E_Viewers));
            elementStateTermGroup.AppendChild(xmlDoc.CreateElement(XMLNames._E_AttachmentRemovers));
            elementStateTermGroup.AppendChild(xmlDoc.CreateElement(XMLNames._E_ScannedAttachmentRemovers));

            elementStateTermGroups.AppendChild(elementStateTermGroup);
            elementState.AppendChild(elementStateTermGroups);

            elementStates.AppendChild(elementState);
            elementWorkFlow.AppendChild(elementStates);
            elementWorkFlows.AppendChild(elementWorkFlow);

            Utility.XMLHelper.AddAttributeString(xmlDoc, elementWorkFlows, XMLNames._A_ActiveWorkflowID, sActiveWorkflowID);
            elementTemplateDef.AppendChild(elementWorkFlows);

            XmlElement elementTerms = xmlDoc.CreateElement(XMLNames._E_Terms);
            elementTemplateDef.AppendChild(elementTerms);

            XmlElement elementDocuments = xmlDoc.CreateElement(XMLNames._E_Documents);
            elementTemplateDef.AppendChild(elementDocuments);


            XmlElement elementDocument = xmlDoc.CreateElement(XMLNames._E_Document);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementDocument, XMLNames._A_ID, Guid.NewGuid().ToString());
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementDocument, XMLNames._A_Name, XMLNames._E_Document);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementDocument, XMLNames._A_Document_DefaultDocument, bool.TrueString);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementDocument, XMLNames._A_Document_WorkflowEnabled, bool.TrueString);

            XmlElement elementHeader = xmlDoc.CreateElement(XMLNames._E_Header);
            elementDocument.AppendChild(elementHeader);
            XmlElement elementBody = xmlDoc.CreateElement(XMLNames._E_Body);
            Utility.XMLHelper.AddAttributeString(xmlDoc, elementBody, XMLNames._A_Name, XMLNames._E_Document);
            elementDocument.AppendChild(elementBody);
            XmlElement elementFooter = xmlDoc.CreateElement(XMLNames._E_Footer);
            elementDocument.AppendChild(elementFooter);
            elementDocuments.AppendChild(elementDocument);


            XmlElement elementComments = xmlDoc.CreateElement(XMLNames._E_Comments);
            elementTemplateDef.AppendChild(elementComments);

            bool bValidate = false;
            foreach (Term term in itatSystem.Terms)
                term.TermGroupID = basicTermGroupID;

            Term newTerm = new PlaceHolderAttachments(false, null, false);
            newTerm.TermGroupID = basicTermGroupID;
            itatSystem.Terms.Add(newTerm);

            newTerm = new PlaceHolderComments(false, null, false);
            newTerm.TermGroupID = basicTermGroupID;
            itatSystem.Terms.Add(newTerm);

            Business.BasicTerms.SaveTerms(itatSystem.Terms, xmlDoc, elementTerms, bValidate);

            using (TransactionScope transScope = new TransactionScope(Data.Common.TransactionScopeOption))
            {
                templateGuid = Data.Template.InsertTemplate(ITATSystemID, name);
                Data.Template.UpdateTemplateSummary(templateGuid, name, status, null);
                Data.Template.UpdateDraftTemplateDef(templateGuid, xmlDoc.OuterXml);
                Data.Template.InsertTemplateAudit(templateGuid, Business.SecurityHelper.GetLoggedOnPersonId(), (short)status, xmlDoc.OuterXml, (int)Retro.AuditType.Created);
                transScope.Complete();
            }

            return templateGuid;
        }