/// <summary>
        /// Serializes the <see cref="IOpenApiSerializable"/> to Open API document using the given specification version and writer.
        /// </summary>
        /// <typeparam name="T">the <see cref="IOpenApiSerializable"/></typeparam>
        /// <param name="element">The Open API element.</param>
        /// <param name="writer">The output writer.</param>
        /// <param name="specVersion">Version of the specification the output should conform to</param>
        public static void Serialize <T>(this T element, IOpenApiWriter writer, OpenApiSpecVersion specVersion)
            where T : IOpenApiSerializable
        {
            if (element == null)
            {
                throw Error.ArgumentNull(nameof(element));
            }

            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            switch (specVersion)
            {
            case OpenApiSpecVersion.OpenApi3_0:
                element.SerializeAsV3(writer);
                break;

            case OpenApiSpecVersion.OpenApi2_0:
                element.SerializeAsV2(writer);
                break;

            default:
                throw new OpenApiException(string.Format(SRResource.OpenApiSpecVersionNotSupported, specVersion));
            }

            writer.Flush();
        }
        /// <summary>
        /// Write Open API document to given stream using given writer factory
        /// </summary>
        /// <param name="stream">The stream to write.</param>
        /// <param name="writerFactory">The writer factory.</param>
        public virtual void Write(Stream stream, Func <Stream, IOpenApiWriter> writerFactory)
        {
            if (stream == null)
            {
                throw Error.ArgumentNull("stream");
            }

            if (writerFactory == null)
            {
                throw Error.ArgumentNull("writerFactory");
            }

            IOpenApiWriter writer = writerFactory(stream);

            this.Write(writer);
            writer.Flush();
        }
        /// <summary>
        /// Write Open API document to the given writer.
        /// </summary>
        /// <param name="writer">The writer.</param>
        public virtual void Write(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull("writer");
            }

            // { for json, empty for YAML
            writer.WriteStartObject();

            // openapi:3.0.0
            writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocOpenApi, OpenApi.ToString());

            // info
            writer.WriteRequiredObject(OpenApiConstants.OpenApiDocInfo, Info);

            // servers
            writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocServers, Servers);

            // paths
            writer.WriteRequiredObject(OpenApiConstants.OpenApiDocPaths, Paths);

            // components
            writer.WriteOptionalObject(OpenApiConstants.OpenApiDocComponents, Components);

            // security
            writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocSecurity, Security);

            // tags
            writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocTags, Tags);

            // external docs
            writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExternalDocs, ExternalDoc);

            // specification extensions
            writer.WriteDictionary(Extensions);

            // } for json, empty for YAML
            writer.WriteEndObject();

            // flush
            writer.Flush();
        }