/// <summary>
        /// This method takes a type and a set of facets and returns the best mapped equivalent type
        /// in Jet
        /// </summary>
        /// <param name="storeType">A TypeUsage encapsulating an EDM type and a set of facets</param>
        /// <returns>A TypeUsage encapsulating a store type and a set of facets</returns>
        public override TypeUsage GetStoreType(TypeUsage edmType)
        {
            if (edmType == null)
            {
                throw new ArgumentNullException("edmType");
            }

            System.Diagnostics.Debug.Assert(edmType.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType);

            PrimitiveType primitiveType = edmType.EdmType as PrimitiveType;

            if (primitiveType == null)
            {
                throw new ArgumentException(String.Format("The underlying provider does not support the type '{0}'.", edmType));
            }

            ReadOnlyMetadataCollection <Facet> facets = edmType.Facets;

            switch (primitiveType.PrimitiveTypeKind)
            {
            case PrimitiveTypeKind.Boolean:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bit"]));

            case PrimitiveTypeKind.Byte:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["tinyint"]));

            case PrimitiveTypeKind.Int16:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["smallint"]));

            case PrimitiveTypeKind.Int32:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int"]));

            case PrimitiveTypeKind.Int64:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int"]));

            case PrimitiveTypeKind.Guid:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["guid"]));

            case PrimitiveTypeKind.Double:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float"]));

            case PrimitiveTypeKind.Single:
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["real"]));

            case PrimitiveTypeKind.Decimal:     // decimal, numeric, smallmoney, money
            {
                byte precision;
                if (!edmType.TryGetPrecision(out precision))
                {
                    precision = 18;
                }

                byte scale;
                if (!edmType.TryGetScale(out scale))
                {
                    scale = 0;
                }

                return(TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["decimal"], precision, scale));
            }

            case PrimitiveTypeKind.Binary:     // binary, varbinary, image
            {
                bool isFixedLength = edmType.GetIsFixedLength();
                bool isMaxLength   = edmType.GetMaxLength() > BINARY_MAXSIZE;
                int  maxLength     = edmType.GetMaxLength();

                TypeUsage tu;
                if (isFixedLength)
                {
                    tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["binary"], true, maxLength);
                }
                else if (isMaxLength)
                {
                    tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["image"], false);
                    System.Diagnostics.Debug.Assert(tu.Facets["MaxLength"].Description.IsConstant, "varbinary(max) is not constant!");
                }
                else
                {
                    tu = TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["varbinary"], false, maxLength);
                }

                return(tu);
            }

            case PrimitiveTypeKind.String:
                // char, varchar, text
            {
                bool isUnicode     = edmType.GetIsUnicode();     // We do not handle unicode (everything's unicode in Jet)
                bool isFixedLength = edmType.GetIsFixedLength();
                bool isMaxLength   = edmType.GetMaxLength() > VARCHAR_MAXSIZE;
                int  maxLength     = edmType.GetMaxLength();

                TypeUsage tu;

                if (isFixedLength)
                {
                    tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["char"], false, true, maxLength);
                }
                else if (isMaxLength)
                {
                    tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["text"], false, false);
                }
                else
                {
                    tu = TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], false, false, maxLength);
                }

                return(tu);
            }

            case PrimitiveTypeKind.DateTime:     // datetime
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["datetime"]));

            case PrimitiveTypeKind.Time:     // time
                return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["time"]));

            default:
                throw new NotSupportedException(String.Format("There is no store type corresponding to the EDM type '{0}' of primitive type '{1}'.", edmType, primitiveType.PrimitiveTypeKind));
            }
        }