private static void CreateMetadata(IEnumerable <ColumnMetadataInfo> infos, Bindings bindings, out MetadataDispatcher md)
        {
            Contracts.AssertValue(bindings);

            md = new MetadataDispatcher(bindings.InfoCount);
            foreach (var colInfo in infos)
            {
                if (colInfo == null)
                {
                    continue;
                }
                int iinfo;
                var found = bindings.TryGetInfoIndex(colInfo.Name, out iinfo);
                Contracts.Assert(found);
                using (var bldr = md.BuildMetadata(iinfo))
                {
                    foreach (var info in colInfo.Infos())
                    {
                        Action <MetadataDispatcher.Builder, string, MetadataInfo <int> > del = AddGetter;
                        var meth =
                            del.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(info.Value.Type.RawType);
                        meth.Invoke(null, new object[] { bldr, info.Key, info.Value });
                    }
                }
            }
            md.Seal();
        }
        // Computes the column type and whether multiple indicator vectors need to be concatenated.
        // Also populates the metadata.
        private static void ComputeType(KeyToVectorTransform trans, ISchema input, int iinfo, ColInfo info, bool bag,
                                        MetadataDispatcher md, out VectorType type, out bool concat)
        {
            Contracts.AssertValue(trans);
            Contracts.AssertValue(input);
            Contracts.AssertValue(info);
            Contracts.Assert(info.TypeSrc.ItemType.IsKey);
            Contracts.AssertValue(md);

            int size = info.TypeSrc.ItemType.KeyCount;

            Contracts.Assert(size > 0);

            // See if the source has key names.
            var typeNames = input.GetMetadataTypeOrNull(MetadataUtils.Kinds.KeyValues, info.Source);

            if (typeNames == null || !typeNames.IsKnownSizeVector || !typeNames.ItemType.IsText ||
                typeNames.VectorSize != size)
            {
                typeNames = null;
            }

            // Don't pass through any source column metadata.
            using (var bldr = md.BuildMetadata(iinfo))
            {
                if (bag || info.TypeSrc.ValueCount == 1)
                {
                    // Output is a single vector computed as the sum of the output indicator vectors.
                    concat = false;
                    type   = new VectorType(NumberType.Float, size);
                    if (typeNames != null)
                    {
                        bldr.AddGetter <VBuffer <DvText> >(MetadataUtils.Kinds.SlotNames, typeNames, trans.GetKeyNames);
                    }
                }
                else
                {
                    // Output is the concatenation of the multiple output indicator vectors.
                    concat = true;
                    type   = new VectorType(NumberType.Float, info.TypeSrc.ValueCount, size);
                    if (typeNames != null && type.VectorSize > 0)
                    {
                        bldr.AddGetter <VBuffer <DvText> >(MetadataUtils.Kinds.SlotNames,
                                                           new VectorType(TextType.Instance, type), trans.GetSlotNames);
                    }
                }

                if (!bag && info.TypeSrc.ValueCount > 0)
                {
                    bldr.AddGetter <VBuffer <DvInt4> >(MetadataUtils.Kinds.CategoricalSlotRanges,
                                                       MetadataUtils.GetCategoricalType(info.TypeSrc.ValueCount), trans.GetCategoricalSlotRanges);
                }

                if (!bag || info.TypeSrc.ValueCount == 1)
                {
                    bldr.AddPrimitive(MetadataUtils.Kinds.IsNormalized, BoolType.Instance, DvBool.True);
                }
            }
        }
        /// <summary>
        /// Computes the column type and whether multiple indicator vectors need to be concatenated.
        /// Also populates the metadata.
        /// </summary>
        private static void ComputeType(KeyToBinaryVectorTransform trans, ISchema input, int iinfo,
                                        ColInfo info, MetadataDispatcher md, out VectorType type, out bool concat, out int bitsPerColumn)
        {
            Contracts.AssertValue(trans);
            Contracts.AssertValue(input);
            Contracts.AssertValue(info);
            Contracts.Assert(info.TypeSrc.ItemType.IsKey);
            Contracts.Assert(info.TypeSrc.ItemType.KeyCount > 0);

            //Add an additional bit for all 1s to represent missing values.
            bitsPerColumn = Utils.IbitHigh((uint)info.TypeSrc.ItemType.KeyCount) + 2;

            Contracts.Assert(bitsPerColumn > 0);

            // See if the source has key names.
            var typeNames = input.GetMetadataTypeOrNull(MetadataUtils.Kinds.KeyValues, info.Source);

            if (typeNames == null || !typeNames.IsKnownSizeVector || !typeNames.ItemType.IsText ||
                typeNames.VectorSize != info.TypeSrc.ItemType.KeyCount)
            {
                typeNames = null;
            }

            // Don't pass through any source column metadata.
            using (var bldr = md.BuildMetadata(iinfo))
            {
                if (info.TypeSrc.ValueCount == 1)
                {
                    // Output is a single vector computed as the sum of the output indicator vectors.
                    concat = false;
                    type   = new VectorType(NumberType.Float, bitsPerColumn);
                    if (typeNames != null)
                    {
                        bldr.AddGetter <VBuffer <DvText> >(MetadataUtils.Kinds.SlotNames,
                                                           new VectorType(TextType.Instance, type), trans.GetKeyNames);
                    }

                    bldr.AddPrimitive(MetadataUtils.Kinds.IsNormalized, BoolType.Instance, DvBool.True);
                }
                else
                {
                    // Output is the concatenation of the multiple output indicator vectors.
                    concat = true;
                    type   = new VectorType(NumberType.Float, info.TypeSrc.ValueCount, bitsPerColumn);
                    if (typeNames != null && type.VectorSize > 0)
                    {
                        bldr.AddGetter <VBuffer <DvText> >(MetadataUtils.Kinds.SlotNames,
                                                           new VectorType(TextType.Instance, type), trans.GetSlotNames);
                    }
                }
            }
        }