private static void ReadTermStore(
            string templateName,
            Guid managedItemID,
            XmlReader reader,
            ManagedItemStore managedItemStore,
            Dictionary<string /* Term Name */, Term> templateTerms,
            List<string> basicTermsToProcess)
        {
            string termName = string.Empty;
            bool attachmentsProcessed = false;

            using (reader)
            {
                reader.MoveToContent(); //Positioned at 'Terms' element.
                reader.Read();          //Positioned at first term or end element if no terms.
                while (reader.NodeType != XmlNodeType.EndElement)
                {
                    termName = Term.GetTermName(reader);
                    if (basicTermsToProcess.Contains(termName))
                    {
                        //Note - we use the current template definition as a filter for the reported terms.
                        if (templateTerms.ContainsKey(termName))
                        {
                            TermStore termStore = null;
                            switch (reader.Name)
                            {
                                case XMLNames._E_Text:
                                    termStore = TextTerm.CreateStore(termName, reader.ReadSubtree());
                                    break;

                                case XMLNames._E_Date:
                                    termStore = Term.CreateStore(termName, reader.ReadSubtree(), TermType.Date);
                                    break;

                                case XMLNames._E_MSO:
                                    termStore = MSOTerm.CreateStore(termName, reader.ReadSubtree());
                                    break;

                                case XMLNames._E_Renewal:
                                    termStore = RenewalTerm.CreateStore(termName, reader.ReadSubtree());
                                    break;

                                case XMLNames._E_Facility:
                                    termStore = FacilityTerm.CreateStore(termName, reader.ReadSubtree());
                                    break;

                                case XMLNames._E_PickList:
                                    termStore = PickListTerm.CreateStore(termName, reader.ReadSubtree());
                                    break;

                                case XMLNames._E_External:
                                    termStore = ExternalTerm.CreateStore(termName, templateTerms[termName] as ExternalTerm, managedItemID);
                                    break;

                                case XMLNames._E_Link:
                                    using (reader.ReadSubtree()) { }
                                    break;

                                //This will not be processed by older ManagedItems.
                                case XMLNames._E_PlaceHolderAttachments:
                                    attachmentsProcessed = true;
                                    termStore = Attachment.CreateStore(termName, managedItemID);
                                    break;

                                default:
                                    throw new Exception(string.Format("In ReadTermStore: unable to identify term type '{0}'", reader.Name));
                            }
                            if (termStore != null)
                                managedItemStore.AddTerm(termStore);
                        }
                        else
                        {
                            //Not found in the current template.
                            using (reader.ReadSubtree()) { }
                        }

                        basicTermsToProcess.Remove(termName);
                        if (basicTermsToProcess.Count == 0)
                        {
                            //All of the DataStoreDefinition terms have been processed, so quit early.
                            break;
                        }
                    }
                    else
                    {
                        //Not found in the DataStoreDefinition.
                        using (reader.ReadSubtree()) { }
                    }

                    reader.Read();      //Position the reader just past the term node.
                }

            }
            termName = XMLNames._A_Attachments;
            if (!attachmentsProcessed && basicTermsToProcess.Contains(termName))
            {
                TermStore termStore = Attachment.CreateStore(termName, managedItemID);
                if (termStore != null)
                    managedItemStore.AddTerm(termStore);
            }
        }
        private static void ReadComplexListStore(
            XmlReader reader,
            ManagedItemStore managedItemStore,
            Dictionary<string /* Term Name */, Term> templateTerms,
            List<string> complexListTermsToProcess)
        {
            string termName = string.Empty;

            using (reader)
            {
                reader.MoveToContent(); //Positioned at 'ComplexLists' element.
                reader.Read();          //Positioned at first ComplexList term or end element if no terms.
                while (reader.NodeType != XmlNodeType.EndElement)
                {
                    termName = Term.GetTermName(reader);
                    if (complexListTermsToProcess.Contains(termName))
                    {
                        //Note - we use the current template definition as a filter for the reported terms.
                        if (templateTerms.ContainsKey(termName))
                        {
                            List<string> templateFieldNames = new List<string>();
                            ComplexList complexList = templateTerms[termName] as ComplexList;
                            foreach (ComplexListField complexListField in complexList.Fields)
                            {
                                templateFieldNames.Add(complexListField.Name);
                            }
                            TermStore termStore = ComplexList.CreateStore(termName, reader.ReadSubtree(), templateFieldNames);
                            managedItemStore.AddTerm(termStore);
                        }
                        else
                        {
                            //Not found in the current template.
                            using (reader.ReadSubtree()) { }
                        }

                        complexListTermsToProcess.Remove(termName);
                        if (complexListTermsToProcess.Count == 0)
                        {
                            //All of the DataStoreDefinition terms have been processed, so quit early.
                            break;
                        }
                    }
                    else
                    {
                        //Not found in the DataStoreDefinition.
                        using (reader.ReadSubtree()) { }
                    }

                    reader.Read();      //Position the reader just past the term node.
                }
            }
        }
        public static ManagedItemStore CreateStore(
            ILog log, 
            Template template, 
            string managedItem, 
            Guid managedItemID, 
            string managedItemNumber, 
            string status, 
            string state, 
            Dictionary<string /* Term Name */, Term> templateTerms,
            List<string> basicTermsToProcess,
            List<string> complexListTermsToProcess)
        {
            ManagedItemStore managedItemStore = new ManagedItemStore(template.ID, template.Name, managedItemNumber, status, state);
            bool basicTermsProcessed = false;
            bool complexListsProcessed = false;
            bool workflowsProcessed = false;
            int basicTermsToProcessCount = basicTermsToProcess.Count;
            int complexListTermsToProcessCount = complexListTermsToProcess.Count;

            XmlTextReader txtReader = new XmlTextReader(new MemoryStream(Encoding.UTF8.GetBytes(managedItem)));
            XmlReaderSettings readerSettings = new XmlReaderSettings();
            readerSettings.IgnoreWhitespace = true;
            readerSettings.IgnoreComments = true;
            readerSettings.IgnoreProcessingInstructions = true;

            using (XmlReader reader = XmlReader.Create(txtReader, readerSettings))
            {
                reader.MoveToContent();     //Reader initialized and positioned at the 'TemplateDef' node.

                while (!(basicTermsProcessed && complexListsProcessed && workflowsProcessed))
                {
                    if (!reader.Read())     //At start element of a TemplateDef child node.
                    {
                        throw new Exception(string.Format("CreateStore call stopped unexpectedly on failed reader.Read call for ManagedItemNumber '{0}', ManagedItemID '{1}'", managedItemNumber, managedItemID.ToString()));
                    }

                    //Ensure completion before quitting...
                    if (reader.NodeType == XmlNodeType.EndElement && reader.Name == XMLNames._E_TemplateDef)
                    {
                        string error = string.Empty;
                        if (basicTermsToProcessCount > 0 && !basicTermsProcessed)
                            error += "Basic Terms were not processed.  ";
                        if (complexListTermsToProcessCount > 0 && !complexListsProcessed)
                            error += "Complex Lists were not processed.  ";
                        if (!workflowsProcessed)
                            error += "WorkFlows were not processed.  ";
                        if (!string.IsNullOrEmpty(error))
                            throw new Exception(string.Format("CreateStore call at end element before processing completed for ManagedItemNumber '{0}', ManagedItemID '{1}'.  {2}", managedItemNumber, managedItemID.ToString(), error));
                        break;
                    }

                    switch (reader.Name)
                    {
                        case XMLNames._E_Workflows:
                            Guid activeWorkflowID = new Guid(reader.GetAttribute(XMLNames._A_ActiveWorkflowID));
                            //NOTE - The search for active workflow may fail if the template information does not match the manageditem's information.
                            Workflow activeWorkflow = template.FindWorkflow(activeWorkflowID);
                            if (activeWorkflow != null)
                                managedItemStore.ActiveWorkflow = activeWorkflow.Name;
                            else
                                managedItemStore.ActiveWorkflow = string.Empty;
                            using (reader.ReadSubtree()) { }
                            workflowsProcessed = true;
                            break;

                        case XMLNames._E_Terms:
                            if (basicTermsToProcess.Count > 0)
                            {
                                ReadTermStore(
                                    template.Name,
                                    managedItemID,
                                    reader.ReadSubtree(),
                                    managedItemStore,
                                    templateTerms,
                                    basicTermsToProcess);
                            }
                            else
                            {
                                using (reader.ReadSubtree()) { }
                            }
                            basicTermsProcessed = true;
                            break;

                        case XMLNames._E_ComplexLists:
                            if (complexListTermsToProcess.Count > 0)
                            {
                                ReadComplexListStore(
                                    reader.ReadSubtree(),
                                    managedItemStore,
                                    templateTerms,
                                    complexListTermsToProcess);
                            }
                            else
                            {
                                using (reader.ReadSubtree()) { }
                            }
                            complexListsProcessed = true;
                            break;

                        case XMLNames._E_Events:
                        case XMLNames._E_Document:
                        case XMLNames._E_Comments:
                        case XMLNames._E_TermDependencies:
                        case XMLNames._E_DetailedDescriptions:
                        case XMLNames._E_TermGroups:
                        case XMLNames._E_DocumentPrinters:
                        default:
                            using (reader.ReadSubtree()) { }
                            break;
                    }

                }
            }

            return managedItemStore;
        }