/// <summary>
        /// Fills in the data table with data from a list of ThingBase.
        /// </summary>
        /// <param name="record"/>
        /// <param name="items"/>
        /// <param name="startIndex"/>
        /// <param name="count"/>
        public async Task GetDataAsync(HealthRecordAccessor record, IList <ThingBase> items, int startIndex, int count)
        {
            ThingDataTableView effectiveView =
                await this.ApplyEffectiveViewAsync(record.Connection).ConfigureAwait(false);

            IDictionary <Guid, ThingTypeDefinition> typeDefDict =
                await ItemTypeManager.GetHealthRecordItemTypeDefinitionAsync(query.TypeIds,
                                                                             record.Connection).ConfigureAwait(false);

            ThingTypeDefinition sttTypeDef =
                typeDefDict.Count == 1 ? typeDefDict[query.TypeIds[0]] : null;

            bool   firstRow      = true;
            string transformName =
                (effectiveView == ThingDataTableView.SingleTypeTable) ? "stt" : "mtt";

            for (int i = startIndex; i < items.Count && i < count; ++i)
            {
                ThingBase item = items[i];

                XPathNavigator itemTransformNav;
                IDictionary <string, XDocument> transformedXmlData = item.TransformedXmlData;
                if (transformedXmlData.ContainsKey(transformName))
                {
                    itemTransformNav =
                        transformedXmlData[transformName].CreateNavigator().SelectSingleNode(
                            "//data-xml/row");
                }
                else
                {
                    string transform = (sttTypeDef == null) ?
                                       ThingTypeDefinitionHelper.Create(typeDefDict[item.TypeId]).TransformItem(transformName, item) :
                                       ThingTypeDefinitionHelper.Create(sttTypeDef).TransformItem(transformName, item);

                    XmlReaderSettings settings = new XmlReaderSettings()
                    {
                        XmlResolver   = null,
                        DtdProcessing = DtdProcessing.Prohibit
                    };

                    using (StringReader stringReader = new StringReader(transform))
                    {
                        itemTransformNav = new XPathDocument(XmlReader.Create(stringReader, settings)).CreateNavigator();
                    }

                    if (!itemTransformNav.MoveToFirstChild())
                    {
                        continue;
                    }
                }

                if (firstRow)
                {
                    SetupColumns(itemTransformNav.Clone());
                    firstRow = false;
                }
                AddRow(itemTransformNav);
            }
        }
        public static ThingTypeDefinitionHelper Create(ThingTypeDefinition itemTypeDefinition)
        {
            ThingTypeDefinitionHelper helper = new ThingTypeDefinitionHelper(itemTypeDefinition);

            if (itemTypeDefinition.TypeNavigator == null)
            {
                throw new ArgumentException("TypeNavigator should be set on itemTypeDefinition");
            }

            itemTypeDefinition.TypeNavigator.MoveToRoot();
            helper.ParseXml(itemTypeDefinition.TypeNavigator);

            return(helper);
        }
        private async Task <ThingDataTableView> ApplyEffectiveViewAsync(
            IConnectionInternal connection)
        {
            ThingDataTableView effectiveView =
                ThingDataTableView.MultipleTypeTable;

            ThingTypeDefinition typeDefinition = null;

            if (Query.TypeIds.Count == 1 &&
                View != ThingDataTableView.MultipleTypeTable)
            {
                typeDefinition =
                    await ItemTypeManager.GetHealthRecordItemTypeDefinitionAsync(
                        this.Query.TypeIds[0],
                        connection).ConfigureAwait(false);

                ThingTypeDefinitionHelper thingTypeDefinitionHelper = null;

                if (typeDefinition != null)
                {
                    thingTypeDefinitionHelper = ThingTypeDefinitionHelper.Create(typeDefinition);
                }

                if (thingTypeDefinitionHelper != null &&
                    thingTypeDefinitionHelper.ColumnDefinitions.Count > 0)
                {
                    effectiveView
                        = ThingDataTableView.SingleTypeTable;
                    _singleTypeDefinition = typeDefinition;

                    foreach (
                        ItemTypeDataColumn column in
                        thingTypeDefinitionHelper.ColumnDefinitions)
                    {
                        _displayColumns.Add(
                            column.ColumnName, column.Clone());
                    }

                    this.Query.View.TransformsToApply.Clear();
                    this.Query.View.TransformsToApply.Add("stt");
                }
            }

            if (_singleTypeDefinition == null)
            {
                typeDefinition =
                    await ItemTypeManager.GetBaseHealthRecordItemTypeDefinitionAsync(
                        connection).ConfigureAwait(false);

                effectiveView
                    = ThingDataTableView.MultipleTypeTable;

                if (typeDefinition != null)
                {
                    var healthRecordItemTypeDefinitionHelper = ThingTypeDefinitionHelper.Create(typeDefinition);

                    foreach (
                        ItemTypeDataColumn column in
                        healthRecordItemTypeDefinitionHelper.ColumnDefinitions)
                    {
                        _displayColumns.Add(column.ColumnName, column.Clone());
                    }

                    this.Query.View.TransformsToApply.Clear();
                    this.Query.View.TransformsToApply.Add("mtt");
                }
            }

            return(effectiveView);
        }