/// <summary>
        /// Constructs blueprint of the given <paramref name="type"/>.
        /// </summary>
        /// <param name="type">Type for which mapper being generated.</param>
        /// <param name="serializedName">Serialized name to be used.</param>
        /// <param name="parameter">Parameter of the composite type to construct the parameter constraints.</param>
        /// <param name="expandComposite">Expand composite type if <c>true</c> otherwise specify class_name in the mapper.</param>
        /// <returns>Mapper for the <paramref name="type"/> as string.</returns>
        /// <exception cref="ArgumentNullException">Thrown when a required parameter is null.</exception>
        /// <example>
        /// One of the example of the mapper is
        /// {
        ///   required: false,
        ///   serialized_name: 'Fish',
        ///   type: {
        ///     name: 'Composite',
        ///     polymorphic_discriminator: 'fishtype',
        ///     uber_parent: 'Fish',
        ///     class_name: 'Fish',
        ///     model_properties: {
        ///       species: {
        ///         required: false,
        ///         serialized_name: 'species',
        ///         type: {
        ///           name: 'String'
        ///         }
        ///       },
        ///       length: {
        ///         required: true,
        ///         serialized_name: 'length',
        ///         type: {
        ///           name: 'Double'
        ///         }
        ///       },
        ///       siblings: {
        ///         required: false,
        ///         serialized_name: 'siblings',
        ///         type: {
        ///           name: 'Sequence',
        ///           element: {
        ///               required: false,
        ///               serialized_name: 'FishElementType',
        ///               type: {
        ///                 name: 'Composite',
        ///                 polymorphic_discriminator: 'fishtype',
        ///                 uber_parent: 'Fish',
        ///                 class_name: 'Fish'
        ///               }
        ///           }
        ///         }
        ///       }
        ///     }
        ///   }
        /// }
        /// </example>
        public static string ConstructMapper(this IType type, string serializedName, IParameter parameter, bool expandComposite)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var builder = new IndentedStringBuilder("  ");

            CompositeType  composite  = type as CompositeType;
            SequenceType   sequence   = type as SequenceType;
            DictionaryType dictionary = type as DictionaryType;
            PrimaryType    primary    = type as PrimaryType;
            EnumType       enumType   = type as EnumType;

            if (enumType != null && enumType.ModelAsString)
            {
                primary = new PrimaryType(KnownPrimaryType.String);
            }
            builder.AppendLine("").Indent();

            builder.AppendLine(type.AddMetaData(serializedName, parameter));

            if (primary != null)
            {
                builder.AppendLine(primary.ContructMapperForPrimaryType());
            }
            else if (enumType != null && enumType.Name != null)
            {
                builder.AppendLine(enumType.ContructMapperForEnumType());
            }
            else if (sequence != null)
            {
                builder.AppendLine(sequence.ContructMapperForSequenceType());
            }
            else if (dictionary != null)
            {
                builder.AppendLine(dictionary.ContructMapperForDictionaryType());
            }
            else if (composite != null)
            {
                builder.AppendLine(composite.ContructMapperForCompositeType(expandComposite));
            }
            else
            {
                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "{0} is not a supported Type.", type));
            }
            return(builder.ToString());
        }