Repository: eclipse/microprofile-open-api
Pull request #344 (2019-03-27 19:46:23)

Merge 2.0 branch into master
We have decided to make `2.0` our next release, to go into the upcoming MP 3.0 umbrella release which allows for breaking changes.


Patch:
diff --git a/api/pom.xml b/api/pom.xml
index d5ab459..1f86311 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -20,7 +20,7 @@
         <!-- This is just for now and will not work if the API has a separate release cycle than the rest. -->
         <groupId>org.eclipse.microprofile.openapi</groupId>
         <artifactId>microprofile-openapi-parent</artifactId>
-        <version>1.2-SNAPSHOT</version>
+        <version>2.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>microprofile-openapi-api</artifactId>
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/annotations/responses/APIResponse.java b/api/src/main/java/org/eclipse/microprofile/openapi/annotations/responses/APIResponse.java
index b962161..c80aec7 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/annotations/responses/APIResponse.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/annotations/responses/APIResponse.java
@@ -39,7 +39,7 @@ import org.eclipse.microprofile.openapi.annotations.media.Content;
  * 
  * <pre>
  * &#64;ApiResponse(responseCode="200", description="Calculate load size", content=
- *     { &#64;Content(mediaType="application/json", Schema=&#64;Schema(type="integer")) } )
+ *     [ &#64;Content(mediaType="application/json", Schema=&#64;Schema(type="integer")) ] )
  * &#64;GET
  * public getLuggageWeight(Flight id) {
  *     return getBagWeight(id) + getCargoWeight(id);
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java
index 5928c1d..fb5c384 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/Components.java
@@ -54,7 +54,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the schemas property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable schemas for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable schemas for this OpenAPI document
      **/
     Map<String, Schema> getSchemas();
 
@@ -95,7 +95,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the responses property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable responses from API operations for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable responses from API operations for this OpenAPI document
      **/
     Map<String, APIResponse> getResponses();
 
@@ -136,7 +136,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the parameters property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable parameters of API operations for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable parameters of API operations for this OpenAPI document
      **/
     Map<String, Parameter> getParameters();
 
@@ -177,7 +177,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the examples property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable examples for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable examples for this OpenAPI document
      **/
     Map<String, Example> getExamples();
 
@@ -218,7 +218,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the requestBodies property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable request bodies for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable request bodies for this OpenAPI document
      **/
     Map<String, RequestBody> getRequestBodies();
 
@@ -259,7 +259,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the headers property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable headers for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable headers for this OpenAPI document
      **/
     Map<String, Header> getHeaders();
 
@@ -300,7 +300,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the securitySchemes property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable security schemes for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable security schemes for this OpenAPI document
      **/
     Map<String, SecurityScheme> getSecuritySchemes();
 
@@ -341,7 +341,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the links property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable links for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable links for this OpenAPI document
      **/
     Map<String, Link> getLinks();
 
@@ -382,7 +382,7 @@ public interface Components extends Constructible, Extensible<Components> {
     /**
      * Returns the callbacks property from a Components instance.
      *
-     * @return a Map containing the keys and the reusable callbacks for this OpenAPI document
+     * @return a copy Map (potentially immutable) containing the keys and the reusable callbacks for this OpenAPI document
      **/
     Map<String, Callback> getCallbacks();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/OpenAPI.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/OpenAPI.java
index 433403f..dad3a63 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/OpenAPI.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/OpenAPI.java
@@ -111,7 +111,7 @@ public interface OpenAPI extends Constructible, Extensible<OpenAPI> {
     /**
      * Returns the Servers defined in the API
      *
-     * @return Server objects which provide connectivity information to target servers
+     * @return a copy List (potentially immutable) of Server objects which provide connectivity information to target servers
      **/
     List<Server> getServers();
 
@@ -151,7 +151,7 @@ public interface OpenAPI extends Constructible, Extensible<OpenAPI> {
     /**
      * Returns the security property from an OpenAPI instance.
      *
-     * @return which security mechanisms can be used across the API
+     * @return a copy List (potentially immutable) containing the security mechanisms that can be used across the API
      **/
     List<SecurityRequirement> getSecurity();
 
@@ -191,7 +191,7 @@ public interface OpenAPI extends Constructible, Extensible<OpenAPI> {
     /**
      * Returns the tags property from an OpenAPI instance.
      *
-     * @return tags used by the specification
+     * @return a copy List (potentially immutable) of tags defined in this the specification
      **/
 
     List<Tag> getTags();
@@ -254,17 +254,6 @@ public interface OpenAPI extends Constructible, Extensible<OpenAPI> {
         return this;
     }
 
-    /**
-     * Adds the given path item to this OpenAPI instance's list of paths
-     * 
-     * @param name a path name in the format valid for a Paths object
-     * @param path the path item added to the list of paths
-     * @deprecated since 1.1, use @link {@link Paths#addPathItem(String, PathItem)} on {@link #getPaths()} instead
-     * @return the current OpenAPI object
-     */
-    @Deprecated
-    OpenAPI path(String name, PathItem path);
-
     /**
      * Returns the components property from an OpenAPI instance.
      *
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/Operation.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/Operation.java
index f48d023..805d0a2 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/Operation.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/Operation.java
@@ -41,7 +41,7 @@ public interface Operation extends Constructible, Extensible<Operation> {
     /**
      * Returns the tags property from an Operation instance.
      *
-     * @return a list of the operation's tags
+     * @return a copy List (potentially immutable) of the operation's tags
      **/
     List<String> getTags();
 
@@ -181,7 +181,7 @@ public interface Operation extends Constructible, Extensible<Operation> {
     /**
      * Returns the parameters property from an Operation instance.
      *
-     * @return a list of parameters that are applicable for this operation
+     * @return a copy List (potentially immutable) of parameters that are applicable for this operation
      **/
     List<Parameter> getParameters();
 
@@ -271,7 +271,7 @@ public interface Operation extends Constructible, Extensible<Operation> {
     /**
      * Returns the callbacks property from an Operation instance.
      *
-     * @return map of possible out-of-band callbacks related to the operation
+     * @return a copy Map (potentially immutable) of possible out-of-band callbacks related to the operation
      **/
     Map<String, Callback> getCallbacks();
 
@@ -338,7 +338,7 @@ public interface Operation extends Constructible, Extensible<Operation> {
     /**
      * Returns the security property from an Operation instance.
      *
-     * @return a list of which security mechanisms can be used for this operation
+     * @return a copy List (potentially immutable) of which security mechanisms can be used for this operation
      **/
     List<SecurityRequirement> getSecurity();
 
@@ -378,7 +378,7 @@ public interface Operation extends Constructible, Extensible<Operation> {
     /**
      * Returns the servers property from an Operation instance.
      *
-     * @return a list of servers to service this operation
+     * @return a copy List (potentially immutable) of servers to service this operation
      **/
     List<Server> getServers();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/PathItem.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/PathItem.java
index a5d5866..9df833f 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/PathItem.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/PathItem.java
@@ -19,7 +19,6 @@ package org.eclipse.microprofile.openapi.models;
 
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import org.eclipse.microprofile.openapi.models.parameters.Parameter;
 import org.eclipse.microprofile.openapi.models.servers.Server;
@@ -294,28 +293,6 @@ public interface PathItem extends Constructible, Extensible<PathItem>, Reference
         return this;
     }
 
-    /**
-     * Returns a list of all the operations for this path item.
-     * 
-     * @deprecated since 1.1, use @link {@link Map#values()} on {@link #getOperations()} instead
-     * @return a list of all the operations for this path item
-     **/
-    @Deprecated
-    default List<Operation> readOperations() {
-        return getOperations().values().stream().collect(Collectors.toList());
-    }
-
-    /**
-     * Returns a map with all the operations for this path where the keys are HttpMethods.
-     * 
-     * @deprecated since 1.1, use {@link #getOperations()} instead
-     * @return a map with all the operations for this path where the keys are HttpMethods
-     **/
-    @Deprecated
-    default Map<PathItem.HttpMethod, Operation> readOperationsMap() {
-        return getOperations();
-    }
-
     /**
      * Returns a map with all the operations for this path where the keys are {@link PathItem.HttpMethod} items
      * 
@@ -326,7 +303,7 @@ public interface PathItem extends Constructible, Extensible<PathItem>, Reference
     /**
      * Returns the servers property from a PathItem instance.
      *
-     * @return a list of all the servers defined in this path item
+     * @return a copy List (potentially immutable) of all the servers defined in this path item
      **/
     List<Server> getServers();
 
@@ -366,7 +343,7 @@ public interface PathItem extends Constructible, Extensible<PathItem>, Reference
     /**
      * Returns the parameters property from this PathItem instance.
      *
-     * @return a list of parameters that are applicable to all the operations described under this path
+     * @return a copy List (potentially immutable) of parameters that are applicable to all the operations described under this path
      **/
     List<Parameter> getParameters();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/Paths.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/Paths.java
index 11e0398..9d3c10c 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/Paths.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/Paths.java
@@ -29,7 +29,7 @@ import java.util.Map;
  * 
  * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject"> OpenAPI Specification Paths Object</a>
  */
-public interface Paths extends Constructible, Extensible<Paths>, Map<String, PathItem> {
+public interface Paths extends Constructible, Extensible<Paths> {
 
     /**
      * Adds the given path item to this Paths and return this instance of Paths
@@ -89,49 +89,4 @@ public interface Paths extends Constructible, Extensible<Paths>, Map<String, Pat
         return map.get(name);
     }
 
-    /**
-     * In the next version, {@link Paths} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getPathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem get(Object key);
-
-    /**
-     * In the next version, {@link Paths} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasPathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link Paths} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addPathItem(String, PathItem)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem put(String key, PathItem value);
-
-    /**
-     * In the next version, {@link Paths} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setPathItems(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends PathItem> m);
-
-    /**
-     * In the next version, {@link Paths} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removePathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem remove(Object key);
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/callbacks/Callback.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/callbacks/Callback.java
index b646525..9e05989 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/callbacks/Callback.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/callbacks/Callback.java
@@ -33,7 +33,7 @@ import org.eclipse.microprofile.openapi.models.Reference;
  * 
  * @see <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#callbackObject">OpenAPI Specification Callback Object</a>
  */
-public interface Callback extends Constructible, Extensible<Callback>, Reference<Callback>, Map<String, PathItem> {
+public interface Callback extends Constructible, Extensible<Callback>, Reference<Callback> {
 
     /**
      * Adds the given PathItem to this Callback's list of PathItems using the string as its key.
@@ -98,50 +98,4 @@ public interface Callback extends Constructible, Extensible<Callback>, Reference
         return map.get(name);
     }
 
-    /**
-     * In the next version, {@link Callback} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getPathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem get(Object key);
-
-    /**
-     * In the next version, {@link Callback} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasPathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link Callback} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addPathItem(String, PathItem)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem put(String key, PathItem value);
-
-    /**
-     * In the next version, {@link Callback} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setPathItems(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends PathItem> m);
-
-    /**
-     * In the next version, {@link Callback} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removePathItem(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    PathItem remove(Object key);
-
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/headers/Header.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/headers/Header.java
index 6a963d4..b189f16 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/headers/Header.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/headers/Header.java
@@ -232,7 +232,7 @@ public interface Header extends Constructible, Extensible<Header>, Reference<Hea
     /**
      * Returns the examples property from a Header instance.
      *
-     * @return examples of the header
+     * @return a copy Map (potentially immutable) of examples of the header
      **/
     Map<String, Example> getExamples();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/links/Link.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/links/Link.java
index ebef33b..0aa902a 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/links/Link.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/links/Link.java
@@ -146,7 +146,7 @@ public interface Link extends Constructible, Extensible<Link>, Reference<Link> {
      * Returns the parameters property from this instance of Link. The key is the parameter name and the value is a constant or a runtime expression
      * to be passed to the linked operation.
      *
-     * @return a map representing parameters to pass to this link's operation
+     * @return a copy Map (potentially immutable) representing parameters to pass to this link's operation
      **/
     Map<String, Object> getParameters();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Content.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Content.java
index ee5f1d4..f29e80d 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Content.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Content.java
@@ -27,7 +27,7 @@ import org.eclipse.microprofile.openapi.models.Constructible;
  * A map to assist describing the media types for an operation's parameter or response.
  * 
  */
-public interface Content extends Constructible, Map<String, MediaType> {
+public interface Content extends Constructible {
 
     /**
      * Adds the MediaType for this Content, where the key is the name of the MediaType and the value is the object that describes the content passed
@@ -89,49 +89,4 @@ public interface Content extends Constructible, Map<String, MediaType> {
         return map.get(name);
     }
 
-    /**
-     * In the next version, {@link Content} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getMediaType(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    MediaType get(Object key);
-
-    /**
-     * In the next version, {@link Content} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasMediaType(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link Content} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addMediaType(String, MediaType)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    MediaType put(String key, MediaType value);
-
-    /**
-     * In the next version, {@link Content} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setMediaTypes(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends MediaType> m);
-
-    /**
-     * In the next version, {@link Content} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removeMediaType(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    MediaType remove(Object key);
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Discriminator.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Discriminator.java
index 8fbabd5..bdfa4ec 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Discriminator.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Discriminator.java
@@ -89,7 +89,7 @@ public interface Discriminator extends Constructible {
     /**
      * Returns the mapping property from a Discriminator instance.
      *
-     * @return a map containing keys and schema names or references
+     * @return a copy Map (potentially immutable) containing keys and schema names or references
      **/
     Map<String, String> getMapping();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Encoding.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Encoding.java
index edf8749..bbc3fb1 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Encoding.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Encoding.java
@@ -97,7 +97,7 @@ public interface Encoding extends Constructible, Extensible<Encoding> {
      * <p>
      * This method returns the headers property from a Encoding instance.
      * </p>
-     * @return Map&lt;String, Header&gt; headers
+     * @return a copy Map (potentially immutable) containing headers
      **/
     Map<String, Header> getHeaders();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/MediaType.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/MediaType.java
index 7647e7e..4ad65ee 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/MediaType.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/MediaType.java
@@ -62,7 +62,7 @@ public interface MediaType extends Constructible, Extensible<MediaType> {
     /**
      * Returns the collection of examples from a MediaType instance.
      *
-     * @return examples of the media type
+     * @return a copy Map (potentially immutable) of examples of the media type
      **/
     Map<String, Example> getExamples();
 
@@ -134,7 +134,7 @@ public interface MediaType extends Constructible, Extensible<MediaType> {
     /**
      * Returns the encoding property from a MediaType instance.
      *
-     * @return a map between a property name and its encoding information
+     * @return  a copy Map (potentially immutable) between a property name and its encoding information
      **/
     Map<String, Encoding> getEncoding();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Schema.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Schema.java
index 48b42e2..af084db 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Schema.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/media/Schema.java
@@ -139,7 +139,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the enumerated list of values allowed for objects defined by this Schema.
      *
-     * @return the list of values allowed for objects defined by this Schema
+     * @return a copy List (potentially immutable) of values allowed for objects defined by this Schema
      */
     List<Object> getEnumeration();
 
@@ -512,7 +512,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the required property from this Schema instance.
      *
-     * @return the list of fields required in objects defined by this Schema
+     * @return a copy List (potentially immutable) of fields required in objects defined by this Schema
      **/
     List<String> getRequired();
 
@@ -604,7 +604,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the properties defined in this Schema.
      *
-     * @return a map which associates property names with the schemas that describe their contents
+     * @return a copy Map (potentially immutable) which associates property names with the schemas that describe their contents
      **/
     Map<String, Schema> getProperties();
 
@@ -643,32 +643,6 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
      */
     void removeProperty(String key);
 
-    /**
-     * Returns the value of the "additionalProperties" setting, which indicates whether 
-     * properties not otherwise defined are allowed.  This setting MUST either be a {@link Boolean}
-     * or {@link Schema}, they can not be set both at the same time.
-     * 
-     * <ul>
-     *   <li>If "additionalProperties" is true, then any additional properties are allowed.</li>
-     *
-     *   <li>If "additionalProperties" is false, then only properties covered by the "properties"
-     *   and "patternProperties" are allowed.</li>
-     *
-     *   <li>If "additionalProperties" is a Schema, then additional properties are allowed but
-     *   should conform to the Schema.</li>
-     * </ul>
-     * @deprecated since 1.1, use @link {@link #getAdditionalPropertiesSchema()} or {@link #getAdditionalPropertiesBoolean()} instead
-     * @return a Boolean or a schema
-     */
-    @Deprecated
-    default Object getAdditionalProperties() {
-        Schema s = getAdditionalPropertiesSchema();
-        if(s != null) {
-            return s;
-        }
-        return getAdditionalPropertiesBoolean();
-    }
-
     /**
      * Returns the value of the "additionalProperties" setting, which indicates whether 
      * properties not otherwise defined are allowed. This setting MUST either be a {@link Boolean}
@@ -699,20 +673,6 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
      */
     Boolean getAdditionalPropertiesBoolean();
 
-    /**
-     * Sets the Schema which defines additional properties not defined by "properties" or "patternProperties".
-     * See the javadoc for {@link Schema#getAdditionalPropertiesSchema()} for more details on this setting.  Note 
-     * that this version of the setter is mutually exclusive with the {@link Boolean} variants (see 
-     * {@link #setAdditionalPropertiesBoolean(Boolean)}).
-     *
-     * @deprecated since 1.1, use @link {@link #setAdditionalPropertiesSchema(Schema)} instead
-     * @param additionalProperties a Schema which defines additional properties
-     */
-    @Deprecated
-    default void setAdditionalProperties(Schema additionalProperties) {
-        setAdditionalPropertiesSchema(additionalProperties);
-    }
-
     /**
      * Sets the Schema which defines additional properties not defined by "properties" or "patternProperties".
      * See the javadoc for {@link Schema#getAdditionalPropertiesSchema()} for more details on this setting.  Note 
@@ -723,20 +683,6 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
      */
     void setAdditionalPropertiesSchema(Schema additionalProperties);
 
-    /**
-     * Sets the value of "additionalProperties" to either True or False.  See the javadoc for 
-     * {@link Schema#getAdditionalPropertiesBoolean()} for more details on this setting.  Note that
-     * this version of the setter is mutually exclusive with the {@link Schema} variants (see 
-     * {@link #setAdditionalPropertiesSchema(Schema)}).
-     *
-     * @deprecated since 1.1, use @link {@link #setAdditionalPropertiesBoolean(Boolean)} instead
-     * @param additionalProperties a Schema which defines additional properties
-     */
-    @Deprecated
-    default void setAdditionalProperties(Boolean additionalProperties) {
-        setAdditionalPropertiesBoolean(additionalProperties);
-    }
-
     /**
      * Sets the value of "additionalProperties" to either True or False.  See the javadoc for 
      * {@link Schema#getAdditionalPropertiesBoolean()} for more details on this setting.  Note that
@@ -747,21 +693,6 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
      */
     void setAdditionalPropertiesBoolean(Boolean additionalProperties);
 
-    /**
-     * Sets the Schema which defines additional properties not defined by "properties" or "patternProperties".
-     * See the javadoc for {@link Schema#getAdditionalPropertiesSchema()} for more details on this setting.  Note 
-     * that this version of the setter is mutually exclusive with the {@link Boolean} variants (see 
-     * {@link #additionalPropertiesBoolean(Boolean)}).
-     *
-     * @deprecated since 1.1, use @link {@link #additionalPropertiesSchema(Schema)} instead
-     * @param additionalProperties a Schema which defines additional properties
-     * @return the current Schema instance
-     */
-    @Deprecated
-    default Schema additionalProperties(Schema additionalProperties) {
-        return additionalPropertiesSchema(additionalProperties);
-    }
-
     /**
      * Sets the Schema which defines additional properties not defined by "properties" or "patternProperties".
      * See the javadoc for {@link Schema#getAdditionalPropertiesSchema()} for more details on this setting.  Note 
@@ -776,21 +707,6 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
         return this;
     }
 
-    /**
-     * Sets the value of "additionalProperties" to either True or False.  See the javadoc for 
-     * {@link Schema#getAdditionalPropertiesBoolean()} for more details on this setting.  Note that
-     * this version of the setter is mutually exclusive with the {@link Schema} variants (see 
-     * {@link #additionalPropertiesSchema(Schema)}).
-     *
-     * @deprecated since 1.1, use @link {@link #additionalPropertiesBoolean(Boolean)} instead
-     * @param additionalProperties a Schema which defines additional properties
-     * @return the current Schema instance
-     */
-    @Deprecated
-    default Schema additionalProperties(Boolean additionalProperties) {
-        return additionalPropertiesBoolean(additionalProperties);
-    }
-
     /**
      * Sets the value of "additionalProperties" to either True or False.  See the javadoc for 
      * {@link Schema#getAdditionalPropertiesBoolean()} for more details on this setting.  Note that
@@ -1065,7 +981,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the schemas used by the allOf property.
      *
-     * @return the list of schemas used by the allOf property
+     * @return a copy List (potentially immutable) of schemas used by the allOf property
      **/
     List<Schema> getAllOf();
 
@@ -1105,7 +1021,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the schemas used by the anyOf property.
      *
-     * @return the list of schemas used by the anyOf property
+     * @return a copy List (potentially immutable) of schemas used by the anyOf property
      **/
     List<Schema> getAnyOf();
 
@@ -1145,7 +1061,7 @@ public interface Schema extends Extensible<Schema>, Constructible, Reference<Sch
     /**
      * Returns the schemas used by the oneOf property.
      *
-     * @return the list of schemas used by the oneOf property
+     * @return a copy List (potentially immutable) of schemas used by the oneOf property
      **/
     List<Schema> getOneOf();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/Parameter.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/Parameter.java
index a3f12ce..c6aabe1 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/Parameter.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/Parameter.java
@@ -342,7 +342,7 @@ public interface Parameter extends Constructible, Extensible<Parameter>, Referen
     /**
      * Returns the examples property from a Parameter instance.
      *
-     * @return examples of the parameter
+     * @return a copy Map (potentially immutable) of examples of the parameter
      **/
     Map<String, Example> getExamples();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponse.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponse.java
index e2fa96e..4769761 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponse.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponse.java
@@ -64,7 +64,7 @@ public interface APIResponse extends Constructible, Extensible<APIResponse>, Ref
     /**
      * Returns the map of Headers in this instance of ApiResponse.
      *
-     * @return the headers of this response
+     * @return a copy Map (potentially immutable) of the headers of this response
      **/
 
     Map<String, Header> getHeaders();
@@ -140,9 +140,9 @@ public interface APIResponse extends Constructible, Extensible<APIResponse>, Ref
     }
 
     /**
-     * Returns the operations links that can be followed from tis instance of ApiResponse.
+     * Returns the operations links that can be followed from this instance of ApiResponse.
      *
-     * @return operation links that can be followed from the response
+     * @return a copy Map (potentially immutable) of links that can be followed from the response
      **/
 
     Map<String, Link> getLinks();
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponses.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponses.java
index e8061d2..add6101 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponses.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/responses/APIResponses.java
@@ -28,24 +28,10 @@ import org.eclipse.microprofile.openapi.models.Extensible;
  *
  * @see <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responses-object">Responses Object</a>
  */
-public interface APIResponses extends Constructible, Extensible<APIResponses>, Map<String, APIResponse> {
+public interface APIResponses extends Constructible, Extensible<APIResponses> {
 
     public static final String DEFAULT = "default";
 
-    /**
-     * Adds an APIResponse in the format of the name as a key and the item as the value to APIResponses map
-     * 
-     * @param name the name of APIResponse (http status code eventually with wildcard or {@value #DEFAULT})
-     * @param apiResponse the APIResponse object to be added to APIResponses map. null values will be rejected (implementation will throw an
-     *                    exception) or ignored.
-     * @return APIResponses map with the added ApiResponse instance
-     * @deprecated since 1.1, use {@link #addAPIResponse(String, APIResponse)} instead
-     **/
-    @Deprecated
-    default APIResponses addApiResponse(String name, APIResponse apiResponse) {
-        return addAPIResponse(name, apiResponse);
-    }
-
     /**
      * Adds an APIResponse in the format of the name as a key and the item as the value to APIResponses map
      * 
@@ -106,68 +92,10 @@ public interface APIResponses extends Constructible, Extensible<APIResponses>, M
         return map.get(name);
     }
 
-    /**
-     * In the next version, {@link APIResponses} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getAPIResponse(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    APIResponse get(Object key);
-
-    /**
-     * In the next version, {@link APIResponses} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasAPIResponse(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link APIResponses} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addAPIResponse(String, APIResponse)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    APIResponse put(String key, APIResponse value);
-
-    /**
-     * In the next version, {@link APIResponses} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setAPIResponses(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends APIResponse> m);
-
-    /**
-     * In the next version, {@link APIResponses} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removeAPIResponse(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    APIResponse remove(Object key);
-
-    /**
-     * Returns the default documentation of responses other than the ones declared for specific HTTP response codes in this instance of ApiResponses.
-     * <p>
-     * Convenience method that is the same as calling {@link #get(Object)} on the map with {@value #DEFAULT} as value for the key.
-     * 
-     * @deprecated since 1.1, use @link {@link #getDefaultValue()} instead
-     * @return the default documentation of responses
-     **/
-    @Deprecated 
-    default APIResponse getDefault() {
-        return getDefaultValue();
-    }
-
     /**
      * Returns the default documentation of responses other than the ones declared for specific HTTP response codes in this instance of ApiResponses.
      * <p>
-     * Convenience method that is the same as calling {@link #get(Object)} on the map with {@value #DEFAULT} as value for the key.
+     * Convenience method that is the same as calling {@link #getAPIResponse(String)} on the map with {@value #DEFAULT} as value for the key.
      * 
      * @return the default documentation of responses
      **/
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/security/Scopes.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/security/Scopes.java
index dc03b1c..bb7993b 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/security/Scopes.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/security/Scopes.java
@@ -28,7 +28,7 @@ import org.eclipse.microprofile.openapi.models.Extensible;
  * @see <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#oauthFlowObject">OAuthFlow Object</a>
  **/
 
-public interface Scopes extends Constructible, Extensible<Scopes>, Map<String, String> {
+public interface Scopes extends Constructible, Extensible<Scopes> {
 
     /**
      * Adds name of an existing scope object and item parameters to a Scopes instance as a key-value pair in a map.
@@ -88,49 +88,4 @@ public interface Scopes extends Constructible, Extensible<Scopes>, Map<String, S
         return map.get(scope);
     }
 
-    /**
-     * In the next version, {@link Scopes} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getScope(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    String get(Object key);
-
-    /**
-     * In the next version, {@link Scopes} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasScope(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link Scopes} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addScope(String, String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    String put(String key, String value);
-
-    /**
-     * In the next version, {@link Scopes} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setScopes(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends String> m);
-
-    /**
-     * In the next version, {@link Scopes} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removeScope(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    String remove(Object key);
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/security/SecurityRequirement.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/security/SecurityRequirement.java
index 16edfb4..2edabb8 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/security/SecurityRequirement.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/security/SecurityRequirement.java
@@ -27,7 +27,7 @@ import org.eclipse.microprofile.openapi.models.Constructible;
  *
  * @see <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#security-requirement-object">SecurityRequirement Object</a>
  */
-public interface SecurityRequirement extends Constructible, Map<String, List<String>> {
+public interface SecurityRequirement extends Constructible {
 
     /**
      * Adds a security scheme to the SecurityRequirement instance based on the scheme name and 
@@ -111,49 +111,4 @@ public interface SecurityRequirement extends Constructible, Map<String, List<Str
         return map.get(securitySchemeName);
     }
 
-    /**
-     * In the next version, {@link SecurityRequirement} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getScheme(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    List<String> get(Object key);
-
-    /**
-     * In the next version, {@link SecurityRequirement} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasScheme(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link SecurityRequirement} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addScheme(String, List)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    List<String> put(String key, List<String> value);
-
-    /**
-     * In the next version, {@link SecurityRequirement} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setSchemes(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends List<String>> m);
-
-    /**
-     * In the next version, {@link SecurityRequirement} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removeScheme(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    List<String> remove(Object key);
-
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariable.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariable.java
index 7c370bc..21404fc 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariable.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariable.java
@@ -34,7 +34,7 @@ public interface ServerVariable extends Constructible, Extensible<ServerVariable
      * <p>
      * This property represents an enumeration of string values to be used if the substitution options are from a limited set
      * </p> 
-     * @return List&lt;String&gt; enumeration
+     * @return a copy List (potentially immutable) of possible values for this variable
      **/
     List<String> getEnumeration();
 
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariables.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariables.java
index 1f249cd..ccfe9c9 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariables.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/servers/ServerVariables.java
@@ -30,7 +30,7 @@ import org.eclipse.microprofile.openapi.models.Extensible;
  * need to be extensible
  */
 @Deprecated
-public interface ServerVariables extends Constructible, Extensible<ServerVariables>, Map<String, ServerVariable> {
+public interface ServerVariables extends Constructible, Extensible<ServerVariables> {
 
     /**
      * This method adds a key-value item to a ServerVariables instance from the name-item parameter pair and returns the modified instance.
@@ -90,49 +90,4 @@ public interface ServerVariables extends Constructible, Extensible<ServerVariabl
         return map.get(name);
     }
 
-    /**
-     * In the next version, {@link ServerVariables} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #getServerVariable(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    ServerVariable get(Object key);
-
-    /**
-     * In the next version, {@link ServerVariables} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #hasServerVariable(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    boolean containsKey(Object key);
-    
-    /**
-     * In the next version, {@link ServerVariables} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #addServerVariable(String, ServerVariable)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    ServerVariable put(String key, ServerVariable value);
-
-    /**
-     * In the next version, {@link ServerVariables} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #setServerVariables(Map)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    void putAll(Map<? extends String, ? extends ServerVariable> m);
-
-    /**
-     * In the next version, {@link ServerVariables} will no longer extends {@link Map}, this method will no longer be present.
-     * Use {@link #removeServerVariable(String)} instead.
-     * @deprecated since 1.1
-     */
-    @Deprecated
-    @Override
-    ServerVariable remove(Object key);
-
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8f044c2..9f84966 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
 
     <groupId>org.eclipse.microprofile.openapi</groupId>
     <artifactId>microprofile-openapi-parent</artifactId>
-    <version>1.2-SNAPSHOT</version>
+    <version>2.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>MicroProfile OpenAPI</name>
     <description>Eclipse MicroProfile OpenAPI</description>
diff --git a/spec/pom.xml b/spec/pom.xml
index fe7ee27..982c42b 100644
--- a/spec/pom.xml
+++ b/spec/pom.xml
@@ -20,7 +20,7 @@
         <!-- This is just for now and will not work if the API has a separate release cycle than the rest. -->
         <groupId>org.eclipse.microprofile.openapi</groupId>
         <artifactId>microprofile-openapi-parent</artifactId>
-        <version>1.2-SNAPSHOT</version>
+        <version>2.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>microprofile-openapi-spec</artifactId>
diff --git a/spec/src/main/asciidoc/microprofile-openapi-spec.adoc b/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
index cdabf49..4a1b99b 100644
--- a/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
+++ b/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
@@ -17,7 +17,8 @@
 // limitations under the License.
 //
 
-:authors: Arthur De Magalhaes (Spec Lead), Eric Wittmann, Anna Safonov, Matt Gill, Ivan Junckes Filho, Jérémie Bresson, Jana Manoharan, Rui Qi Wang,Tommy Wojtczak
+:authors: Arthur De Magalhaes (Spec Lead), Leo Christy Jesuraj, Eric Wittmann, Michael Glavassevich, Artur Dzmitryieu, Navid Shakibapour, Anna Safonov, Jana Manoharan, Paul Gooderham
+:email: ademagalhaes@gmail.com, leo.jesuraj@gmail.com, eric.wittmann@gmail.com, mrglavas@ca.ibm.com, dzmitry@ca.ibm.com, navid.shakibapour@gmail.com, anna.safonov@uoit.net, jana.manoharan96@gmail.com, turkeyonmarblerye@gmail.com
 :version-label!:
 :sectanchors:
 :doctype: book
@@ -719,6 +720,72 @@ the interface for microservice (B) to appear in microservice (A)'s OAS3 document
 
 Therefore, vendors are required to exclude from the final OAS3 document any interface annotated with https://github.com/eclipse/microprofile-rest-client/blob/master/api/src/main/java/org/eclipse/microprofile/rest/client/inject/RegisterRestClient.java[org.eclipse.microprofile.rest.client.inject.RegisterRestClient].
 
+== Exposing platform OpenAPIs
+
+Vendors are required to support a mechanism to expose `platform` OpenAPIs to consumers. 
+These are RESTful APIs implemented by the vendor framework itself, which may include 
+MicroProfile Metrics, MicroProfile Health Check, JMX-REST connectors, OpenID Connect Providers
+or any other API the framework may be exposing.  
+
+The exposure of these platform OpenAPIs allows for:
+
+  *  discovery of available platform endpoints
+  *  generation of clients to consume the API (OAS3 -> client_language)
+  *  a standard way to document non-application APIs
+    **  this is probably the most significant reason for this new SPI, as the number of APIs exposed by 
+  frameworks continues to grow and they all need to be documented in some way.  We certainly don't want 
+  RESTful APIs being documented in HTML tables, proprietary / custom formats, etc - if it's a REST API 
+  it should be documented using OpenAPI.
+
+
+=== Registrying a platform OpenAPI
+
+The components within a vendor's framework will register their platform OpenAPI by using the 
+following patttern:
+
+`mp.openapi.spi.platform.<component>=<path_to_OAS3>`
+
+Example:  `mp.openapi.spi.platform.jmx=${server_install_dir}/oas/jmx/openapi.yaml`
+
+Please note that this is an `SPI`, which means it is intended to be set only by the vendor framework, not by
+user applications.
+
+This pattern takes advantage of MicroProfile Config to inject the location of the component's OAS3 doc,
+which creates dynamic and composed deployments, only exposing the platform APIs that are currently enabled.
+
+For dynamic frameworks (e.g. loading and unloading OSGi bundles), components can be unregistered by setting
+their OAS3 path to empty:
+
+`mp.openapi.spi.platform.jmx=`
+
+
+=== Exposing platform OpenAPIs
+
+There are two new RESTful endpoints that vendors must expose.  The first queries which platform OpenAPIs
+are currently available:
+
+*  `GET openapi/platform`  
+** returns a list (following the <<Content format>> rules) of available components exposing
+OAS3 docs.  
+** the component name used matches the `<component>` string used during registration inside the key `mp.openapi.spi.platform.<component>`.
+
+**  A sample returning payload:
+
+[source, yaml]
+----
+'components':
+- metrics
+- jmx
+- oidc
+----
+  
+*  `GET openapi/platform/<component>` 
+**  returns the actual OAS3 doc for that component (following the <<Content format>> rules).
+**  the `servers` element of the OAS3 doc for each component may be omitted, in which case
+the vendor framework must insert an appropriate `servers` value.  
+
+These APIs are public and meant to be used by application developers or anyone that needs to interact with these endpoints.
+
 == Limitations
 
 === Internationalization
diff --git a/spi/pom.xml b/spi/pom.xml
index 815bbff..bd86bf0 100644
--- a/spi/pom.xml
+++ b/spi/pom.xml
@@ -20,7 +20,7 @@
         <!-- This is just for now and will not work if the API has a separate release cycle than the rest. -->
         <groupId>org.eclipse.microprofile.openapi</groupId>
         <artifactId>microprofile-openapi-parent</artifactId>
-        <version>1.2-SNAPSHOT</version>
+        <version>2.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>microprofile-openapi-spi</artifactId>
diff --git a/tck/pom.xml b/tck/pom.xml
index 9c6991d..2bac47a 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -20,7 +20,7 @@
         <!-- This is just for now and will not work if the API has a separate release cycle than the rest. -->
         <groupId>org.eclipse.microprofile.openapi</groupId>
         <artifactId>microprofile-openapi-parent</artifactId>
-        <version>1.2-SNAPSHOT</version>
+        <version>2.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>microprofile-openapi-tck</artifactId>
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/filter/AirlinesOASFilter.java b/tck/src/main/java/org/eclipse/microprofile/openapi/filter/AirlinesOASFilter.java
index 941100a..b08852b 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/filter/AirlinesOASFilter.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/filter/AirlinesOASFilter.java
@@ -55,11 +55,11 @@ public class AirlinesOASFilter implements OASFilter {
             Map<String, Callback> callbacks = pathItem.getPOST().getCallbacks();
             if (callbacks.containsKey("bookingCallback")) {
                 Callback callback = callbacks.get("bookingCallback");
-                if (callback.containsKey("http://localhost:9080/airlines/bookings")
-                        && callback.get("http://localhost:9080/airlines/bookings").getGET() != null) {
-                    if ("child - Retrieve all bookings for current user".equals(callback.get("http://localhost:9080/airlines/bookings")
+                if (callback.hasPathItem("http://localhost:9080/airlines/bookings")
+                        && callback.getPathItem("http://localhost:9080/airlines/bookings").getGET() != null) {
+                    if ("child - Retrieve all bookings for current user".equals(callback.getPathItem("http://localhost:9080/airlines/bookings")
                             .getGET().getDescription())) {   
-                        callback.get("http://localhost:9080/airlines/bookings").getGET()
+                        callback.getPathItem("http://localhost:9080/airlines/bookings").getGET()
                         .setDescription("parent - Retrieve all bookings for current user"); 
                     }
                 }
@@ -127,8 +127,8 @@ public class AirlinesOASFilter implements OASFilter {
         // testing child before parent filtering
         Content content = apiResponse.getContent();
         if (content != null) {
-            if (content.containsKey("application/json")) {
-                Schema schema = content.get("application/json").getSchema();
+            if (content.hasMediaType("application/json")) {
+                Schema schema = content.getMediaType("application/json").getSchema();
                 if ("child - id of the new review".equals(schema.getDescription())) {
                     schema.setDescription("parent - id of the new review");
                 }
@@ -190,13 +190,13 @@ public class AirlinesOASFilter implements OASFilter {
 
     @Override
     public Callback filterCallback(Callback callback) {
-        if(callback.containsKey("{$request.query.callbackUrl}/data") && callback.get("{$request.query.callbackUrl}/data").getPOST() != null){
-            callback.get("{$request.query.callbackUrl}/data").getPOST().setDescription("filterCallback - callback post operation");
+        if(callback.hasPathItem("{$request.query.callbackUrl}/data") && callback.getPathItem("{$request.query.callbackUrl}/data").getPOST() != null){
+            callback.getPathItem("{$request.query.callbackUrl}/data").getPOST().setDescription("filterCallback - callback post operation");
         }
         
-        if (callback.containsKey("http://localhost:9080/airlines/bookings") 
-                && callback.get("http://localhost:9080/airlines/bookings").getGET() != null) {
-            callback.get("http://localhost:9080/airlines/bookings").getGET().setDescription("child - Retrieve all bookings for current user");
+        if (callback.hasPathItem("http://localhost:9080/airlines/bookings") 
+                && callback.getPathItem("http://localhost:9080/airlines/bookings").getGET() != null) {
+            callback.getPathItem("http://localhost:9080/airlines/bookings").getGET().setDescription("child - Retrieve all bookings for current user");
         }
         return callback;
     }
@@ -205,6 +205,6 @@ public class AirlinesOASFilter implements OASFilter {
     public void filterOpenAPI(OpenAPI openAPI) {
         //Spec states : The filterOpenAPI method must be the last method called on a filter (which is just a specialization of the first exception).
         //To ensure that this method is called last, override the operation summary that was previously overridden in filterOperation method
-        openAPI.getPaths().get("/bookings/{id}").getPUT().setSummary("filterOpenAPI - Update a booking with ID");
+        openAPI.getPaths().getPathItem("/bookings/{id}").getPUT().setSummary("filterOpenAPI - Update a booking with ID");
     }
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassBase.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassBase.java
new file mode 100644
index 0000000..4e5fdc8
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassBase.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2019 Contributors to the Eclipse Foundation
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.eclipse.microprofile.openapi.tck;
+
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.startsWith;
+import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
+
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.testng.annotations.Test;
+
+import io.restassured.response.ValidatableResponse;
+
+/**
+ * Base class for config scan classes.
+ */
+public abstract class OASConfigScanClassBase extends AppTestBase {
+    private ValidatableResponse vr;
+    
+    @RunAsClient
+    @Test(dataProvider = "formatProvider")
+    public void testScanClass(String type) throws InterruptedException {
+        vr = callEndpoint(type);
+        vr.body("openapi", startsWith("3.0."));
+        vr.body("paths", aMapWithSize(5));
+        vr.body("paths", hasKey("/reviews"));
+        vr.body("paths", hasKey("/reviews/{id}"));
+        vr.body("paths", hasKey("/reviews/users/{user}"));
+        vr.body("paths", hasKey("/reviews/airlines/{airline}"));
+        vr.body("paths", hasKey("/reviews/{user}/{airlines}"));
+        
+        vr.body("paths.'/reviews'", aMapWithSize(2));
+        vr.body("paths.'/reviews/{id}'", aMapWithSize(2)); 
+        vr.body("paths.'/reviews/users/{user}'", aMapWithSize(1));
+        vr.body("paths.'/reviews/airlines/{airline}'", aMapWithSize(1)); 
+        vr.body("paths.'/reviews/{user}/{airlines}'", aMapWithSize(1)); 
+        
+        
+    }
+}


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java
index b7a81b0..6df6a5a 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/ModelConstructionTest.java
@@ -77,14 +77,23 @@ import org.eclipse.microprofile.openapi.models.servers.ServerVariable;
 import org.eclipse.microprofile.openapi.models.servers.ServerVariables;
 import org.eclipse.microprofile.openapi.models.tags.Tag;
 import org.testng.annotations.Test;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
 
 /**
  * This test covers construction of the OpenAPI model. It verifies that the implementation can
  * create instances of all of the Constructible interfaces and then invokes methods (including
  * getters, setters and builders) on those instances to verify that they behave correctly.
  */
-public class ModelConstructionTest {
+public class ModelConstructionTest extends Arquillian {
     
+    @Deployment
+    public static WebArchive createDeployment() {
+        return ShrinkWrap.create(WebArchive.class);
+    }
+
     // Container for matched getter, setter and builder methods
     static final class Property {
         private final String name;
@@ -161,36 +170,84 @@ public class ModelConstructionTest {
         final Callback callbackValue = createConstructibleInstance(Callback.class);
         checkSameObject(c, c.addCallback(callbackKey, callbackValue));
         checkMapEntry(c.getCallbacks(), callbackKey, callbackValue);
-        assertEquals(c.getCallbacks().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getCallbacks().size(), 1, "The map is expected to contain one entry.");
         c.removeCallback(callbackKey);
-        assertEquals(c.getCallbacks().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getCallbacks().size(), 0, "The map is expected to be empty.");
+        
+        final String callbackKey2 = "myCallbackKey2";
+        final Callback callbackValue2 = createConstructibleInstance(Callback.class);
+        c.setCallbacks(Collections.singletonMap(callbackKey2, callbackValue2));
+        checkMapEntry(c.getCallbacks(), callbackKey2, callbackValue2);
+        assertEquals(c.getCallbacks().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addCallback(callbackKey, callbackValue));
+        checkMapEntry(c.getCallbacks(), callbackKey, callbackValue);
+        assertEquals(c.getCallbacks().size(), 2, "The map is expected to contain two entries.");
+        
+        Callback otherCallbackValue  = createConstructibleInstance(Callback.class);
+        checkMapImmutable(c, Components::getCallbacks, "otherCallback", otherCallbackValue);
         checkNullValueInAdd(c::getCallbacks, c::addCallback, "someCallback", callbackValue);
         
         final String exampleKey = "myExample";
         final Example exampleValue = createConstructibleInstance(Example.class);
         checkSameObject(c, c.addExample(exampleKey, exampleValue));
         checkMapEntry(c.getExamples(), exampleKey, exampleValue);
-        assertEquals(c.getExamples().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getExamples().size(), 1, "The map is expected to contain one entry.");
         c.removeExample(exampleKey);
-        assertEquals(c.getExamples().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getExamples().size(), 0, "The map is expected to be empty.");
+        Example otherExampleValue  = createConstructibleInstance(Example.class);
+        
+        final String exampleKey2 = "myExampleKey2";
+        final Example exampleValue2 = createConstructibleInstance(Example.class);
+        c.setExamples(Collections.singletonMap(exampleKey2, exampleValue2));
+        checkMapEntry(c.getExamples(), exampleKey2, exampleValue2);
+        assertEquals(c.getExamples().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addExample(exampleKey, exampleValue));
+        checkMapEntry(c.getExamples(), exampleKey, exampleValue);
+        assertEquals(c.getExamples().size(), 2, "The map is expected to contain two entries.");
+        
+        checkMapImmutable(c, Components::getExamples, "otherExample", otherExampleValue);
         checkNullValueInAdd(c::getExamples, c::addExample, "someExample", exampleValue);
         
         final String headerKey = "myHeader";
         final Header headerValue = createConstructibleInstance(Header.class);
         checkSameObject(c, c.addHeader(headerKey, headerValue));
         checkMapEntry(c.getHeaders(), headerKey, headerValue);
-        assertEquals(c.getHeaders().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getHeaders().size(), 1, "The map is expected to contain one entry.");
         c.removeHeader(headerKey);
-        assertEquals(c.getHeaders().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getHeaders().size(), 0, "The map is expected to be empty.");
+        Header otherHeaderValue  = createConstructibleInstance(Header.class);
+        
+        final String headerKey2 = "myHeaderKey2";
+        final Header headerValue2 = createConstructibleInstance(Header.class);
+        c.setHeaders(Collections.singletonMap(headerKey2, headerValue2));
+        checkMapEntry(c.getHeaders(), headerKey2, headerValue2);
+        assertEquals(c.getHeaders().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addHeader(headerKey, headerValue));
+        checkMapEntry(c.getHeaders(), headerKey, headerValue);
+        assertEquals(c.getHeaders().size(), 2, "The map is expected to contain two entries.");
+        
+        checkMapImmutable(c, Components::getHeaders, "otherHeader", otherHeaderValue);
         checkNullValueInAdd(c::getHeaders, c::addHeader, "some-header", headerValue);
         
         final String linkKey = "myLink";
         final Link linkValue = createConstructibleInstance(Link.class);
         checkSameObject(c, c.addLink(linkKey, linkValue));
         checkMapEntry(c.getLinks(), linkKey, linkValue);
-        assertEquals(c.getLinks().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getLinks().size(), 1, "The map is expected to contain one entry.");
         c.removeLink(linkKey);
-        assertEquals(c.getLinks().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getLinks().size(), 0, "The map is expected to be empty.");
+        Link otherLinkValue  = createConstructibleInstance(Link.class);
+        
+        final String linkKey2 = "myLinkKey2";
+        final Link linkValue2 = createConstructibleInstance(Link.class);
+        c.setLinks(Collections.singletonMap(linkKey2, linkValue2));
+        checkMapEntry(c.getLinks(), linkKey2, linkValue2);
+        assertEquals(c.getLinks().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addLink(linkKey, linkValue));
+        checkMapEntry(c.getLinks(), linkKey, linkValue);
+        assertEquals(c.getLinks().size(), 2, "The map is expected to contain two entries.");
+        
+        checkMapImmutable(c, Components::getLinks, "otherLink", otherLinkValue);
         checkNullValueInAdd(c::getLinks, c::addLink, "someLink", linkValue);
         
         final String parameterKey = "myParameter";
@@ -202,40 +259,100 @@ public class ModelConstructionTest {
         assertEquals(c.getParameters().size(), 0, "The list is expected to be empty.");
         checkNullValueInAdd(c::getParameters, c::addParameter, "someParameter", parameterValue);
         
+        final String parameterKey2 = "myParameterKey2";
+        final Parameter parameterValue2 = createConstructibleInstance(Parameter.class);
+        c.setParameters(Collections.singletonMap(parameterKey2, parameterValue2));
+        checkMapEntry(c.getParameters(), parameterKey2, parameterValue2);
+        assertEquals(c.getParameters().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addParameter(parameterKey, parameterValue));
+        checkMapEntry(c.getParameters(), parameterKey, parameterValue);
+        assertEquals(c.getParameters().size(), 2, "The map is expected to contain two entries.");
+        
+        Parameter otherParameterValue  = createConstructibleInstance(Parameter.class);
+        checkMapImmutable(c, Components::getParameters, "otherParameter", otherParameterValue);
+        
         final String requestBodyKey = "myRequestBody";
         final RequestBody requestBodyValue = createConstructibleInstance(RequestBody.class);
         checkSameObject(c, c.addRequestBody(requestBodyKey, requestBodyValue));
         checkMapEntry(c.getRequestBodies(), requestBodyKey, requestBodyValue);
-        assertEquals(c.getRequestBodies().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getRequestBodies().size(), 1, "The map is expected to contain one entry.");
         c.removeRequestBody(requestBodyKey);
-        assertEquals(c.getRequestBodies().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getRequestBodies().size(), 0, "The map is expected to be empty.");
+        
+        final String requestBodyKey2 = "myRequestBodyKey2";
+        final RequestBody requestBodyValue2 = createConstructibleInstance(RequestBody.class);
+        c.setRequestBodies(Collections.singletonMap(requestBodyKey2, requestBodyValue2));
+        checkMapEntry(c.getRequestBodies(), requestBodyKey2, requestBodyValue2);
+        assertEquals(c.getRequestBodies().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addRequestBody(requestBodyKey, requestBodyValue));
+        checkMapEntry(c.getRequestBodies(), requestBodyKey, requestBodyValue);
+        assertEquals(c.getRequestBodies().size(), 2, "The map is expected to contain two entries.");
+        
+        RequestBody otherRequestBodyValue  = createConstructibleInstance(RequestBody.class);
+        checkMapImmutable(c, Components::getRequestBodies, "otherRequestBody", otherRequestBodyValue);
         checkNullValueInAdd(c::getRequestBodies, c::addRequestBody, "someRequestBody", requestBodyValue);
         
         final String responseKey = "myResponse";
         final APIResponse responseValue = createConstructibleInstance(APIResponse.class);
         checkSameObject(c, c.addResponse(responseKey, responseValue));
         checkMapEntry(c.getResponses(), responseKey, responseValue);
-        assertEquals(c.getResponses().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getResponses().size(), 1, "The map is expected to contain one entry.");
         c.removeResponse(responseKey);
-        assertEquals(c.getResponses().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getResponses().size(), 0, "The map is expected to be empty.");
+        
+        final String responseKey2 = "myResponseKey2";
+        final APIResponse responseValue2 = createConstructibleInstance(APIResponse.class);
+        c.setResponses(Collections.singletonMap(responseKey2, responseValue2));
+        checkMapEntry(c.getResponses(), responseKey2, responseValue2);
+        assertEquals(c.getResponses().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addResponse(responseKey, responseValue));
+        checkMapEntry(c.getResponses(), responseKey, responseValue);
+        assertEquals(c.getResponses().size(), 2, "The map is expected to contain two entries.");
+        
+        APIResponse otherAPIResponseValue  = createConstructibleInstance(APIResponse.class);
+        checkMapImmutable(c, Components::getResponses, "otherAPIResponse", otherAPIResponseValue);
         checkNullValueInAdd(c::getResponses, c::addResponse, "someResponse", responseValue);
         
         final String schemaKey = "mySchema";
         final Schema schemaValue = createConstructibleInstance(Schema.class);
         checkSameObject(c, c.addSchema(schemaKey, schemaValue));
         checkMapEntry(c.getSchemas(), schemaKey, schemaValue);
-        assertEquals(c.getSchemas().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getSchemas().size(), 1, "The map is expected to contain one entry.");
         c.removeSchema(schemaKey);
-        assertEquals(c.getSchemas().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getSchemas().size(), 0, "The map is expected to be empty.");
+        
+        final String schemaKey2 = "mySchemaKey2";
+        final Schema schemaValue2 = createConstructibleInstance(Schema.class);
+        c.setSchemas(Collections.singletonMap(schemaKey2, schemaValue2));
+        checkMapEntry(c.getSchemas(), schemaKey2, schemaValue2);
+        assertEquals(c.getSchemas().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addSchema(schemaKey, schemaValue));
+        checkMapEntry(c.getSchemas(), schemaKey, schemaValue);
+        assertEquals(c.getSchemas().size(), 2, "The map is expected to contain two entries.");
+        
+        Schema otherSchemaValue  = createConstructibleInstance(Schema.class);
+        checkMapImmutable(c, Components::getSchemas, "otherSchema", otherSchemaValue);
         checkNullValueInAdd(c::getSchemas, c::addSchema, "someSchema", schemaValue);
         
         final String securitySchemeKey = "mySecurityScheme";
         final SecurityScheme securitySchemeValue = createConstructibleInstance(SecurityScheme.class);
         checkSameObject(c, c.addSecurityScheme(securitySchemeKey, securitySchemeValue));
         checkMapEntry(c.getSecuritySchemes(), securitySchemeKey, securitySchemeValue);
-        assertEquals(c.getSecuritySchemes().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(c.getSecuritySchemes().size(), 1, "The map is expected to contain one entry.");
         c.removeSecurityScheme(securitySchemeKey);
-        assertEquals(c.getSecuritySchemes().size(), 0, "The list is expected to be empty.");
+        assertEquals(c.getSecuritySchemes().size(), 0, "The map is expected to be empty.");
+        
+        final String securitySchemeKey2 = "mySecuritySchemeKey2";
+        final SecurityScheme securitySchemeValue2 = createConstructibleInstance(SecurityScheme.class);
+        c.setSecuritySchemes(Collections.singletonMap(securitySchemeKey2, securitySchemeValue2));
+        checkMapEntry(c.getSecuritySchemes(), securitySchemeKey2, securitySchemeValue2);
+        assertEquals(c.getSecuritySchemes().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(c, c.addSecurityScheme(securitySchemeKey, securitySchemeValue));
+        checkMapEntry(c.getSecuritySchemes(), securitySchemeKey, securitySchemeValue);
+        assertEquals(c.getSecuritySchemes().size(), 2, "The map is expected to contain two entries.");
+        
+        SecurityScheme otherSecuritySchemeValue  = createConstructibleInstance(SecurityScheme.class);
+        checkMapImmutable(c, Components::getSecuritySchemes, "otherSecurityScheme", otherSecuritySchemeValue);
         checkNullValueInAdd(c::getSecuritySchemes, c::addSecurityScheme, "someSecurityScheme", securitySchemeValue);
     }
     
@@ -256,6 +373,19 @@ public class ModelConstructionTest {
         o.removeSecurityRequirement(sr);
         assertEquals(o.getSecurity().size(), 0, "The list is expected to be empty.");
         
+        final SecurityRequirement sr2 = createConstructibleInstance(SecurityRequirement.class);
+        sr2.addScheme("OAuth2", "read");
+        o.setSecurity(Collections.singletonList(sr2));
+        assertEquals(o.getSecurity().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getSecurity(), sr2);
+        checkSameObject(o, o.addSecurityRequirement(sr));
+        assertEquals(o.getSecurity().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getSecurity(), sr);
+        
+        SecurityRequirement otherSecurityRequirementValue  = createConstructibleInstance(SecurityRequirement.class);
+        otherSecurityRequirementValue.addScheme("OAuth2", "admin");
+        checkListImmutable(o, OpenAPI::getSecurity, otherSecurityRequirementValue);
+        
         final Server s = createConstructibleInstance(Server.class);
         checkSameObject(o, o.addServer(s));
         checkListEntry(o.getServers(), s);
@@ -263,12 +393,34 @@ public class ModelConstructionTest {
         o.removeServer(s);
         assertEquals(o.getServers().size(), 0, "The list is expected to be empty.");
         
+        final Server s2 = createConstructibleInstance(Server.class);
+        o.setServers(Collections.singletonList(s2));
+        assertEquals(o.getServers().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getServers(), s2);
+        checkSameObject(o, o.addServer(s));
+        assertEquals(o.getSecurity().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getServers(), s);
+        
+        Server otherServer  = createConstructibleInstance(Server.class);
+        checkListImmutable(o, OpenAPI::getServers, otherServer);
+        
         final Tag t = createConstructibleInstance(Tag.class);
         checkSameObject(o, o.addTag(t));
         checkListEntry(o.getTags(), t);
         assertEquals(o.getTags().size(), 1, "The list is expected to contain one entry.");
         o.removeTag(t);
         assertEquals(o.getTags().size(), 0, "The list is expected to be empty.");
+        
+        final Tag t2 = createConstructibleInstance(Tag.class);
+        o.setTags(Collections.singletonList(t2));
+        assertEquals(o.getTags().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getTags(), t2);
+        checkSameObject(o, o.addTag(t));
+        assertEquals(o.getSecurity().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getTags(), t);
+        
+        Tag otherTag  = createConstructibleInstance(Tag.class);
+        checkListImmutable(o, OpenAPI::getTags, otherTag);
     }
     
     @Test
@@ -282,6 +434,17 @@ public class ModelConstructionTest {
         o.removeParameter(p);
         assertEquals(o.getParameters().size(), 0, "The list is expected to be empty.");
         
+        final Parameter p2 = createConstructibleInstance(Parameter.class);
+        o.setParameters(Collections.singletonList(p2));
+        assertEquals(o.getParameters().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getParameters(), p2);
+        checkSameObject(o, o.addParameter(p));
+        assertEquals(o.getParameters().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getParameters(), p);
+        
+        Parameter otherParameter  = createConstructibleInstance(Parameter.class);
+        checkListImmutable(o, Operation::getParameters, otherParameter);
+        
         final SecurityRequirement sr = createConstructibleInstance(SecurityRequirement.class);
         sr.addScheme("OAuth2", Arrays.asList("read", "write"));
         checkSameObject(o, o.addSecurityRequirement(sr));
@@ -290,6 +453,19 @@ public class ModelConstructionTest {
         o.removeSecurityRequirement(sr);
         assertEquals(o.getSecurity().size(), 0, "The list is expected to be empty.");
         
+        final SecurityRequirement sr2 = createConstructibleInstance(SecurityRequirement.class);
+        sr2.addScheme("ApiKey");
+        o.setSecurity(Collections.singletonList(sr2));
+        assertEquals(o.getSecurity().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getSecurity(), sr2);
+        checkSameObject(o, o.addSecurityRequirement(sr));
+        assertEquals(o.getSecurity().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getSecurity(), sr);
+        
+        SecurityRequirement otherSecurityRequirement  = createConstructibleInstance(SecurityRequirement.class);
+        otherSecurityRequirement.addScheme("BasicAuth");
+        checkListImmutable(o, Operation::getSecurity, otherSecurityRequirement);
+        
         final Server s = createConstructibleInstance(Server.class);
         checkSameObject(o, o.addServer(s));
         checkListEntry(o.getServers(), s);
@@ -297,6 +473,17 @@ public class ModelConstructionTest {
         o.removeServer(s);
         assertEquals(o.getServers().size(), 0, "The list is expected to be empty.");
         
+        final Server s2 = createConstructibleInstance(Server.class);
+        o.setServers(Collections.singletonList(s2));
+        assertEquals(o.getServers().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getServers(), s2);
+        checkSameObject(o, o.addServer(s));
+        assertEquals(o.getServers().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getServers(), s);
+        
+        Server otherServer  = createConstructibleInstance(Server.class);
+        checkListImmutable(o, Operation::getServers, otherServer);
+        
         final String tag = new String("myTag");
         checkSameObject(o, o.addTag(tag));
         checkListEntry(o.getTags(), tag);
@@ -304,13 +491,36 @@ public class ModelConstructionTest {
         o.removeTag(tag);
         assertEquals(o.getTags().size(), 0, "The list is expected to be empty.");
         
+        final String tag2 = new String("myTag2");
+        o.setTags(Collections.singletonList(tag2));
+        assertEquals(o.getTags().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(o.getTags(), tag2);
+        checkSameObject(o, o.addTag(tag));
+        assertEquals(o.getTags().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(o.getTags(), tag);
+        
+        String otherTag  = new String("otherTag");
+        checkListImmutable(o, Operation::getTags, otherTag);
+        
         final String callbackKey = "myCallback";
         final Callback callbackValue = createConstructibleInstance(Callback.class);
         checkSameObject(o, o.addCallback(callbackKey, callbackValue));
         checkMapEntry(o.getCallbacks(), callbackKey, callbackValue);
-        assertEquals(o.getCallbacks().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(o.getCallbacks().size(), 1, "The map is expected to contain one entry.");
         o.removeCallback(callbackKey);
-        assertEquals(o.getCallbacks().size(), 0, "The list is expected to be empty.");
+        assertEquals(o.getCallbacks().size(), 0, "The map is expected to be empty.");
+        
+        final String callbackKey2 = "myCallbackKey2";
+        final Callback callbackValue2 = createConstructibleInstance(Callback.class);
+        o.setCallbacks(Collections.singletonMap(callbackKey2, callbackValue2));
+        checkMapEntry(o.getCallbacks(), callbackKey2, callbackValue2);
+        assertEquals(o.getCallbacks().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(o, o.addCallback(callbackKey, callbackValue));
+        checkMapEntry(o.getCallbacks(), callbackKey, callbackValue);
+        assertEquals(o.getCallbacks().size(), 2, "The map is expected to contain two entries.");
+        
+        Callback otherCallback  = createConstructibleInstance(Callback.class);
+        checkMapImmutable(o, Operation::getCallbacks, "otherCallback", otherCallback);
         checkNullValueInAdd(o::getCallbacks, o::addCallback, "someCallback", callbackValue);
     }
     
@@ -325,6 +535,17 @@ public class ModelConstructionTest {
         pi.removeParameter(p);
         assertEquals(pi.getParameters().size(), 0, "The list is expected to be empty.");
         
+        final Parameter p2 = createConstructibleInstance(Parameter.class);
+        pi.setParameters(Collections.singletonList(p2));
+        assertEquals(pi.getParameters().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(pi.getParameters(), p2);
+        checkSameObject(pi, pi.addParameter(p));
+        assertEquals(pi.getParameters().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(pi.getParameters(), p);
+        
+        Parameter otherParameter  = createConstructibleInstance(Parameter.class);
+        checkListImmutable(pi, PathItem::getParameters, otherParameter);
+        
         final Server s = createConstructibleInstance(Server.class);
         checkSameObject(pi, pi.addServer(s));
         checkListEntry(pi.getServers(), s);
@@ -332,6 +553,17 @@ public class ModelConstructionTest {
         pi.removeServer(s);
         assertEquals(pi.getServers().size(), 0, "The list is expected to be empty.");
         
+        final Server s2 = createConstructibleInstance(Server.class);
+        pi.setServers(Collections.singletonList(s2));
+        assertEquals(pi.getServers().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(pi.getServers(), s2);
+        checkSameObject(pi, pi.addServer(s));
+        assertEquals(pi.getServers().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(pi.getServers(), s);
+        
+        Server otherServer  = createConstructibleInstance(Server.class);
+        checkListImmutable(pi, PathItem::getServers, otherServer);
+        
         final Operation o1 = createConstructibleInstance(Operation.class);
         checkSameObject(pi, pi.GET(o1));
         checkSameObject(o1, pi.getGET());
@@ -379,36 +611,30 @@ public class ModelConstructionTest {
         final Paths p = processConstructible(Paths.class);
         
         final String pathItemKey = "/myPathItem";
-        assertFalse(p.hasPathItem(pathItemKey), pathItemKey + " is absent in the map");
         final PathItem pathItemValue = createConstructibleInstance(PathItem.class);
-        checkSameObject(p, p.addPathItem(pathItemKey, pathItemValue));
+        p.setPathItems(Collections.singletonMap(pathItemKey, pathItemValue));
         assertTrue(p.hasPathItem(pathItemKey), pathItemKey + " is present in the map");
+        assertEquals(p.getPathItems().size(), 1, "The map is expected to contain one entry.");
         assertSame(p.getPathItem(pathItemKey), pathItemValue, 
                 "The value associated with the key: " + pathItemKey + " is expected to be the same one that was added.");
-        checkMapEntry(p, pathItemKey, pathItemValue);
         checkMapEntry(p.getPathItems(), pathItemKey, pathItemValue);
         
         final String pathItemKey2 = "/myPathItem2";
         assertFalse(p.hasPathItem(pathItemKey2), pathItemKey2 + " is absent in the map");
         final PathItem pathItemValue2 = createConstructibleInstance(PathItem.class);
-        assertNull(p.put(pathItemKey2, pathItemValue2), "No previous mapping expected.");
+        checkSameObject(p, p.addPathItem(pathItemKey2, pathItemValue2));
         assertTrue(p.hasPathItem(pathItemKey2), pathItemKey2 + " is present in the map");
+        assertEquals(p.getPathItems().size(), 2, "The map is expected to contain two entries.");
         assertSame(p.getPathItem(pathItemKey2), pathItemValue2, 
                 "The value associated with the key: " + pathItemKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(p, pathItemKey2, pathItemValue2);
         checkMapEntry(p.getPathItems(), pathItemKey2, pathItemValue2);
         
-        assertEquals(p.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(p.getPathItems().size(), 2, "The map is expected to contain two entries.");
-        
         p.removePathItem(pathItemKey);
         assertFalse(p.hasPathItem(pathItemKey), pathItemKey + " is absent in the map");
-        assertEquals(p.size(), 1, "The map is expected to contain one entry.");
         assertEquals(p.getPathItems().size(), 1, "The map is expected to contain one entry.");
         
-        p.remove(pathItemKey2);
+        p.removePathItem(pathItemKey2);
         assertFalse(p.hasPathItem(pathItemKey2), pathItemKey + " is absent in the map");
-        assertEquals(p.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(p.getPathItems().size(), 0, "The map is expected to contain 0 entries.");
         
         final PathItem otherValue = createConstructibleInstance(PathItem.class);
@@ -421,36 +647,30 @@ public class ModelConstructionTest {
         final Callback c = processConstructible(Callback.class);
         
         final String pathItemKey = "myPathItem";
-        assertFalse(c.hasPathItem(pathItemKey), pathItemKey + " is absent in the map");
         final PathItem pathItemValue = createConstructibleInstance(PathItem.class);
-        checkSameObject(c, c.addPathItem(pathItemKey, pathItemValue));
+        c.setPathItems(Collections.singletonMap(pathItemKey, pathItemValue));
         assertTrue(c.hasPathItem(pathItemKey), pathItemKey + " is present in the map");
+        assertEquals(c.getPathItems().size(), 1, "The map is expected to contain one entry.");
         assertSame(c.getPathItem(pathItemKey), pathItemValue, 
                 "The value associated with the key: " + pathItemKey + " is expected to be the same one that was added.");
-        checkMapEntry(c, pathItemKey, pathItemValue);
         checkMapEntry(c.getPathItems(), pathItemKey, pathItemValue);
         
         final String pathItemKey2 = "myPathItem2";
         assertFalse(c.hasPathItem(pathItemKey2), pathItemKey2 + " is absent in the map");
         final PathItem pathItemValue2 = createConstructibleInstance(PathItem.class);
-        assertNull(c.put(pathItemKey2, pathItemValue2), "No previous mapping expected.");
+        checkSameObject(c, c.addPathItem(pathItemKey2, pathItemValue2));
         assertTrue(c.hasPathItem(pathItemKey2), pathItemKey2 + " is present in the map");
+        assertEquals(c.getPathItems().size(), 2, "The map is expected to contain two entries.");
         assertSame(c.getPathItem(pathItemKey2), pathItemValue2, 
                 "The value associated with the key: " + pathItemKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(c, pathItemKey2, pathItemValue2);
         checkMapEntry(c.getPathItems(), pathItemKey2, pathItemValue2);
         
-        assertEquals(c.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(c.getPathItems().size(), 2, "The map is expected to contain two entries.");
-        
         c.removePathItem(pathItemKey);
         assertFalse(c.hasPathItem(pathItemKey), pathItemKey + " is absent in the map");
-        assertEquals(c.size(), 1, "The map is expected to contain one entry.");
         assertEquals(c.getPathItems().size(), 1, "The map is expected to contain one entry.");
         
-        c.remove(pathItemKey2);
+        c.removePathItem(pathItemKey2);
         assertFalse(c.hasPathItem(pathItemKey2), pathItemKey + " is absent in the map");
-        assertEquals(c.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(c.getPathItems().size(), 0, "The map is expected to contain 0 entries.");
         
         final PathItem otherValue = createConstructibleInstance(PathItem.class);
@@ -471,9 +691,21 @@ public class ModelConstructionTest {
         final Example exampleValue = createConstructibleInstance(Example.class);
         checkSameObject(h, h.addExample(exampleKey, exampleValue));
         checkMapEntry(h.getExamples(), exampleKey, exampleValue);
-        assertEquals(h.getExamples().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(h.getExamples().size(), 1, "The map is expected to contain one entry.");
         h.removeExample(exampleKey);
-        assertEquals(h.getExamples().size(), 0, "The list is expected to be empty.");
+        assertEquals(h.getExamples().size(), 0, "The map is expected to be empty.");
+        
+        final String exampleKey2 = "myExampleKey2";
+        final Example exampleValue2 = createConstructibleInstance(Example.class);
+        h.setExamples(Collections.singletonMap(exampleKey2, exampleValue2));
+        checkMapEntry(h.getExamples(), exampleKey2, exampleValue2);
+        assertEquals(h.getExamples().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(h, h.addExample(exampleKey, exampleValue));
+        checkMapEntry(h.getExamples(), exampleKey, exampleValue);
+        assertEquals(h.getExamples().size(), 2, "The map is expected to contain two entries.");
+        
+        Example otherExampleValue = createConstructibleInstance(Example.class);
+        checkMapImmutable(h, Header::getExamples, "otherExample", otherExampleValue);
         checkNullValueInAdd(h::getExamples, h::addExample, "otherExample", exampleValue);
     }
     
@@ -500,9 +732,21 @@ public class ModelConstructionTest {
         final String parameterValue = "$request.parameter.id";
         checkSameObject(l, l.addParameter(parameterKey, parameterValue));
         checkMapEntry(l.getParameters(), parameterKey, parameterValue);
-        assertEquals(l.getParameters().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(l.getParameters().size(), 1, "The map is expected to contain one entry.");
         l.removeParameter(parameterKey);
-        assertEquals(l.getParameters().size(), 0, "The list is expected to be empty.");
+        assertEquals(l.getParameters().size(), 0, "The map is expected to be empty.");
+        
+        final String parameterKey2 = "myParameterKey2";
+        final String parameterValue2 = "$request.parameter2.id";
+        l.setParameters(Collections.singletonMap(parameterKey2, parameterValue2));
+        checkMapEntry(l.getParameters(), parameterKey2, parameterValue2);
+        assertEquals(l.getParameters().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(l, l.addParameter(parameterKey, parameterValue));
+        checkMapEntry(l.getParameters(), parameterKey, parameterValue);
+        assertEquals(l.getParameters().size(), 2, "The map is expected to contain two entries.");
+        
+        Object otherExampleValue = new Object();
+        checkMapImmutable(l, Link::getParameters, "otherParameter", otherExampleValue);
         checkNullValueInAdd(l::getParameters, l::addParameter, "otherParameter", parameterValue);
     }
     
@@ -511,36 +755,30 @@ public class ModelConstructionTest {
         final Content c = processConstructible(Content.class);
         
         final String mediaTypeKey = "application/json";
-        assertFalse(c.hasMediaType(mediaTypeKey), mediaTypeKey + " is absent in the map");
         final MediaType mediaTypeValue = createConstructibleInstance(MediaType.class);
-        checkSameObject(c, c.addMediaType(mediaTypeKey, mediaTypeValue));
+        c.setMediaTypes(Collections.singletonMap(mediaTypeKey, mediaTypeValue));
         assertTrue(c.hasMediaType(mediaTypeKey), mediaTypeKey + " is present in the map");
+        assertEquals(c.getMediaTypes().size(), 1, "The map is expected to contain one entry.");
         assertSame(c.getMediaType(mediaTypeKey), mediaTypeValue, 
                 "The value associated with the key: " + mediaTypeKey + " is expected to be the same one that was added.");
-        checkMapEntry(c, mediaTypeKey, mediaTypeValue);
         checkMapEntry(c.getMediaTypes(), mediaTypeKey, mediaTypeValue);
         
         final String mediaTypeKey2 = "*/*";
         assertFalse(c.hasMediaType(mediaTypeKey2), mediaTypeKey2 + " is absent in the map");
         final MediaType mediaTypeValue2 = createConstructibleInstance(MediaType.class);
-        assertNull(c.put(mediaTypeKey2, mediaTypeValue2), "No previous mapping expected.");
+        checkSameObject(c, c.addMediaType(mediaTypeKey2, mediaTypeValue2));
         assertTrue(c.hasMediaType(mediaTypeKey2), mediaTypeKey2 + " is present in the map");
+        assertEquals(c.getMediaTypes().size(), 2, "The map is expected to contain two entries.");
         assertSame(c.getMediaType(mediaTypeKey2), mediaTypeValue2, 
                 "The value associated with the key: " + mediaTypeKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(c, mediaTypeKey2, mediaTypeValue2);
         checkMapEntry(c.getMediaTypes(), mediaTypeKey2, mediaTypeValue2);
         
-        assertEquals(c.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(c.getMediaTypes().size(), 2, "The map is expected to contain two entries.");
-        
         c.removeMediaType(mediaTypeKey);
         assertFalse(c.hasMediaType(mediaTypeKey), mediaTypeKey + " is absent in the map");
-        assertEquals(c.size(), 1, "The map is expected to contain one entry.");
         assertEquals(c.getMediaTypes().size(), 1, "The map is expected to contain one entry.");
         
-        c.remove(mediaTypeKey2);
+        c.removeMediaType(mediaTypeKey2);
         assertFalse(c.hasMediaType(mediaTypeKey2), mediaTypeKey + " is absent in the map");
-        assertEquals(c.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(c.getMediaTypes().size(), 0, "The map is expected to contain 0 entries.");
         
         final MediaType otherValue = createConstructibleInstance(MediaType.class);
@@ -555,9 +793,21 @@ public class ModelConstructionTest {
         final String value = new String("myValue");
         checkSameObject(d, d.addMapping(key, value));
         checkMapEntry(d.getMapping(), key, value);
-        assertEquals(d.getMapping().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(d.getMapping().size(), 1, "The map is expected to contain one entry.");
         d.removeMapping(key);
-        assertEquals(d.getMapping().size(), 0, "The list is expected to be empty.");
+        assertEquals(d.getMapping().size(), 0, "The map is expected to be empty.");
+        
+        final String key2 = "myCallbackKey2";
+        final String value2 = new String("myValue2");
+        d.setMapping(Collections.singletonMap(key2, value2));
+        checkMapEntry(d.getMapping(), key2, value2);
+        assertEquals(d.getMapping().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(d, d.addMapping(key, value));
+        checkMapEntry(d.getMapping(), key, value);
+        assertEquals(d.getMapping().size(), 2, "The map is expected to contain two entries.");
+        
+        final String otherValue = new String("otherValue");
+        checkMapImmutable(d, Discriminator::getMapping, "otherValue", otherValue);
         checkNullValueInAdd(d::getMapping, d::addMapping, "otherKey", value);
     }
     
@@ -569,9 +819,21 @@ public class ModelConstructionTest {
         final Header headerValue = createConstructibleInstance(Header.class);
         checkSameObject(e, e.addHeader(headerKey, headerValue));
         checkMapEntry(e.getHeaders(), headerKey, headerValue);
-        assertEquals(e.getHeaders().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(e.getHeaders().size(), 1, "The map is expected to contain one entry.");
         e.removeHeader(headerKey);
-        assertEquals(e.getHeaders().size(), 0, "The list is expected to be empty.");
+        assertEquals(e.getHeaders().size(), 0, "The map is expected to be empty.");
+        
+        final String headerKey2 = "myHeaderKey2";
+        final Header headerValue2 = createConstructibleInstance(Header.class);
+        e.setHeaders(Collections.singletonMap(headerKey2, headerValue2));
+        checkMapEntry(e.getHeaders(), headerKey2, headerValue2);
+        assertEquals(e.getHeaders().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(e, e.addHeader(headerKey, headerValue));
+        checkMapEntry(e.getHeaders(), headerKey, headerValue);
+        assertEquals(e.getHeaders().size(), 2, "The map is expected to contain two entries.");
+        
+        final Header otherHeaderValue = createConstructibleInstance(Header.class);
+        checkMapImmutable(e, Encoding::getHeaders, "otherHeader", otherHeaderValue);
         checkNullValueInAdd(e::getHeaders, e::addHeader, "otherHeaderKey", headerValue);
     }
     
@@ -583,18 +845,42 @@ public class ModelConstructionTest {
         final Encoding encodingValue = createConstructibleInstance(Encoding.class);
         checkSameObject(mt, mt.addEncoding(encodingKey, encodingValue));
         checkMapEntry(mt.getEncoding(), encodingKey, encodingValue);
-        assertEquals(mt.getEncoding().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(mt.getEncoding().size(), 1, "The map is expected to contain one entry.");
         mt.removeEncoding(encodingKey);
-        assertEquals(mt.getEncoding().size(), 0, "The list is expected to be empty.");
+        assertEquals(mt.getEncoding().size(), 0, "The map is expected to be empty.");
+        
+        final String encodingKey2 = "myEncodingKey2";
+        final Encoding encodingValue2 = createConstructibleInstance(Encoding.class);
+        mt.setEncoding(Collections.singletonMap(encodingKey2, encodingValue2));
+        checkMapEntry(mt.getEncoding(), encodingKey2, encodingValue2);
+        assertEquals(mt.getEncoding().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(mt, mt.addEncoding(encodingKey, encodingValue));
+        checkMapEntry(mt.getEncoding(), encodingKey, encodingValue);
+        assertEquals(mt.getEncoding().size(), 2, "The map is expected to contain two entries.");
+        
+        Encoding otherEncodingValue = createConstructibleInstance(Encoding.class);
+        checkMapImmutable(mt, MediaType::getEncoding, "otherEncoding", otherEncodingValue);
         checkNullValueInAdd(mt::getEncoding, mt::addEncoding, "otherEncoding", encodingValue);
         
         final String exampleKey = "myExample";
         final Example exampleValue = createConstructibleInstance(Example.class);
         checkSameObject(mt, mt.addExample(exampleKey, exampleValue));
         checkMapEntry(mt.getExamples(), exampleKey, exampleValue);
-        assertEquals(mt.getExamples().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(mt.getExamples().size(), 1, "The map is expected to contain one entry.");
         mt.removeExample(exampleKey);
-        assertEquals(mt.getExamples().size(), 0, "The list is expected to be empty.");
+        assertEquals(mt.getExamples().size(), 0, "The map is expected to be empty.");
+        
+        final String exampleKey2 = "myExampleKey2";
+        final Example exampleValue2 = createConstructibleInstance(Example.class);
+        mt.setExamples(Collections.singletonMap(exampleKey2, exampleValue2));
+        checkMapEntry(mt.getExamples(), exampleKey2, exampleValue2);
+        assertEquals(mt.getExamples().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(mt, mt.addExample(exampleKey, exampleValue));
+        checkMapEntry(mt.getExamples(), exampleKey, exampleValue);
+        assertEquals(mt.getExamples().size(), 2, "The map is expected to contain two entries.");
+        
+        Example otherExampleValue = createConstructibleInstance(Example.class);
+        checkMapImmutable(mt, MediaType::getExamples, "otherExample", otherExampleValue);
         checkNullValueInAdd(mt::getExamples, mt::addExample, "otherExample", exampleValue);
     }
     
@@ -623,6 +909,17 @@ public class ModelConstructionTest {
         s.removeAllOf(allOf);
         assertEquals(s.getAllOf().size(), 0, "The list is expected to be empty.");
         
+        final Schema allOf2 = createConstructibleInstance(Schema.class);
+        s.setAllOf(Collections.singletonList(allOf2));
+        assertEquals(s.getAllOf().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(s.getAllOf(), allOf2);
+        checkSameObject(s, s.addAllOf(allOf));
+        assertEquals(s.getAllOf().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(s.getAllOf(), allOf);
+        
+        final Schema otherAllOfValue = createConstructibleInstance(Schema.class);
+        checkListImmutable(s, Schema::getAllOf, otherAllOfValue);
+        
         final Schema anyOf = createConstructibleInstance(Schema.class);
         checkSameObject(s, s.addAnyOf(anyOf));
         checkListEntry(s.getAnyOf(), anyOf);
@@ -630,6 +927,17 @@ public class ModelConstructionTest {
         s.removeAnyOf(anyOf);
         assertEquals(s.getAnyOf().size(), 0, "The list is expected to be empty.");
         
+        final Schema anyOf2 = createConstructibleInstance(Schema.class);
+        s.setAnyOf(Collections.singletonList(anyOf2));
+        assertEquals(s.getAnyOf().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(s.getAnyOf(), anyOf2);
+        checkSameObject(s, s.addAnyOf(anyOf));
+        assertEquals(s.getAnyOf().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(s.getAnyOf(), anyOf);
+        
+        final Schema otherAnyOfValue = createConstructibleInstance(Schema.class);
+        checkListImmutable(s, Schema::getAnyOf, otherAnyOfValue);
+        
         final String enumeration = new String("enumValue");
         checkSameObject(s, s.addEnumeration(enumeration));
         checkListEntry(s.getEnumeration(), enumeration);
@@ -637,6 +945,17 @@ public class ModelConstructionTest {
         s.removeEnumeration(enumeration);
         assertEquals(s.getEnumeration().size(), 0, "The list is expected to be empty.");
         
+        final String enumeration2 = new String("enumValue2");
+        s.setEnumeration(Collections.singletonList(enumeration2));
+        assertEquals(s.getEnumeration().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(s.getEnumeration(), enumeration2);
+        checkSameObject(s, s.addEnumeration(enumeration));
+        assertEquals(s.getEnumeration().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(s.getEnumeration(), enumeration);
+        
+        final String otherEnumerationValue = new String("otherValue");
+        checkListImmutable(s, Schema::getEnumeration , otherEnumerationValue);
+        
         final Schema oneOf = createConstructibleInstance(Schema.class);
         checkSameObject(s, s.addOneOf(oneOf));
         checkListEntry(s.getOneOf(), oneOf);
@@ -644,13 +963,36 @@ public class ModelConstructionTest {
         s.removeOneOf(oneOf);
         assertEquals(s.getOneOf().size(), 0, "The list is expected to be empty.");
         
+        final Schema oneOf2 = createConstructibleInstance(Schema.class);
+        s.setOneOf(Collections.singletonList(oneOf2));
+        assertEquals(s.getOneOf().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(s.getOneOf(), oneOf2);
+        checkSameObject(s, s.addOneOf(oneOf));
+        assertEquals(s.getOneOf().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(s.getOneOf(), oneOf);
+        
+        final Schema otherOneOfValue = createConstructibleInstance(Schema.class);
+        checkListImmutable(s, Schema::getOneOf, otherOneOfValue);
+        
         final String propertySchemaKey = "myPropertySchemaKey";
         final Schema propertySchemaValue = createConstructibleInstance(Schema.class);
         checkSameObject(s, s.addProperty(propertySchemaKey, propertySchemaValue));
         checkMapEntry(s.getProperties(), propertySchemaKey, propertySchemaValue);
-        assertEquals(s.getProperties().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(s.getProperties().size(), 1, "The map is expected to contain one entry.");
         s.removeProperty(propertySchemaKey);
-        assertEquals(s.getProperties().size(), 0, "The list is expected to be empty.");
+        assertEquals(s.getProperties().size(), 0, "The map is expected to be empty.");
+        
+        final String propertySchemaKey2 = "myPropertySchemaKey2";
+        final Schema propertySchemaValue2 = createConstructibleInstance(Schema.class);
+        s.setProperties(Collections.singletonMap(propertySchemaKey2, propertySchemaValue2));
+        checkMapEntry(s.getProperties(), propertySchemaKey2, propertySchemaValue2);
+        assertEquals(s.getProperties().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(s, s.addProperty(propertySchemaKey, propertySchemaValue));
+        checkMapEntry(s.getProperties(), propertySchemaKey, propertySchemaValue);
+        assertEquals(s.getProperties().size(), 2, "The map is expected to contain two entries.");
+        
+        final Schema otherPropertyValue = createConstructibleInstance(Schema.class);
+        checkMapImmutable(s, Schema::getProperties, "otherPropertyKey", otherPropertyValue);
         checkNullValueInAdd(s::getProperties, s::addProperty, "otherProperty", propertySchemaValue);
         
         final String required = new String("required");
@@ -659,6 +1001,17 @@ public class ModelConstructionTest {
         assertEquals(s.getRequired().size(), 1, "The list is expected to contain one entry.");
         s.removeRequired(required);
         assertEquals(s.getRequired().size(), 0, "The list is expected to be empty.");
+        
+        final String required2 = new String("required2");
+        s.setRequired(Collections.singletonList(required2));
+        assertEquals(s.getRequired().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(s.getRequired(), required2);
+        checkSameObject(s, s.addRequired(required));
+        assertEquals(s.getRequired().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(s.getRequired(), required);
+        
+        final String otherRequiredValue = new String("otherRequired");
+        checkListImmutable(s, Schema::getEnumeration, otherRequiredValue);
     }
     
     @Test
@@ -674,9 +1027,21 @@ public class ModelConstructionTest {
         final Example exampleValue = createConstructibleInstance(Example.class);
         checkSameObject(p, p.addExample(exampleKey, exampleValue));
         checkMapEntry(p.getExamples(), exampleKey, exampleValue);
-        assertEquals(p.getExamples().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(p.getExamples().size(), 1, "The map is expected to contain one entry.");
         p.removeExample(exampleKey);
-        assertEquals(p.getExamples().size(), 0, "The list is expected to be empty.");
+        assertEquals(p.getExamples().size(), 0, "The map is expected to be empty.");
+        
+        final String exampleKey2 = "myExampleKey2";
+        final Example exampleValue2 = createConstructibleInstance(Example.class);
+        p.setExamples(Collections.singletonMap(exampleKey2, exampleValue2));
+        checkMapEntry(p.getExamples(), exampleKey2, exampleValue2);
+        assertEquals(p.getExamples().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(p, p.addExample(exampleKey, exampleValue));
+        checkMapEntry(p.getExamples(), exampleKey, exampleValue);
+        assertEquals(p.getExamples().size(), 2, "The map is expected to contain two entries.");
+        
+        Example otherExampleValue = createConstructibleInstance(Example.class);
+        checkMapImmutable(p, Parameter::getExamples, "otherExample", otherExampleValue);
         checkNullValueInAdd(p::getExamples, p::addExample, "otherExample", exampleValue);
     }
     
@@ -693,18 +1058,42 @@ public class ModelConstructionTest {
         final Header headerValue = createConstructibleInstance(Header.class);
         checkSameObject(response, response.addHeader(headerKey, headerValue));
         checkMapEntry(response.getHeaders(), headerKey, headerValue);
-        assertEquals(response.getHeaders().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(response.getHeaders().size(), 1, "The map is expected to contain one entry.");
         response.removeHeader(headerKey);
-        assertEquals(response.getHeaders().size(), 0, "The list is expected to be empty.");
+        assertEquals(response.getHeaders().size(), 0, "The map is expected to be empty.");
+        
+        final String headerKey2 = "myHeaderKey2";
+        final Header headerValue2 = createConstructibleInstance(Header.class);
+        response.setHeaders(Collections.singletonMap(headerKey2, headerValue2));
+        checkMapEntry(response.getHeaders(), headerKey2, headerValue2);
+        assertEquals(response.getHeaders().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(response, response.addHeader(headerKey, headerValue));
+        checkMapEntry(response.getHeaders(), headerKey, headerValue);
+        assertEquals(response.getHeaders().size(), 2, "The map is expected to contain two entries.");
+        
+        Header otherHeaderValue  = createConstructibleInstance(Header.class);
+        checkMapImmutable(response, APIResponse::getHeaders, "otherHeader", otherHeaderValue);
         checkNullValueInAdd(response::getHeaders, response::addHeader, "some-header", headerValue);
         
         final String linkKey = "myLinkKey";
         final Link linkValue = createConstructibleInstance(Link.class);
         checkSameObject(response, response.addLink(linkKey, linkValue));
         checkMapEntry(response.getLinks(), linkKey, linkValue);
-        assertEquals(response.getLinks().size(), 1, "The list is expected to contain one entry.");
+        assertEquals(response.getLinks().size(), 1, "The map is expected to contain one entry.");
         response.removeLink(linkKey);
-        assertEquals(response.getLinks().size(), 0, "The list is expected to be empty.");
+        assertEquals(response.getLinks().size(), 0, "The map is expected to be empty.");
+        Link otherLinkValue  = createConstructibleInstance(Link.class);
+        
+        final String linkKey2 = "myLinkKey2";
+        final Link linkValue2 = createConstructibleInstance(Link.class);
+        response.setLinks(Collections.singletonMap(linkKey2, linkValue2));
+        checkMapEntry(response.getLinks(), linkKey2, linkValue2);
+        assertEquals(response.getLinks().size(), 1, "The map is expected to contain one entry.");
+        checkSameObject(response, response.addLink(linkKey, linkValue));
+        checkMapEntry(response.getLinks(), linkKey, linkValue);
+        assertEquals(response.getLinks().size(), 2, "The map is expected to contain two entries.");
+        
+        checkMapImmutable(response, APIResponse::getLinks, "otherLink", otherLinkValue);
         checkNullValueInAdd(response::getLinks, response::addLink, "someLinkKey", linkValue);
     }
     
@@ -712,40 +1101,31 @@ public class ModelConstructionTest {
     public void apiResponsesTest() {
         final APIResponses responses = processConstructible(APIResponses.class);
         
-        responses.remove(APIResponses.DEFAULT);
-        assertEquals(responses.size(), 0, "The map is expected to contain two entries.");
-        
         final String responseKey = "200";
-        assertFalse(responses.hasAPIResponse(responseKey), responseKey + " is absent in the map");
         final APIResponse pathItemValue = createConstructibleInstance(APIResponse.class);
-        checkSameObject(responses, responses.addAPIResponse(responseKey, pathItemValue));
+        responses.setAPIResponses(Collections.singletonMap(responseKey, pathItemValue));
         assertTrue(responses.hasAPIResponse(responseKey), responseKey + " is present in the map");
+        assertEquals(responses.getAPIResponses().size(), 1, "The map is expected to contain one entry.");
         assertSame(responses.getAPIResponse(responseKey), pathItemValue, 
                 "The value associated with the key: " + responseKey + " is expected to be the same one that was added.");
-        checkMapEntry(responses, responseKey, pathItemValue);
         checkMapEntry(responses.getAPIResponses(), responseKey, pathItemValue);
         
         final String responseKey2 = "4XX";
         assertFalse(responses.hasAPIResponse(responseKey2), responseKey2 + " is absent in the map");
         final APIResponse pathItemValue2 = createConstructibleInstance(APIResponse.class);
-        assertNull(responses.put(responseKey2, pathItemValue2), "No previous mapping expected.");
+        checkSameObject(responses, responses.addAPIResponse(responseKey2, pathItemValue2));
         assertTrue(responses.hasAPIResponse(responseKey2), responseKey2 + " is present in the map");
+        assertEquals(responses.getAPIResponses().size(), 2, "The map is expected to contain two entries.");
         assertSame(responses.getAPIResponse(responseKey2), pathItemValue2, 
                 "The value associated with the key: " + responseKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(responses, responseKey2, pathItemValue2);
         checkMapEntry(responses.getAPIResponses(), responseKey2, pathItemValue2);
         
-        assertEquals(responses.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(responses.getAPIResponses().size(), 2, "The map is expected to contain two entries.");
-        
         responses.removeAPIResponse(responseKey);
         assertFalse(responses.hasAPIResponse(responseKey), responseKey + " is absent in the map");
-        assertEquals(responses.size(), 1, "The map is expected to contain one entry.");
         assertEquals(responses.getAPIResponses().size(), 1, "The map is expected to contain one entry.");
         
-        responses.remove(responseKey2);
+        responses.removeAPIResponse(responseKey2);
         assertFalse(responses.hasAPIResponse(responseKey2), responseKey + " is absent in the map");
-        assertEquals(responses.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(responses.getAPIResponses().size(), 0, "The map is expected to contain 0 entries.");
         
         final APIResponse otherValue = createConstructibleInstance(APIResponse.class);
@@ -754,19 +1134,19 @@ public class ModelConstructionTest {
         assertNull(responses.getDefaultValue(), "No default value expected.");
         final String responseKey3 = APIResponses.DEFAULT;
         final APIResponse responseValue3 = createConstructibleInstance(APIResponse.class);
-        assertNull(responses.put(responseKey3, responseValue3), "No previous mapping expected.");
-        checkMapEntry(responses, responseKey3, responseValue3);
+        checkSameObject(responses, responses.addAPIResponse(responseKey3, responseValue3));
+        checkMapEntry(responses.getAPIResponses(), responseKey3, responseValue3);
         checkSameObject(responseValue3, responses.getDefaultValue());
         
-        assertEquals(responses.size(), 1, "The map is expected to contain one entry.");
+        assertEquals(responses.getAPIResponses().size(), 1, "The map is expected to contain one entry.");
         
         responses.setDefaultValue(null);
-        assertNull(responses.get(APIResponses.DEFAULT), "No default value expected.");
+        assertNull(responses.getAPIResponse(APIResponses.DEFAULT), "No default value expected.");
         assertNull(responses.getDefaultValue(), "No default value expected.");
         
         final APIResponse responseValue4 = createConstructibleInstance(APIResponse.class);
         responses.setDefaultValue(responseValue4);
-        checkMapEntry(responses, APIResponses.DEFAULT, responseValue4);
+        checkMapEntry(responses.getAPIResponses(), APIResponses.DEFAULT, responseValue4);
         checkSameObject(responseValue4, responses.getDefaultValue());
         
         checkNullValueInAdd(responses::getAPIResponses, responses::addAPIResponse, "4XX", otherValue);
@@ -787,36 +1167,30 @@ public class ModelConstructionTest {
         final Scopes s = processConstructible(Scopes.class);
         
         final String scopeKey = "myScope";
-        assertFalse(s.hasScope(scopeKey), scopeKey + " is absent in the map");
         final String scopeValue = new String("myDescription");
-        checkSameObject(s, s.addScope(scopeKey, scopeValue));
+        s.setScopes(Collections.singletonMap(scopeKey, scopeValue));
         assertTrue(s.hasScope(scopeKey), scopeKey + " is present in the map");
+        assertEquals(s.getScopes().size(), 1, "The map is expected to contain one entry.");
         assertSame(s.getScope(scopeKey), scopeValue, 
                 "The value associated with the key: " + scopeKey + " is expected to be the same one that was added.");
-        checkMapEntry(s, scopeKey, scopeValue);
         checkMapEntry(s.getScopes(), scopeKey, scopeValue);
         
         final String scopeKey2 = "myScope2";
         assertFalse(s.hasScope(scopeKey2), scopeKey2 + " is absent in the map");
         final String scopeValue2 = new String("myDescription2");
-        assertNull(s.put(scopeKey2, scopeValue2), "No previous mapping expected.");
+        checkSameObject(s, s.addScope(scopeKey2, scopeValue2));
         assertTrue(s.hasScope(scopeKey2), scopeKey2 + " is present in the map");
+        assertEquals(s.getScopes().size(), 2, "The map is expected to contain two entries.");
         assertSame(s.getScope(scopeKey2), scopeValue2, 
                 "The value associated with the key: " + scopeKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(s, scopeKey2, scopeValue2);
         checkMapEntry(s.getScopes(), scopeKey2, scopeValue2);
         
-        assertEquals(s.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(s.getScopes().size(), 2, "The map is expected to contain two entries.");
-        
         s.removeScope(scopeKey);
         assertFalse(s.hasScope(scopeKey), scopeKey + " is absent in the map");
-        assertEquals(s.size(), 1, "The map is expected to contain one entry.");
         assertEquals(s.getScopes().size(), 1, "The map is expected to contain one entry.");
         
-        s.remove(scopeKey2);
+        s.removeScope(scopeKey2);
         assertFalse(s.hasScope(scopeKey2), scopeKey + " is absent in the map");
-        assertEquals(s.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(s.getScopes().size(), 0, "The map is expected to contain 0 entries.");
         
         final String otherValue = new String("otherDescription");
@@ -833,36 +1207,30 @@ public class ModelConstructionTest {
         final SecurityRequirement sr = processConstructible(SecurityRequirement.class);
         
         final String schemeKey = "myScheme";
-        assertFalse(sr.hasScheme(schemeKey), schemeKey + " is absent in the map");
         final List<String> schemeValue = new ArrayList<String>();
-        checkSameObject(sr, sr.addScheme(schemeKey, schemeValue));
+        sr.setSchemes(Collections.singletonMap(schemeKey, schemeValue));
         assertTrue(sr.hasScheme(schemeKey), schemeKey + " is present in the map");
+        assertEquals(sr.getSchemes().size(), 1, "The map is expected to contain one entry.");
         assertSame(sr.getScheme(schemeKey), schemeValue, 
                 "The value associated with the key: " + schemeKey + " is expected to be the same one that was added.");
-        checkMapEntry(sr, schemeKey, schemeValue);
         checkMapEntry(sr.getSchemes(), schemeKey, schemeValue);
         
         final String schemeKey2 = "myScheme2";
         assertFalse(sr.hasScheme(schemeKey2), schemeKey2 + " is absent in the map");
         final List<String> schemeValue2 = new ArrayList<String>();
-        assertNull(sr.put(schemeKey2, schemeValue2), "No previous mapping expected.");
+        checkSameObject(sr, sr.addScheme(schemeKey2, schemeValue2));
         assertTrue(sr.hasScheme(schemeKey2), schemeKey2 + " is present in the map");
+        assertEquals(sr.getSchemes().size(), 2, "The map is expected to contain two entries.");
         assertSame(sr.getScheme(schemeKey2), schemeValue2, 
                 "The value associated with the key: " + schemeKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(sr, schemeKey2, schemeValue2);
         checkMapEntry(sr.getSchemes(), schemeKey2, schemeValue2);
         
-        assertEquals(sr.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(sr.getSchemes().size(), 2, "The map is expected to contain two entries.");
-        
         sr.removeScheme(schemeKey);
         assertFalse(sr.hasScheme(schemeKey), schemeKey + " is absent in the map");
-        assertEquals(sr.size(), 1, "The map is expected to contain one entry.");
         assertEquals(sr.getSchemes().size(), 1, "The map is expected to contain one entry.");
         
-        sr.remove(schemeKey2);
+        sr.removeScheme(schemeKey2);
         assertFalse(sr.hasScheme(schemeKey2), schemeKey + " is absent in the map");
-        assertEquals(sr.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(sr.getSchemes().size(), 0, "The map is expected to contain 0 entries.");
         
         final List<String> otherValue = new ArrayList<String>();
@@ -894,7 +1262,7 @@ public class ModelConstructionTest {
         
         final ServerVariable sv1 = createConstructibleInstance(ServerVariable.class);
         server.setVariables(Collections.singletonMap("var1", sv1));
-        Map<String,ServerVariable> variables = server.getVariables();
+        Map<String,ServerVariable> variables = server.getVariables().getServerVariables();
         assertEquals(variables.size(), 1, "The map is expected to contain one entry.");
         assertTrue(variables.containsKey("var1"), "The map is expected to contain a 'var1' entry.");
         assertEquals(variables.get("var1"), sv1, "The value corresponding to the 'var1' is wrong.");
@@ -913,6 +1281,17 @@ public class ModelConstructionTest {
         assertEquals(sv.getEnumeration().size(), 1, "The list is expected to contain one entry.");
         sv.removeEnumeration(enumeration);
         assertEquals(sv.getEnumeration().size(), 0, "The list is expected to be empty.");
+        
+        final String enumeration2 = new String("enumValue2");
+        sv.setEnumeration(Collections.singletonList(enumeration2));
+        assertEquals(sv.getEnumeration().size(), 1, "The list is expected to contain one entry.");
+        checkListEntry(sv.getEnumeration(), enumeration2);
+        checkSameObject(sv, sv.addEnumeration(enumeration));
+        assertEquals(sv.getEnumeration().size(), 2, "The list is expected to contain two entries.");
+        checkListEntry(sv.getEnumeration(), enumeration);
+        
+        final String otherEnumerationValue = new String("otherValue");
+        checkListImmutable(sv, ServerVariable::getEnumeration , otherEnumerationValue);
     }
     
     @Test
@@ -921,36 +1300,30 @@ public class ModelConstructionTest {
         final ServerVariables svs = processConstructible(ServerVariables.class);
         
         final String varKey = "myServerVariable";
-        assertFalse(svs.hasServerVariable(varKey), varKey + " is absent in the map");
         final ServerVariable varValue = createConstructibleInstance(ServerVariable.class);
-        checkSameObject(svs, svs.addServerVariable(varKey, varValue));
+        svs.setServerVariables(Collections.singletonMap(varKey, varValue));
         assertTrue(svs.hasServerVariable(varKey), varKey + " is present in the map");
+        assertEquals(svs.getServerVariables().size(), 1, "The map is expected to contain one entry.");
         assertSame(svs.getServerVariable(varKey), varValue, 
                 "The value associated with the key: " + varKey + " is expected to be the same one that was added.");
-        checkMapEntry(svs, varKey, varValue);
         checkMapEntry(svs.getServerVariables(), varKey, varValue);
         
         final String varKey2 = "myServerVariable2";
         assertFalse(svs.hasServerVariable(varKey2), varKey2 + " is absent in the map");
         final ServerVariable varValue2 = createConstructibleInstance(ServerVariable.class);
-        assertNull(svs.put(varKey2, varValue2), "No previous mapping expected.");
+        checkSameObject(svs, svs.addServerVariable(varKey2, varValue2));
         assertTrue(svs.hasServerVariable(varKey2), varKey2 + " is present in the map");
+        assertEquals(svs.getServerVariables().size(), 2, "The map is expected to contain two entries.");
         assertSame(svs.getServerVariable(varKey2), varValue2, 
                 "The value associated with the key: " + varKey2 + " is expected to be the same one that was added.");
-        checkMapEntry(svs, varKey2, varValue2);
         checkMapEntry(svs.getServerVariables(), varKey2, varValue2);
         
-        assertEquals(svs.size(), 2, "The map is expected to contain two entries.");
-        assertEquals(svs.getServerVariables().size(), 2, "The map is expected to contain two entries.");
-        
         svs.removeServerVariable(varKey);
         assertFalse(svs.hasServerVariable(varKey), varKey + " is absent in the map");
-        assertEquals(svs.size(), 1, "The map is expected to contain one entry.");
         assertEquals(svs.getServerVariables().size(), 1, "The map is expected to contain one entry.");
         
-        svs.remove(varKey2);
+        svs.removeServerVariable(varKey2);
         assertFalse(svs.hasServerVariable(varKey2), varKey + " is absent in the map");
-        assertEquals(svs.size(), 0, "The map is expected to contain 0 entries.");
         assertEquals(svs.getServerVariables().size(), 0, "The map is expected to contain 0 entries.");
         
         final ServerVariable otherValue = createConstructibleInstance(ServerVariable.class);
@@ -1015,12 +1388,16 @@ public class ModelConstructionTest {
         assertEquals(map2.size(), 0, "The extensions map is expected to contain no entries.");
         assertEquals(map2, newMap, "The return value of getExtensions() is expected to be the same value that was set.");
         // Check that the extension map can be replaced with the builder method and that it is returned by the getter.
-        final Map<String, Object> newOtherMap = new HashMap<>();
-        newOtherMap.put("x-test", 42);
+        final Map<String, Object> newOtherMap = Collections.singletonMap("x-test", 42);
         e.setExtensions(newOtherMap);
         final Map<String, Object> map3 = e.getExtensions();
         assertEquals(map3.size(), 1, "The extensions map is expected to contain one entry.");
         assertEquals(map3, newOtherMap, "The return value of getExtensions() is expected to be the same value that was set.");
+        // Check that a value can be added, even if the map was immutable
+        e.addExtension(extensionName1, obj1);
+        assertEquals(e.getExtensions().size(), 2, "The extensions map is expected to contain two entries.");
+
+        checkMapImmutable(e, Extensible::getExtensions, "x-other", new Object());
     }
     
     private void processReference(Reference<?> r) {
@@ -1240,7 +1617,7 @@ public class ModelConstructionTest {
         assertTrue(map.containsKey(key), "The map is expected to contain the key: " + key);
         assertSame(map.get(key), value, "The value associated with the key: " + key + " is expected to be the same one that was added.");
     }
-
+    
     private <O, K, T> void checkMapImmutable(O container, Function<O, Map<K,T>> mapGetter, K key, T otherValue) {
         Map<K,T> map = mapGetter.apply(container);
         assertNotNull(map, "The map must not be null.");
@@ -1287,6 +1664,23 @@ public class ModelConstructionTest {
         assertTrue(list.stream().anyMatch((v) -> v == value), "The list is expected to contain the value: " + value);
     }
     
+    private <O, V> void checkListImmutable(O container, Function<O, List<V>> listGetter, V otherValue) {
+        List<V> list = listGetter.apply(container);
+        assertNotNull(list, "The list must not be null.");
+        assertFalse(list.contains(otherValue), "The list is expected to not contain the value: " + otherValue);
+        int originalSize = list.size();
+        try {
+            list.add(otherValue);
+        }
+        catch (Exception e) {
+            //It is allowed to throw an exception
+        }
+        List<V>  map2 = listGetter.apply(container);
+        assertNotNull(map2, "The list must not be null.");
+        assertFalse(map2.contains(otherValue), "The list is expected to not contain the key: " + otherValue);
+        assertEquals(map2.size(), originalSize, "The list is expected to have a size of " + originalSize);
+    }
+    
     private <T> void checkSameObject(T expected, T actual) {
         assertSame(actual, expected ,"Expecting same object.");
     }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassTest.java
index 4abae6b..16fc9d0 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigScanClassTest.java
@@ -16,20 +16,11 @@
 
 package org.eclipse.microprofile.openapi.tck;
 
-import static org.hamcrest.Matchers.hasKey;
-import static org.hamcrest.Matchers.startsWith;
-import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
-
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.container.test.api.RunAsClient;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.testng.annotations.Test;
-
-import io.restassured.response.ValidatableResponse;
 
-public class OASConfigScanClassTest extends AppTestBase {
-    private ValidatableResponse vr;
+public class OASConfigScanClassTest extends OASConfigScanClassBase {
     
     @Deployment(name = "airlines")
     public static WebArchive createDeployment() {
@@ -37,25 +28,5 @@ public class OASConfigScanClassTest extends AppTestBase {
                 .addPackages(true, "org.eclipse.microprofile.openapi.apps.airlines")
                 .addAsManifestResource("class-microprofile-config.properties", "microprofile-config.properties");
     }
-    
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testScanClass(String type) throws InterruptedException {
-        vr = callEndpoint(type);
-        vr.body("openapi", startsWith("3.0."));
-        vr.body("paths", aMapWithSize(5));
-        vr.body("paths", hasKey("/reviews"));
-        vr.body("paths", hasKey("/reviews/{id}"));
-        vr.body("paths", hasKey("/reviews/users/{user}"));
-        vr.body("paths", hasKey("/reviews/airlines/{airline}"));
-        vr.body("paths", hasKey("/reviews/{user}/{airlines}"));
-        
-        vr.body("paths.'/reviews'", aMapWithSize(2));
-        vr.body("paths.'/reviews/{id}'", aMapWithSize(2)); 
-        vr.body("paths.'/reviews/users/{user}'", aMapWithSize(1));
-        vr.body("paths.'/reviews/airlines/{airline}'", aMapWithSize(1)); 
-        vr.body("paths.'/reviews/{user}/{airlines}'", aMapWithSize(1)); 
-        
-        
-    }
+
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigWebInfTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigWebInfTest.java
index 17776f9..fceeb6d 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigWebInfTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASConfigWebInfTest.java
@@ -20,9 +20,9 @@ import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
 
-public class OASConfigWebInfTest extends OASConfigScanClassTest {
+public class OASConfigWebInfTest extends OASConfigScanClassBase {
 
-    @Deployment(name = "airlinesWebInf", order = 2)
+    @Deployment(name = "airlinesWebInf")
     public static WebArchive createDeployment() {
         return ShrinkWrap.create(WebArchive.class, "airlinesWebInf.war")
                 .addPackages(true, "org.eclipse.microprofile.openapi.apps.airlines")