Repository: eclipse/microprofile-open-api
Pull request #151 (2017-12-12 02:31:05)

Updating authors
Updating list of authors.

@navidsh - can you please review this one?

Signed-off-by: Arthur De Magalhaes <ademagalhaes@gmail.com>


Patch:
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/OASFilter.java b/api/src/main/java/org/eclipse/microprofile/openapi/OASFilter.java
index a848704..ab6b599 100644
--- a/api/src/main/java/org/eclipse/microprofile/openapi/OASFilter.java
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/OASFilter.java
@@ -40,6 +40,7 @@ import org.eclipse.microprofile.openapi.models.tags.Tag;
  * The value is the fully qualified name of the filter implementation, which needs to be visible to the application's classloader.
  *
  */
+@SuppressWarnings("rawtypes")
 public interface OASFilter {    
 
     /** 
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 6a784dd..e56a2a5 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
@@ -49,6 +49,7 @@ import org.eclipse.microprofile.openapi.models.security.SecurityScheme;
  * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject"> OpenAPI Specification Components
  *      Object</a>
  */
+@SuppressWarnings("rawtypes")
 public interface Components extends Constructible, Extensible {
 
     /**
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 33b8433..12c5eff 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
@@ -36,6 +36,7 @@ import org.eclipse.microprofile.openapi.models.servers.Server;
  * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject">OpenAPI Specification Operation
  *      Object</a>
  */
+@SuppressWarnings("rawtypes")
 public interface Operation extends Constructible, Extensible {
 
     /**
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 c0bde3e..fa221e9 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
@@ -34,6 +34,7 @@ import org.eclipse.microprofile.openapi.models.servers.Server;
  * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject"> OpenAPI Specification Path Item
  *      Object</a>
  */
+@SuppressWarnings("rawtypes")
 public interface PathItem extends Constructible, Extensible, Reference<PathItem> {
 
     /**
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/CookieParameter.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/CookieParameter.java
new file mode 100644
index 0000000..5387db0
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/CookieParameter.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2017 Contributors to the Eclipse Foundation
+ * Copyright 2017 SmartBear Software
+ * <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.models.parameters;
+
+import org.eclipse.microprofile.openapi.models.Constructible;
+
+/**
+ * CookieParameter
+ * <p>
+ * A cookie parameter is a {@link Parameter Parameter} where the "in" property has the value "cookie."
+ * 
+ * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject">OpenAPI Specification Parameter
+ *      Object</a>
+ */
+public interface CookieParameter extends Constructible, Parameter<CookieParameter> {
+
+}
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/HeaderParameter.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/HeaderParameter.java
new file mode 100644
index 0000000..7cd19e5
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/HeaderParameter.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2017 Contributors to the Eclipse Foundation
+ * Copyright 2017 SmartBear Software
+ * <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.models.parameters;
+
+import org.eclipse.microprofile.openapi.models.Constructible;
+
+/**
+ * HeaderParameter
+ * <p>
+ * A header parameter is a {@link Parameter Parameter} where the "in" property has the value "header."
+ * 
+ * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject">OpenAPI Specification Parameter
+ *      Object</a>
+ */
+public interface HeaderParameter extends Constructible, Parameter<HeaderParameter> {
+
+}
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 eff0833..03acfe5 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
@@ -19,7 +19,6 @@ package org.eclipse.microprofile.openapi.models.parameters;
 
 import java.util.Map;
 
-import org.eclipse.microprofile.openapi.models.Constructible;
 import org.eclipse.microprofile.openapi.models.Extensible;
 import org.eclipse.microprofile.openapi.models.Reference;
 import org.eclipse.microprofile.openapi.models.examples.Example;
@@ -31,8 +30,7 @@ import org.eclipse.microprofile.openapi.models.media.Schema;
  * <p>
  * Describes a single operation parameter.
  * <p>
- * A unique parameter is defined by a combination of a name and location. There are four possible parameter locations
- * specified by the <code>in</code> field:
+ * A unique parameter is defined by a combination of a name and location. There are four possible parameter locations specified by the in field:
  * <ul>
  * <li>path - Used together with Path Templating, where the parameter value is actually part of the operation's URL. This does not include the host or
  * base path of the API. For example, in /items/{itemId}, the path parameter is itemId.</li>
@@ -50,7 +48,7 @@ import org.eclipse.microprofile.openapi.models.media.Schema;
  * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject">OpenAPI Specification Parameter
  *      Object</a>
  */
-public interface Parameter extends Constructible, Extensible, Reference<Parameter> {
+public interface Parameter<T extends Parameter<T>> extends Extensible, Reference<T> {
 
     /**
      * The values allowed for the style field.
@@ -70,7 +68,6 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
             return String.valueOf(value);
         }
     }
-    
     /**
      * The values allowed for the in field.
      */
@@ -88,7 +85,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
             return String.valueOf(value);
         }
     }
-    
+
     /**
      * Returns the name property from a Parameter instance.
      *
@@ -109,7 +106,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param name the name of the parameter
      * @return the current Parameter instance
      */
-    Parameter name(String name);
+    T name(String name);
 
     /**
      * Returns the in property from a Parameter instance.
@@ -117,21 +114,6 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @return the location of the parameter
      **/
     In getIn();
-    
-    /**
-     * Sets the in property of a Parameter instance to the given value.
-     *
-     * @param in the value of the in property
-     */
-    void setIn(In in);
-    
-    /**
-     * Sets the in property of a Parameter instance to the given value.
-     *
-     * @param in the value of the in property
-     * @return the current Parameter instance
-     */
-    Parameter in(In in);
 
     /**
      * Returns the description property from a Parameter instance.
@@ -153,7 +135,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param description a brief description of the parameter
      * @return the current Parameter instance
      */
-    Parameter description(String description);
+    T description(String description);
 
     /**
      * Returns the required property from a Parameter instance.
@@ -175,7 +157,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param required indicates whether this parameter is mandatory
      * @return the current Parameter instance
      */
-    Parameter required(Boolean required);
+    T required(Boolean required);
 
     /**
      * Returns the deprecated property from a Parameter instance.
@@ -197,7 +179,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param deprecated specifies that a parameter is deprecated
      * @return the current Parameter instance
      */
-    Parameter deprecated(Boolean deprecated);
+    T deprecated(Boolean deprecated);
 
     /**
      * Returns the allowEmptyValue property from a Parameter instance.
@@ -219,7 +201,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param allowEmptyValue specify the ability to pass empty-valued parameters
      * @return the current Parameter instance
      */
-    Parameter allowEmptyValue(Boolean allowEmptyValue);
+    T allowEmptyValue(Boolean allowEmptyValue);
 
     /**
      * Returns the style property from a Parameter instance.
@@ -241,7 +223,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param style describes how the parameter value will be serialized
      * @return the current Parameter instance
      */
-    Parameter style(Parameter.Style style);
+    T style(Parameter.Style style);
 
     /**
      * Returns the explode property from a Parameter instance.
@@ -263,7 +245,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param explode whether parameter values of type "array" or "object" generate separate parameters for each value
      * @return the current Parameter instance
      */
-    Parameter explode(Boolean explode);
+    T explode(Boolean explode);
 
     /**
      * Returns the allowReserved property from a Parameter instance.
@@ -285,7 +267,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param allowReserved specifies whether the parameter value should allow reserved characters
      * @return the current Parameter instance
      */
-    Parameter allowReserved(Boolean allowReserved);
+    T allowReserved(Boolean allowReserved);
 
     /**
      * Returns the schema property from a Parameter instance.
@@ -307,7 +289,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param schema schema defining the type used for the parameter
      * @return the current Parameter instance
      */
-    Parameter schema(Schema schema);
+    T schema(Schema schema);
 
     /**
      * Returns the examples property from a Parameter instance.
@@ -331,7 +313,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param examples examples of the media type
      * @return the current Parameter instance
      */
-    Parameter examples(Map<String, Example> examples);
+    T examples(Map<String, Example> examples);
 
     /**
      * Adds an example of the media type using the specified key. The example should contain a value in the correct format as specified in the
@@ -341,7 +323,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param example example of the media type
      * @return the current Parameter instance
      */
-    Parameter addExample(String key, Example example);
+    T addExample(String key, Example example);
 
     /**
      * Returns the example property from a Parameter instance.
@@ -365,7 +347,7 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param example example of the media type
      * @return the current Parameter instance
      */
-    Parameter example(Object example);
+    T example(Object example);
 
     /**
      * Returns the content property from a Parameter instance.
@@ -387,6 +369,6 @@ public interface Parameter extends Constructible, Extensible, Reference<Paramete
      * @param content a map containing the media representations for the parameter
      * @return the current Parameter instance
      */
-    Parameter content(Content content);
+    T content(Content content);
 
 }
\ No newline at end of file
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/PathParameter.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/PathParameter.java
new file mode 100644
index 0000000..71fa5b6
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/PathParameter.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2017 Contributors to the Eclipse Foundation
+ * Copyright 2017 SmartBear Software
+ * <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.models.parameters;
+
+import org.eclipse.microprofile.openapi.models.Constructible;
+
+/**
+ * PathParameter
+ * <p>
+ * A path parameter is a {@link Parameter Parameter} where the "in" property has the value "path."
+ * 
+ * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject">OpenAPI Specification Parameter
+ *      Object</a>
+ */
+public interface PathParameter extends Constructible, Parameter<PathParameter> {
+
+}
diff --git a/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/QueryParameter.java b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/QueryParameter.java
new file mode 100644
index 0000000..e81eae8
--- /dev/null
+++ b/api/src/main/java/org/eclipse/microprofile/openapi/models/parameters/QueryParameter.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2017 Contributors to the Eclipse Foundation
+ * Copyright 2017 SmartBear Software
+ * <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.models.parameters;
+
+import org.eclipse.microprofile.openapi.models.Constructible;
+
+/**
+ * QueryParameter
+ * <p>
+ * A query parameter is a {@link Parameter Parameter} where the "in" property has the value "query."
+ * 
+ * @see <a href= "https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject">OpenAPI Specification Parameter
+ *      Object</a>
+ */
+public interface QueryParameter extends Constructible, Parameter<QueryParameter> {
+
+}
diff --git a/spec/src/main/asciidoc/microprofile-openapi-spec.adoc b/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
index c618fd4..8110706 100644
--- a/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
+++ b/spec/src/main/asciidoc/microprofile-openapi-spec.adoc
@@ -17,8 +17,8 @@
 // limitations under the License.
 //
 
-:authors: Arthur De Magalhaes (Spec Lead), Leo Christy Jesuraj, Eric Wittmann
-:email: ademagalhaes@gmail.com, leo.jesuraj@gmail.com, eric.wittmann@gmail.com
+: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
@@ -332,10 +332,10 @@ post:
     requestBody:
       description: Created user object
       content:
-        '*/*':
-          schema:
-            $ref: '#/components/schemas/User'
-            required: true
+       '*/*':
+        schema:
+          $ref: '#/components/schemas/User'
+          required: true
     responses:
       default:
         description: no description
@@ -657,7 +657,7 @@ from the current model.
 == OpenAPI Endpoint
 
 === Overview
-A fully processed OpenAPI document must be available at the root
+A fully processed and valid OpenAPI document must be available at the root
 URL `/openapi`, as a `HTTP GET` operation.
 
 For example, `GET http://myHost:myPort/openapi`.
@@ -673,7 +673,7 @@ The default format of the `/openapi` endpoint is `YAML`.
 
 Vendors must also support the `JSON` format if the request contains an `Accept`
 header with a value of `application/json`, in which case the response must contain
-a `Content-Type` header with a value of `application/json`.
+a `Content-Type` header with value of `application/json`.
 
 === Query parameters
 No query parameters are required for the `/openapi` endpoint.  However, one
diff --git a/tck/pom.xml b/tck/pom.xml
index ae23ba9..d63ccdc 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -88,15 +88,15 @@
         </dependency>
 
         <dependency>
-            <groupId>org.testng</groupId>
-            <artifactId>testng</artifactId>
-            <version>6.9.9</version>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
             <scope>compile</scope>
         </dependency>
 
         <dependency>
-            <groupId>org.jboss.arquillian.testng</groupId>
-            <artifactId>arquillian-testng-container</artifactId>
+            <groupId>org.jboss.arquillian.junit</groupId>
+            <artifactId>arquillian-junit-container</artifactId>
             <scope>compile</scope>
         </dependency>
 
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
index 11285f4..b58ca58 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
@@ -103,7 +103,6 @@ import org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource;
                         schema = @Schema(type = SchemaType.STRING), required = true) }, 
                 examples = {
                         @ExampleObject(name = "review", summary = "External review example", 
-                                description = "This example exemplifies the content on our site.",
                                 externalValue = "http://foo.bar/examples/review-example.json"),
                         @ExampleObject(name = "user", summary = "External user example", 
                                 externalValue = "http://foo.bar/examples/user-example.json") }, 
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/model/Order.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/model/Order.java
index e88ada9..45840db 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/model/Order.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/model/Order.java
@@ -16,14 +16,10 @@ package org.eclipse.microprofile.openapi.apps.petstore.model;
 import java.util.Date;
 
 import javax.xml.bind.annotation.XmlRootElement;
-
-import org.eclipse.microprofile.openapi.annotations.media.Schema;
-
 import javax.xml.bind.annotation.XmlElement;
 
 @XmlRootElement(name = "Order")
 public class Order {
-    @Schema(required = true) // discriminator
     private long id;
     private long petId;
     private int quantity;
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetResource.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetResource.java
index 2ce4ccc..766507d 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetResource.java
@@ -355,6 +355,7 @@ public class PetResource {
             },
             allowEmptyValue = true)
         @Extension(name = "x-mp-parm1", value = "true")
+        @Extensions( { @Extension(name = "x-mp-parm2", value = "true"), @Extension(value = "false", name = "x-mp-parm3") } )
         String status) {
                 return Response.ok(petData.findPetByStatus(status)).build();
             }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetStoreResource.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetStoreResource.java
index 756916b..284daf2 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetStoreResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/petstore/resource/PetStoreResource.java
@@ -20,7 +20,6 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema;
 import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
 import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
 import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType;
-import org.eclipse.microprofile.openapi.annotations.extensions.Extension;
 import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme;
 import org.eclipse.microprofile.openapi.annotations.security.SecuritySchemes;
 import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement;
@@ -72,8 +71,6 @@ import javax.ws.rs.Produces;
         )
     }
 )
-@Extension(name = "x-mp-type1", value = "true")
-@Extension(name = "x-mp-type2", value = "false")
 public class PetStoreResource {
     static StoreData storeData = new StoreData();
     static PetData petData = new PetData();


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/AppTestBase.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/AppTestBase.java
deleted file mode 100644
index 3be3603..0000000
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/AppTestBase.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright (c) 2017 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 io.restassured.RestAssured.given;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.lang3.StringUtils;
-import org.eclipse.microprofile.openapi.tck.utils.YamlToJsonConverterServlet;
-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;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.DataProvider;
-
-import io.restassured.RestAssured;
-import io.restassured.parsing.Parser;
-import io.restassured.response.ValidatableResponse;
-
-public abstract class AppTestBase extends Arquillian {
-    private static final String APPLICATION_JSON = "application/json";
-
-    private static final String DEFAULT_PROTOCOL = "http";
-    private static final String DEFAULT_HOST = "localhost";
-    private static final int DEFAULT_PORT = 9080;
-
-    private static String serverUrl;
-    private static String username;
-    private static String password;
-    private static Map<String, String> headers = new HashMap<>();
-
-    @Deployment(name = "proxy")
-    public static WebArchive createProxy() {
-        return ShrinkWrap.create(WebArchive.class, "proxy.war")
-                .addClass(YamlToJsonConverterServlet.class)
-                .addAsLibraries(new File("./lib/httpclient-4.5.2.jar"))
-                .addAsLibraries(new File("./lib/httpcore-4.4.4.jar"))
-                .addAsLibraries(new File("./lib/jackson-core-2.9.2.jar"))
-                .addAsLibraries(new File("./lib/jackson-dataformat-yaml-2.9.2.jar"))
-                .addAsLibraries(new File("./lib/jackson-databind-2.9.2.jar"))
-                .addAsLibraries(new File("./lib/jackson-annotations-2.9.1.jar"))
-                .addAsLibraries(new File("./lib/snakeyaml-1.18.jar"))
-                .addAsLibraries(new File("./lib/commons-logging-1.2.jar"))
-                .addAsLibraries(new File("./lib/commons-lang3-3.4.jar"));
-    }
-
-    @BeforeClass
-    public static void setUp() throws MalformedURLException {
-        // set base URI and port number to use for all requests
-        serverUrl = System.getProperty("test.url");
-        String protocol = DEFAULT_PROTOCOL;
-        String host = DEFAULT_HOST;
-        int port = DEFAULT_PORT;
-
-        if (serverUrl != null) {
-            URL url = new URL(serverUrl);
-            protocol = url.getProtocol();
-            host = url.getHost();
-            port = (url.getPort() == -1) ? DEFAULT_PORT : url.getPort();
-        }
-
-        RestAssured.baseURI = protocol + "://" + host;
-        RestAssured.port = port;
-
-        username = System.getProperty("test.user");
-        password = System.getProperty("test.pwd");
-
-        if (username != null && password != null) {
-            RestAssured.authentication = RestAssured.basic(username, password);
-            RestAssured.useRelaxedHTTPSValidation();
-        }
-        RestAssured.defaultParser = Parser.JSON;
-
-        if (StringUtils.isBlank(serverUrl)) {
-            serverUrl = DEFAULT_PROTOCOL + "://" + DEFAULT_HOST + ":" + DEFAULT_PORT;
-        }
-        headers.put(YamlToJsonConverterServlet.TCK_HEADER_SERVERURL, serverUrl);
-        if (StringUtils.isNotBlank(username)) {
-            headers.put(YamlToJsonConverterServlet.TCK_HEADER_USERNAME, username);
-        }
-        if (StringUtils.isNotBlank(password)) {
-            headers.put(YamlToJsonConverterServlet.TCK_HEADER_PASSWORD, password);
-        }
-    }
-
-    public ValidatableResponse callEndpoint(String type) {
-        ValidatableResponse vr;
-        if ("JSON".equals(type)) {
-            vr = given().accept(APPLICATION_JSON).when().get("/openapi").then().statusCode(200);
-        }
-        else {
-            vr = given().headers(headers).when().get("/proxy").then().statusCode(200);
-        }
-        return vr;
-    }
-
-    @DataProvider(name = "formatProvider")
-    public Object[][] provide() throws Exception {
-        return new Object[][] { { "JSON" }, { "YAML" } };
-    }
-}
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/AirlinesAppTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
similarity index 54%
rename from tck/src/main/java/org/eclipse/microprofile/openapi/tck/AirlinesAppTest.java
rename to tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
index 15a492c..7018451 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/AirlinesAppTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
@@ -16,12 +16,14 @@
 
 package org.eclipse.microprofile.openapi.tck;
 
+import static io.restassured.RestAssured.given;
 import static org.hamcrest.Matchers.both;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.either;
+import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.hasKey;
@@ -30,18 +32,99 @@ import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
 
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.microprofile.openapi.tck.utils.YamlToJsonConverterServlet;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.testng.annotations.Test;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+import io.restassured.RestAssured;
+import io.restassured.parsing.Parser;
 import io.restassured.response.ValidatableResponse;
 
-public class AirlinesAppTest extends AppTestBase {
+@RunWith(Arquillian.class)
+public class EndpointTest {
+    private static final String APPLICATION_JSON = "application/json";
+    private static final String APPLICATION_YAML = "application/yaml";
+
+    private static final String DEFAULT_PROTOCOL = "http";
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int DEFAULT_PORT = 9080;
+
+    private static ValidatableResponse vr;
+    private static String serverUrl;
+    private static String username;
+    private static String password;
+    private static Map<String, String> headers = new HashMap<>();
+
+    @BeforeClass
+    public static void setUp() throws MalformedURLException {
+        // set base URI and port number to use for all requests
+        serverUrl = System.getProperty("test.url");
+        String protocol = DEFAULT_PROTOCOL;
+        String host = DEFAULT_HOST;
+        int port = DEFAULT_PORT;
+
+        if (serverUrl != null) {
+            URL url = new URL(serverUrl);
+            protocol = url.getProtocol();
+            host = url.getHost();
+            port = (url.getPort() == -1) ? DEFAULT_PORT : url.getPort();
+        }
+
+        RestAssured.baseURI = protocol + "://" + host;
+        RestAssured.port = port;
+
+        username = System.getProperty("test.user");
+        password = System.getProperty("test.pwd");
+
+        if (username != null && password != null) {
+            RestAssured.authentication = RestAssured.basic(username, password);
+            RestAssured.useRelaxedHTTPSValidation();
+        }
+        RestAssured.defaultParser = Parser.JSON;
+        
+        if (StringUtils.isBlank(serverUrl)) {
+            serverUrl = DEFAULT_PROTOCOL + "://" + DEFAULT_HOST + ":" + DEFAULT_PORT;
+        }
+        headers.put(YamlToJsonConverterServlet.TCK_HEADER_SERVERURL, serverUrl);
+        if (StringUtils.isNotBlank(username)) {
+            headers.put(YamlToJsonConverterServlet.TCK_HEADER_USERNAME, username);
+        }
+        if (StringUtils.isNotBlank(password)) {
+            headers.put(YamlToJsonConverterServlet.TCK_HEADER_PASSWORD, password);
+        }
+    }
+
+    @Deployment(name = "proxy")
+    public static WebArchive createProxy() {
+        return ShrinkWrap.create(WebArchive.class, "proxy.war")
+                .addClass(YamlToJsonConverterServlet.class)
+                .addAsLibraries(new File("./lib/httpclient-4.5.2.jar"))
+                .addAsLibraries(new File("./lib/httpcore-4.4.4.jar"))
+                .addAsLibraries(new File("./lib/jackson-core-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-dataformat-yaml-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-databind-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-annotations-2.9.1.jar"))
+                .addAsLibraries(new File("./lib/snakeyaml-1.18.jar"))
+                .addAsLibraries(new File("./lib/commons-logging-1.2.jar"))
+                .addAsLibraries(new File("./lib/commons-lang3-3.4.jar"));
+    }
+
     @Deployment(name = "airlines")
     public static WebArchive createDeployment() {
         return ShrinkWrap.create(WebArchive.class, "airlines.war")
@@ -49,51 +132,50 @@ public class AirlinesAppTest extends AppTestBase {
                 .addAsManifestResource("openapi.yaml", "openapi/openapi.yaml");
     }
 
+    @Before
+    public void setUpTest() {
+        vr = given().headers(headers).when().get("/proxy").then().statusCode(200);
+    }
+
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testVersion(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testVersion() {
         vr.body("openapi", equalTo("3.0.0"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testInfo(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testInfo() {
         vr.body("info.title", equalTo("AirlinesRatingApp API"));
         vr.body("info.version", equalTo("1.0"));
         vr.body("info.termsOfService", equalTo("http://airlinesratingapp.com/terms"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testContact(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testContact() {
         vr.body("info.contact.name", equalTo("AirlinesRatingApp API Support"));
         vr.body("info.contact.url", equalTo("http://exampleurl.com/contact"));
         vr.body("info.contact.email", equalTo("techsupport@airlinesratingapp.com"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testLicense(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testLicense() {
         vr.body("info.license.name", equalTo("Apache 2.0"));
         vr.body("info.license.url", equalTo("http://www.apache.org/licenses/LICENSE-2.0.html"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testExternalDocumentation(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testExternalDocumentation() {
         vr.body("externalDocs.description", equalTo("instructions for how to deploy this app"));
         vr.body("externalDocs.url", containsString("README.md"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testServer(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testServer() {
         vr.body("servers", hasSize(2));
         vr.body("servers.url", hasSize(2));
 
@@ -127,14 +209,15 @@ public class AirlinesAppTest extends AppTestBase {
         url = "http://gigantic-server.com:80";
         serverPath = "paths.'/reviews/{id}'.delete.servers.find { it.url == '" + url + "' }";
         vr.body(serverPath + ".description", equalTo("Unsecure server"));
-        vr.body(serverPath + ".variables", not(hasSize(greaterThan(0))));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
 
         url = "{protocol}://test-server.com";
         serverPath = "paths.'/reviews/{id}'.delete.servers.find { it.url == '" + url + "' }";
         vr.body(serverPath + ".description", equalTo("The production API server"));
         vr.body(serverPath + ".variables", aMapWithSize(1));
-        vr.body(serverPath + ".variables.protocol.default", equalTo("https"));
-        vr.body(serverPath + ".variables.protocol.enum", containsInAnyOrder("http", "https"));
+        vr.body(serverPath + ".variables.proxyPath.description", equalTo("Base path of the proxy"));
+        vr.body(serverPath + ".variables.proxyPath.default", equalTo("http"));
+        vr.body(serverPath + ".variables.proxyPath.enum", containsInAnyOrder("http", "https"));
 
         // Testing two @Server defined in an @operation annotation on a method
         // org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource.createReview(Review)
@@ -155,37 +238,34 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.'/bookings'.get.servers", hasSize(2));
         vr.body("paths.'/bookings'.get.servers.url", hasSize(2));
 
-        url = "http://gigantic-server.com:80";
+        url = "https://gigantic-server.com:80";
         serverPath = "paths.'/bookings'.get.servers.find { it.url == '" + url + "' }";
-        vr.body(serverPath + ".description", equalTo("Unsecure server"));
-        vr.body(serverPath + ".variables", not(hasSize(greaterThan(0))));
+        vr.body(serverPath + ".description", equalTo("Secure server"));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
 
         url = "https://gigantic-server.com:443";
         serverPath = "paths.'/bookings'.get.servers.find { it.url == '" + url + "' }";
-        vr.body(serverPath + ".description", equalTo("Secure server"));
-        vr.body(serverPath + ".variables", not(hasSize(greaterThan(0))));
+        vr.body(serverPath + ".description", equalTo("Unsecure server"));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOperationAirlinesResource(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOperationAirlinesResource() {
         vr.body("paths.'/'.get.summary", equalTo("Retrieve all available airlines"));
         vr.body("paths.'/'.get.operationId", equalTo("getAirlines"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOperationAvailabilityResource(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOperationAvailabilityResource() {
         vr.body("paths.'/availability'.get.summary", equalTo("Retrieve all available flights"));
         vr.body("paths.'/availability'.get.operationId", equalTo("getFlights"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOperationBookingResource(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOperationBookingResource() {
         vr.body("paths.'/bookings'.get.summary", equalTo("Retrieve all bookings for current user"));
         vr.body("paths.'/bookings'.get.operationId", equalTo("getAllBookings"));
 
@@ -203,10 +283,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.'/bookings/{id}'.delete.operationId", equalTo("deleteBookingById"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOperationReviewResource(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOperationReviewResource() {
         vr.body("paths.'/reviews'.get.summary", equalTo("get all the reviews"));
         vr.body("paths.'/reviews'.get.operationId", equalTo("getAllReviews"));
 
@@ -229,10 +308,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.'/reviews/{user}/{airlines}'.get.operationId", equalTo("getReviewByAirlineAndUser"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOperationUserResource(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOperationUserResource() {
         vr.body("paths.'/user'.post.summary", equalTo("Create user"));
         vr.body("paths.'/user'.post.description", equalTo("This can only be done by the logged in user."));
         vr.body("paths.'/user'.post.operationId", equalTo("createUser"));
@@ -264,54 +342,16 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.'/user/logout'.get.operationId", equalTo("logOutUser"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testAPIResponse(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        // @APIResponse at method level
-        vr.body("paths.'/availability'.get.responses", aMapWithSize(2));
-        vr.body("paths.'/availability'.get.responses.'200'.description", equalTo("successful operation"));
-        vr.body("paths.'/availability'.get.responses.'404'.description", equalTo("No available flights found"));
-
-        vr.body("paths.'/bookings'.post.responses", aMapWithSize(1));
-        vr.body("paths.'/bookings'.post.responses.'201'.description", equalTo("Booking created"));
-
-        vr.body("paths.'/user/{username}'.delete.responses", aMapWithSize(3));
-        vr.body("paths.'/user/{username}'.delete.responses.'200'.description", equalTo("User deleted successfully"));
-        vr.body("paths.'/user/{username}'.delete.responses.'400'.description", equalTo("Invalid username supplied"));
-        vr.body("paths.'/user/{username}'.delete.responses.'404'.description", equalTo("User not found"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testAPIResponses(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        // @APIResponse annotations nested within @APIResponses
-        vr.body("paths.'/bookings/{id}'.get.responses", aMapWithSize(2));
-        vr.body("paths.'/bookings/{id}'.get.responses.'200'.description", equalTo("Booking retrieved"));
-        vr.body("paths.'/bookings/{id}'.get.responses.'404'.description", equalTo("Booking not found"));
-
-        vr.body("paths.'/reviews/{user}'.get.responses", aMapWithSize(2));
-        vr.body("paths.'/reviews/{user}'.get.responses.'200'.description", equalTo("Review(s) retrieved"));
-        vr.body("paths.'/reviews/{user}'.get.responses.'404'.description", equalTo("Review(s) not found"));
-
-        vr.body("paths.'/user/{username}'.put.responses", aMapWithSize(3));
-        vr.body("paths.'/user/{username}'.put.responses.'200'.description", equalTo("User updated successfully"));
-        vr.body("paths.'/user/{username}'.put.responses.'400'.description", equalTo("Invalid user supplied"));
-        vr.body("paths.'/user/{username}'.put.responses.'404'.description", equalTo("User not found"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testParameter(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testParameter() throws InterruptedException {
         testAvailabilityGetParamater(vr);
         testBookingIdMethods(vr);
         testReviewIdMethods(vr);
         testUserLoginMethods(vr);
     }
 
-    private void testUserLoginMethods(ValidatableResponse vr) {
+    private void testUserLoginMethods(ValidatableResponse vr2) {
         String reviewParameters = "paths.'/user/login'.get.parameters";
         vr.body(reviewParameters, hasSize(2));
         vr.body(reviewParameters + ".findAll { it }.name", hasItems("username", "password"));
@@ -330,7 +370,7 @@ public class AirlinesAppTest extends AppTestBase {
         }
     }
 
-    private void testReviewIdMethods(ValidatableResponse vr) {
+    private void testReviewIdMethods(ValidatableResponse vr2) {
         String reviewParameters = "paths.'/reviews/{id}'.get.parameters";
         vr.body(reviewParameters, hasSize(1));
         vr.body(reviewParameters + ".findAll { it }.name", contains("id"));
@@ -385,89 +425,66 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(availabilityParameters + ".findAll { it.name == 'numberOfChildren' }.schema.minimum", both(hasSize(1)).and(contains(0)));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testExplode(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testExplode() throws InterruptedException {
         String explode = "paths.'/user/{username}'.put.responses.'200'.content.'application/xml'.encoding.password.explode";
         vr.body(explode, equalTo(true));
         explode = "paths.'/user/{username}'.put.responses.'200'.content.'application/xml'.encoding.password.explode";
         vr.body(explode, equalTo(true));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testCallbackAnnotations(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        String endpoint = "paths.'/streams'.post.callbacks";
-        vr.body(endpoint, hasKey("onData"));
-        vr.body(endpoint + ".onData", hasKey("{$request.query.callbackUrl}/data"));
-
-        endpoint = "paths.'/reviews'.post.callbacks";
-        vr.body(endpoint, hasKey("testCallback"));
-        vr.body(endpoint + ".testCallback", hasKey("http://localhost:9080/oas3-airlines/reviews"));
-
-        endpoint = "paths.'/bookings'.post.callbacks";
-        vr.body(endpoint, hasKey("get all the bookings"));
-        vr.body(endpoint + ".'get all the bookings'", hasKey("http://localhost:9080/airlines/bookings"));
-    }
+    public void testSecuritySchemesInComponents() throws InterruptedException {
+        String s = "components.securitySchemes";
+        vr.body(s, hasKey("httpTestScheme"));
+        vr.body(s, hasKey("airlinesRatingApp_auth"));
+        vr.body(s, hasKey("reviewoauth2"));
 
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testCallbackOperationAnnotations(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+        vr.body(s + ".httpTestScheme.type", equalTo("http"));
+        vr.body(s + ".httpTestScheme.description", equalTo("user security scheme"));
+        vr.body(s + ".httpTestScheme.scheme", equalTo("testScheme"));
 
-        // TODO: cover /streams endpoint
-        String endpoint = "paths.'/bookings'.post.callbacks.'get all the bookings'.'http://localhost:9080/airlines/bookings'";
-        vr.body(endpoint, hasKey("get"));
-        vr.body(endpoint + ".get.summary", hasKey("Retrieve all bookings for current user"));
-        vr.body(endpoint + ".get.responses.'200'.description", equalTo("Bookings retrieved"));
-        vr.body(endpoint + "get.responses.'200'.content.'application/json'.type", equalTo("array"));
+        vr.body(s + ".airlinesRatingApp_auth.type", equalTo("apiKey"));
+        vr.body(s + ".airlinesRatingApp_auth.description", equalTo("authentication needed to access Airlines app"));
+        vr.body(s + ".airlinesRatingApp_auth.name", equalTo("api_key"));
+        vr.body(s + ".airlinesRatingApp_auth.in", equalTo("header"));
 
-        endpoint = "paths.'/reviews'.post.callbacks.testCallback.'http://localhost:9080/oas3-airlines/reviews'";
-        vr.body(endpoint, hasKey("get"));
+        vr.body(s + ".reviewoauth2.type", equalTo("oauth2"));
+        vr.body(s + ".reviewoauth2.description", equalTo("authentication needed to create and delete reviews"));
 
-        vr.body(endpoint + ".get.summary", equalTo("Get all reviews"));
-        vr.body(endpoint + ".get.operationId", equalTo("getAllReviews_1"));
-        vr.body(endpoint + "responses.'200'.description", equalTo("successful operation"));
-        vr.body(endpoint + "responses.'200'.content.'application/json'.schema.ref", equalTo("#/components/schemas/Review"));
+        String t = "components.securitySchemes.reviewoauth2.flows";
+        vr.body(t + ".implicit.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(t + ".implicit.scopes.'write:reviews'", equalTo("create a review"));
+        vr.body(t + ".authorizationCode.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(t + ".authorizationCode.tokenUrl", equalTo("https://example.com/api/oauth/token"));
+        vr.body(t + ".password.refreshUrl", equalTo("https://example.com/api/oauth/refresh"));
+        vr.body(t + ".clientCredentials.authorizationUrl", equalTo("https://example.com/api/oauth/clientcredentials"));
+        vr.body(t + ".clientCredentials.scopes.'read:reviews'", equalTo("search for a review"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testRequestBodyAnnotations(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        String endpoint = "paths.'/bookings'.post.requestBody";
-        vr.body(endpoint + ".description", equalTo("Create a new booking with the provided information."));
-        vr.body(endpoint + ".content", notNullValue());
+    public void testOAuthAnnotations() throws InterruptedException {
+        String endpoint = "components.securitySchemes.reviewoauth2.flows.";
 
-        endpoint = "paths.'/bookings/{id}'.put.requestBody";
-        vr.body(endpoint + ".content", notNullValue());
+        vr.body(endpoint + "implicit.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(endpoint + "implicit.scopes.'write:reviews'", equalTo("create a review"));
 
-        endpoint = "paths.'/user'.post.requestBody";
-        vr.body(endpoint + ".description", equalTo("Record of a new user to be created in the system."));
-        vr.body(endpoint + ".content", notNullValue());
-        vr.body(endpoint + ".required", equalTo(true));
+        vr.body(endpoint + "authorizationCode.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(endpoint + "authorizationCode.tokenUrl", equalTo("https://example.com/api/oauth/token"));
 
-        endpoint = "paths.'/user/{username}'.put.requestBody";
-        vr.body(endpoint + ".description", equalTo("Record of a new user to be created in the system."));
-        vr.body(endpoint + ".content", notNullValue());
+        vr.body(endpoint + "password.tokenUrl", equalTo("https://example.com/api/oauth/token"));
+        vr.body(endpoint + "password.refreshUrl", equalTo("https://example.com/api/oauth/refresh"));
 
-        endpoint = "paths.'/user/createWithArray'.post.requestBody";
-        vr.body(endpoint + ".description", equalTo("Array of user object"));
-        vr.body(endpoint + ".content", notNullValue());
-        vr.body(endpoint + ".required", equalTo(true));
-
-        endpoint = "paths.'/user/createWithList'.post.requestBody";
-        vr.body(endpoint + ".description", equalTo("List of user object"));
-        vr.body(endpoint + ".content", notNullValue());
-        vr.body(endpoint + ".required", equalTo(true));
+        vr.body(endpoint + "clientCredentials.tokenUrl", equalTo("https://example.com/api/oauth/token"));
+        vr.body(endpoint + "clientCredentials.scopes.'read:reviews'", equalTo("search for a review"));
     }
-
+    
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testSecurityRequirement(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testSecurityRequirement() throws InterruptedException {
         vr.body("security.airlinesRatingApp_auth[0][0]", equalTo(null));
 
         vr.body("paths.'/reviews'.post.security.reviewoauth2[0][0]", equalTo("write:reviews"));
@@ -506,10 +523,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.'/user/logout'.get.security.httpTestScheme", hasSize(1));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testSecuritySchemes(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testSecuritySchemes() throws InterruptedException {
         String s = "components.securitySchemes";
         vr.body(s, hasKey("httpTestScheme"));
         vr.body(s, hasKey("airlinesRatingApp_auth"));
@@ -517,10 +533,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(s, hasKey("bookingSecurityScheme"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testSecurityScheme(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testSecurityScheme() throws InterruptedException {
         String http = "components.securitySchemes.httpTestScheme.";
         vr.body(http + "type", equalTo("http"));
         vr.body(http + "description", equalTo("user security scheme"));
@@ -536,16 +551,15 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(auth + "description", equalTo("authentication needed to access Airlines app"));
         vr.body(auth + "name", equalTo("api_key"));
         vr.body(auth + "in", equalTo("header"));
-
+        
         String reviewoauth2 = "components.securitySchemes.reviewoauth2.";
         vr.body(reviewoauth2 + "type", equalTo("oauth2"));
         vr.body(reviewoauth2 + "description", equalTo("authentication needed to create and delete reviews"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOAuthFlows(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOAuthFlows() throws InterruptedException {
         String t = "components.securitySchemes.reviewoauth2.flows";
         vr.body(t, hasKey("implicit"));
         vr.body(t, hasKey("authorizationCode"));
@@ -553,10 +567,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(t, hasKey("clientCredentials"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOAuthFlow(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOAuthFlow() throws InterruptedException {
         String implicit = "components.securitySchemes.reviewoauth2.flows.implicit.";
         vr.body(implicit + "authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
 
@@ -568,24 +581,22 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(password + "refreshUrl", equalTo("https://example.com/api/oauth/refresh"));
 
         String client = "components.securitySchemes.reviewoauth2.flows.clientCredentials.";
-        vr.body(client + "tokenUrl", equalTo("https://example.com/api/oauth/token"));
+        vr.body(client + "tokenUrl", equalTo("https://example.com/api/oauth/token"));   
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testOAuthScope(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testOAuthScope() throws InterruptedException {
         String implicit = "components.securitySchemes.reviewoauth2.flows.implicit.";
         vr.body(implicit + "scopes.'write:reviews'", equalTo("create a review"));
 
         String client = "components.securitySchemes.reviewoauth2.flows.clientCredentials.";
-        vr.body(client + "scopes.'read:reviews'", equalTo("search for a review"));
+        vr.body(client + "scopes.'read:reviews'", equalTo("search for a review"));   
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testEncodingRequestBody(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testEncodingRequestBody() throws InterruptedException {
         String s = "paths.'/user'.post.requestBody.content.'application/json'.encoding.email.";
         vr.body(s + "contentType", equalTo("text/plain"));
         vr.body(s + "style", equalTo("form"));
@@ -593,10 +604,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(s + "allowReserved", equalTo(true));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testEncodingResponses(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testEncodingResponses() throws InterruptedException {
         String s = "paths.'/user/{username}'.put.responses.'200'.content.'application/json'.encoding.password.";
         vr.body(s + "contentType", equalTo("text/plain"));
         vr.body(s + "style", equalTo("form"));
@@ -610,10 +620,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(t + "allowReserved", equalTo(true));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testLink(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testLink() throws InterruptedException {
         String s = "paths.'/user/{id}'.get.responses.'200'.links.'User name'.";
         vr.body(s + "operationId", equalTo("getUserByName"));
         vr.body(s + "description", equalTo("The username corresponding to provided user id"));
@@ -621,16 +630,15 @@ public class AirlinesAppTest extends AppTestBase {
         String t = "paths.'/user/{id}'.get.responses.'200'.links.Review.";
         vr.body(t + "operationRef", equalTo("/db/reviews/{userName}"));
         vr.body(t + "description", equalTo("The reviews provided by user"));
-
+        
         String k = "paths.'/reviews'.post.responses.'201'.links.Review.";
         vr.body(k + "operationId", equalTo("getReviewById"));
         vr.body(k + "description", equalTo("get the review that was added"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testLinkParameter(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testLinkParameter() throws InterruptedException {
         String s = "paths.'/user/{id}'.get.responses.'200'.links.'User name'.";
         vr.body(s + "parameters.userId", equalTo("$request.path.id"));
 
@@ -641,10 +649,9 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body(k + "parameters.reviewId", equalTo("$request.path.id"));
     }
 
+    @Test
     @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testSchema(String type) {
-        ValidatableResponse vr = callEndpoint(type);
+    public void testSchema() {
         // Basic properties
         vr.body("components.schemas.AirlinesRef.ref", equalTo("#/components/schemas/Airlines"));
         vr.body("components.schemas.Airlines.title", equalTo("Airlines"));
@@ -668,217 +675,4 @@ public class AirlinesAppTest extends AppTestBase {
         vr.body("paths.‘/user/createWithArray’.post.parameters.‘userArray’.content.schema.minItems", equalTo(2));
         vr.body("paths.‘/user/createWithArray’.post.parameters.‘userArray’.content.schema.uniqueItems", equalTo(true));
     }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testExampleObject(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        // Example in Components
-        vr.body("components.examples.review.summary", equalTo("External review example"));
-        vr.body("components.examples.review.description", equalTo("This example exemplifies the content on our site."));
-        vr.body("components.examples.review.externalValue", equalTo("http://foo.bar/examples/review-example.json"));
-
-        // Example in Content
-        vr.body("paths.'/reviews/{user}'.parameters.find{ it.name=='user'}.content.examples.value", hasItem("bsmith"));
-
-        // Example in Parameter
-        vr.body("paths.'/reviews/{user}'.parameters.find{ it.name=='user'}.examples.value", hasItems("bsmith", "pat@example.com"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testTagDeclarations(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        String tagsPath = "tags.find { it.name == '";
-        String desc = "' }.description";
-        vr.body(tagsPath + "user" + desc, equalTo("Operations about user"));
-        vr.body(tagsPath + "create" + desc, equalTo("Operations about create"));
-        vr.body(tagsPath + "Airlines" + desc, equalTo("All the airlines methods"));
-        vr.body(tagsPath + "Availability" + desc, equalTo("All the availability methods"));
-        vr.body(tagsPath + "Get Flights" + desc, equalTo("method to retrieve all flights available"));
-        vr.body(tagsPath + "Get Flights" + "' }.externalDocs.description", equalTo("A list of all the flights offered by the app"));
-        vr.body(tagsPath + "Get Flights" + "' }.externalDocs.url", equalTo("http://airlinesratingapp.com/ourflights"));
-        vr.body(tagsPath + "Bookings" + desc, equalTo("All the bookings methods"));
-        vr.body(tagsPath + "Reservations" + desc, equalTo("All the reservation methods"));
-        vr.body(tagsPath + "Reviews" + desc, equalTo("All the review methods"));
-        vr.body(tagsPath + "Ratings" + desc, equalTo("All the ratings methods"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testTagsInOperations(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        vr.body("paths.'/availability'.get.tags", containsInAnyOrder("Get Flights", "Availability"));
-        vr.body("paths.'/bookings'.get.tags", containsInAnyOrder("bookings"));
-        vr.body("paths.'/bookings'.post.tags", containsInAnyOrder("Bookings", "Reservations"));
-        vr.body("paths.'/bookings/{id}'.get.tags", containsInAnyOrder("Bookings", "Reservations"));
-        vr.body("paths.'/bookings/{id}'.put.tags", containsInAnyOrder("Bookings", "Reservations"));
-        // no tag - class Tag was overwritten with empty Tag
-        vr.body("paths.'/bookings/{id}'.delete.tags", not(hasSize(greaterThan(0))));
-        vr.body("paths.'/reviews'.get.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/reviews'.post.tags", containsInAnyOrder("Reviews"));
-        vr.body("paths.'/reviews/{id}'.get.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/reviews/{id}'.delete.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/reviews/{user}'.get.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/reviews/{airline}'.get.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/reviews/{user}/{airlines}'.get.tags", containsInAnyOrder("Reviews", "Ratings"));
-        vr.body("paths.'/user'.post.tags", containsInAnyOrder("user", "create"));
-        vr.body("paths.'/user/createWithArray'.post.tags", containsInAnyOrder("user", "create"));
-        vr.body("paths.'/user/createWithList'.post.tags", containsInAnyOrder("user", "create"));
-        vr.body("paths.'/user/{username}'.get.tags", containsInAnyOrder("user"));
-        vr.body("paths.'/user/{username}'.put.tags", containsInAnyOrder("user"));
-        vr.body("paths.'/user/{username}'.delete.tags", containsInAnyOrder("user"));
-        vr.body("paths.'/user/{id}'.get.tags", containsInAnyOrder("user"));
-        // empty tag was defined
-        vr.body("paths.'/user/login'.get.tags", not(hasSize(greaterThan(0))));
-        // no tag was defined
-        vr.body("paths.'/user/logout'.get.tags", not(hasSize(greaterThan(0))));
-        vr.body("paths.'/'.get.tags", containsInAnyOrder("Airlines"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testComponents(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        // Tests to ensure that the reusable items declared using the
-        // @Components annotation (within @OpenAPIDefinition) exist.
-        // Each of these item types are tested elsewhere, so no need to test the
-        // content of them here.
-        vr.body("components.schemas.Bookings", notNullValue());
-        vr.body("components.schemas.Airlines", notNullValue());
-        vr.body("components.schemas.AirlinesRef", notNullValue());
-        vr.body("components.responses.FoundAirlines", notNullValue());
-        vr.body("components.responses.FoundBookings", notNullValue());
-        vr.body("components.parameters.departureDate", notNullValue());
-        vr.body("components.parameters.username", notNullValue());
-        vr.body("components.examples.review", notNullValue());
-        vr.body("components.examples.user", notNullValue());
-        vr.body("components.requestBodies.review", notNullValue());
-        vr.body("components.headers.Max-Rate", notNullValue());
-        vr.body("components.headers.Request-Limit", notNullValue());
-        vr.body("components.securitySchemes.httpTestScheme", notNullValue());
-        vr.body("components.links.UserName", notNullValue());
-        vr.body("components.callbacks.GetBookings", notNullValue());
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testHeaderInAPIResponse(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        // Headers within APIResponse
-        String responseHeader1 = "paths.'/reviews/{id}'.get.responses.'200'.headers.responseHeader1";
-        vr.body(responseHeader1, notNullValue());
-        vr.body(responseHeader1 + ".description", equalTo("Max rate"));
-        vr.body(responseHeader1 + ".required", equalTo(true));
-        vr.body(responseHeader1 + ".deprecated", equalTo(true));
-        vr.body(responseHeader1 + ".allowEmptyValue", equalTo(true));
-        vr.body(responseHeader1 + ".style", equalTo("simple"));
-        vr.body(responseHeader1 + ".schema.type", equalTo("integer"));
-
-        String responseHeader2 = "paths.'/reviews/{id}'.get.responses.'200'.headers.responseHeader2";
-        vr.body(responseHeader2, notNullValue());
-        vr.body(responseHeader2 + ".description", equalTo("Input value"));
-        vr.body(responseHeader2 + ".required", equalTo(true));
-        vr.body(responseHeader2 + ".deprecated", equalTo(true));
-        vr.body(responseHeader2 + ".allowEmptyValue", equalTo(true));
-        vr.body(responseHeader2 + ".style", equalTo("simple"));
-        vr.body(responseHeader2 + ".schema.type", equalTo("string"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testHeaderInEncoding(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        // Header within Encoding
-        String testHeader = "paths.'/user'.post.requestBody.content.'application/json'.encoding.email.headers.testHeader";
-        vr.body(testHeader, notNullValue());
-        vr.body(testHeader + ".description", equalTo("Minimum rate"));
-        vr.body(testHeader + ".required", equalTo(true));
-        vr.body(testHeader + ".deprecated", equalTo(true));
-        vr.body(testHeader + ".allowEmptyValue", equalTo(true));
-        vr.body(testHeader + ".style", equalTo("simple"));
-        vr.body(testHeader + ".schema.type", equalTo("integer"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testRefHeaderInAPIResponse(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        // Reference to Header within APIResponse
-        String responseRefHeader = "paths.'/reviews'.get.responses.'200'.headers.Request-Limit";
-        vr.body(responseRefHeader, notNullValue());
-        vr.body(responseRefHeader + ".$ref", equalTo("#/components/headers/Request-Limit"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testRefHeaderInEncoding(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        // Reference to Header within Encoding
-        String encodingRefHeader = "paths.'/user/{username}'.put.responses.'200'.content.'application/json'.encoding.password.headers.Max-Rate";
-        vr.body(encodingRefHeader, notNullValue());
-        vr.body(encodingRefHeader + ".$ref", equalTo("#/components/headers/Max-Rate"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testHeaderInComponents(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        String maxRate = "components.headers.Max-Rate";
-        vr.body(maxRate + ".description", equalTo("Maximum rate"));
-        vr.body(maxRate + ".required", equalTo(true));
-        vr.body(maxRate + ".deprecated", equalTo(true));
-        vr.body(maxRate + ".allowEmptyValue", equalTo(true));
-        vr.body(maxRate + ".style", equalTo("simple"));
-        vr.body(maxRate + ".schema.type", equalTo("integer"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testContentInAPIResponse(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        String content1 = "paths.'/availability'.get.responses.'200'.content.'application/json'";
-        vr.body(content1, notNullValue());
-        vr.body(content1 + ".schema.type", equalTo("array"));
-        vr.body(content1 + ".schema.items.$ref", equalTo("#/components/schemas/Flight"));
-
-        String content2 = "paths.'/user/{username}'.put.responses.'200'.content";
-        vr.body(content2, notNullValue());
-        vr.body(content2 + ".'application/json'", notNullValue());
-        vr.body(content2 + ".'application/json'.schema.$ref", equalTo("#/components/schemas/User"));
-        vr.body(content2 + ".'application/json'.encoding.password", notNullValue());
-
-        vr.body(content2, notNullValue());
-        vr.body(content2 + ".'application/xml'", notNullValue());
-        vr.body(content2 + ".'application/xml'.schema.$ref", equalTo("#/components/schemas/User"));
-        vr.body(content2 + ".'application/xml'.encoding.password", notNullValue());
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testContentInRequestBody(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        String contentJson = "paths.'/bookings'.post.requestBody.content.'application/json'";
-        vr.body(contentJson, notNullValue());
-        vr.body(contentJson + ".schema.$ref", equalTo("#/components/schemas/Booking"));
-        vr.body(contentJson + ".examples.booking.summary", equalTo("External booking example"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testContentInParameter(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-
-        String content = "paths.'/reviews/{user}'.get.parameters.find{ it.name == 'user' }.content";
-        vr.body(content, notNullValue());
-        vr.body(content + ".'*/*'", notNullValue());
-        vr.body(content + ".'*/*'.schema.type", equalTo("string"));
-    }
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTestPetStore.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTestPetStore.java
new file mode 100644
index 0000000..d1c7424
--- /dev/null
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTestPetStore.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2017 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 io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.nullValue;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.microprofile.openapi.tck.utils.YamlToJsonConverterServlet;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import io.restassured.RestAssured;
+import io.restassured.parsing.Parser;
+import io.restassured.response.Response;
+import io.restassured.response.ValidatableResponse;
+
+@RunWith(Arquillian.class)
+public class EndpointTestPetStore {
+    private static final String APPLICATION_JSON = "application/json";
+    private static final String APPLICATION_YAML = "application/yaml";
+
+    private static final String DEFAULT_PROTOCOL = "http";
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int DEFAULT_PORT = 9080;
+
+    private static ValidatableResponse vr;
+
+    @BeforeClass
+    static public void setup() throws MalformedURLException {
+        // set base URI and port number to use for all requests
+        String serverUrl = System.getProperty("test.url");
+        String protocol = DEFAULT_PROTOCOL;
+        String host = DEFAULT_HOST;
+        int port = DEFAULT_PORT;
+
+        if (serverUrl != null) {
+            URL url = new URL(serverUrl);
+            protocol = url.getProtocol();
+            host = url.getHost();
+            port = (url.getPort() == -1) ? DEFAULT_PORT : url.getPort();
+        }
+
+        RestAssured.baseURI = protocol + "://" + host;
+        RestAssured.port = port;
+
+        String userName = System.getProperty("test.user");
+        String password = System.getProperty("test.pwd");
+
+        if (userName != null && password != null) {
+            RestAssured.authentication = RestAssured.basic(userName, password);
+            RestAssured.useRelaxedHTTPSValidation();
+        }
+        RestAssured.defaultParser = Parser.JSON;
+    }
+
+    @Before
+    public void setUpTest() {
+        vr = given().when().get("/proxy").then().statusCode(200);
+    }
+
+    @Deployment(name = "proxy")
+    public static WebArchive createProxy() {
+        WebArchive war = ShrinkWrap.create(WebArchive.class, "proxy.war")
+                .addClass(YamlToJsonConverterServlet.class)
+                .addAsLibraries(new File("./lib/httpclient-4.5.2.jar"))
+                .addAsLibraries(new File("./lib/httpcore-4.4.4.jar"))
+                .addAsLibraries(new File("./lib/jackson-core-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-dataformat-yaml-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-databind-2.9.2.jar"))
+                .addAsLibraries(new File("./lib/jackson-annotations-2.9.1.jar"))
+                .addAsLibraries(new File("./lib/snakeyaml-1.18.jar"))
+                .addAsLibraries(new File("./lib/commons-logging-1.2.jar"))
+                .addAsLibraries(new File("./lib/commons-lang3-3.4.jar"));
+        return war;
+    }
+
+    @Deployment(name = "petstore")
+    public static WebArchive createDeployment() {
+        WebArchive war = ShrinkWrap.create(WebArchive.class, "petstore.war")
+                .addPackages(true, "org.eclipse.microprofile.openapi.apps.petstore")
+                .addAsManifestResource(EmptyAsset.INSTANCE, "/openapi/openapi.yaml");
+        return war;
+    }
+
+    @Test
+    @RunAsClient
+    public void testVersion() throws InterruptedException {
+        vr.body("openapi", equalTo("3.0.0"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testSchema() throws InterruptedException {
+        // Schema annotation tests
+        Response response = given().when().get("/proxy");
+        System.out.println("response=" + response.asString());
+        ValidatableResponse vr = response.then().parser("", Parser.JSON).statusCode(200);
+        
+        // Basic properties
+        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.default", equalTo("Dog"));  // default val
+        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.enum", hasItems("Cat", "Dog", "Lizard")); // enumeration 
+        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.externalDocs.description", equalTo("Pet Types")); // ext doc
+        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.deprecated", equalTo(true)); // deprecated
+        vr.body("paths.'/store/order/{orderId}'.get.responses.'900'.schema", nullValue()); // hidden
+        
+        // Numerical properties
+        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.maximum", equalTo(101)); // maximum
+        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.exclusiveMaximum", equalTo(true)); // exclusive max
+        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.minimum", equalTo(9)); // minimum
+        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.exclusiveMinimum", equalTo(true)); // exclusive min
+        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.multipleOf", equalTo(10)); // multiple of
+        
+        //  String properties
+        vr.body("paths.'/pet/{petId}'.delete.parameters.find{ it.name == 'apiKey' }.schema.maxLength", equalTo(256)); // max length
+        vr.body("paths.'/pet/{petId}'.delete.parameters.find{ it.name == 'apiKey' }.schema.minLength", equalTo(32)); // min length
+
+        // Other properties
+        String storeOrderResponses = "paths.'/store/order/{orderId}'.get.responses";
+        vr.body("paths.'/pet/{petId}'.get.responses.'200'.content.'application/json'.schema.readonly", equalTo(true)); //  readonly
+        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.anyOf", hasItems("Order.class", "BadOrder.class")); //    any of
+        vr.body(storeOrderResponses + ".'200'.content.'application/json'.schema.allOf", hasItems("Order.class", "Pet.class")); //    all of
+        vr.body("paths.'/pet/{petId}'.get.responses.'200'.content.'application/json'.schema.oneOf", 
+                hasItems("Cat.class", "Dog.class", "Lizard.class")); //    one of
+        vr.body(storeOrderResponses + ".'200'.content.'application/json'.schema.not", equalTo("BadOrder.class")); //    not
+        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.discriminatorProperty", equalTo("id")); //    discrimination prop
+        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.discriminatorMapping", hasEntry("0", "BadOrder.class")); // mapping
+    }
+}
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 c2f04e8..cd941bf 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
@@ -16,14 +16,6 @@
 
 package org.eclipse.microprofile.openapi.tck;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNotSame;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.beans.Introspector;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -31,6 +23,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -58,7 +51,11 @@ import org.eclipse.microprofile.openapi.models.media.Encoding;
 import org.eclipse.microprofile.openapi.models.media.MediaType;
 import org.eclipse.microprofile.openapi.models.media.Schema;
 import org.eclipse.microprofile.openapi.models.media.XML;
+import org.eclipse.microprofile.openapi.models.parameters.CookieParameter;
+import org.eclipse.microprofile.openapi.models.parameters.HeaderParameter;
 import org.eclipse.microprofile.openapi.models.parameters.Parameter;
+import org.eclipse.microprofile.openapi.models.parameters.PathParameter;
+import org.eclipse.microprofile.openapi.models.parameters.QueryParameter;
 import org.eclipse.microprofile.openapi.models.parameters.RequestBody;
 import org.eclipse.microprofile.openapi.models.responses.APIResponse;
 import org.eclipse.microprofile.openapi.models.responses.APIResponses;
@@ -72,17 +69,22 @@ 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.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.testng.annotations.Test;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * 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 extends Arquillian {
+@RunWith(Arquillian.class)
+public class ModelConstructionTest {
+    
+    private static final Map<String,Property> PARAMETER_PROPERTIES = Collections.unmodifiableMap(collectProperties0(Parameter.class));
     
     // Container for matched getter, setter and builder methods
     static final class Property {
@@ -119,7 +121,7 @@ public class ModelConstructionTest extends Arquillian {
                 return getter.invoke(target);
             }
             catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                fail("Invocation of getter method \"" + getter.getName() + "\" failed: " + e.getMessage());
+                Assert.fail("Invocation of getter method \"" + getter.getName() + "\" failed: " + e.getMessage());
                 throw new RuntimeException(e);
             }
         }
@@ -128,7 +130,7 @@ public class ModelConstructionTest extends Arquillian {
                 setter.invoke(target, value);
             }
             catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                fail("Invocation of setter method \"" + setter.getName() + "\" failed: " + e.getMessage());
+                Assert.fail("Invocation of setter method \"" + setter.getName() + "\" failed: " + e.getMessage());
                 throw new RuntimeException(e);
             }
         }
@@ -137,7 +139,7 @@ public class ModelConstructionTest extends Arquillian {
                 return builder.invoke(target, value);
             }
             catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-                fail("Invocation of builder method \"" + builder.getName() + "\" failed: " + e.getMessage());
+                Assert.fail("Invocation of builder method \"" + builder.getName() + "\" failed: " + e.getMessage());
                 throw new RuntimeException(e);
             }
         }
@@ -151,12 +153,13 @@ public class ModelConstructionTest extends Arquillian {
             return getter != null && setter != null;
         }
     }
-
+    
     @Deployment
-    public static WebArchive createDeployment() {
-        return ShrinkWrap.create(WebArchive.class);
+    public static WebArchive createProxy() {
+        WebArchive war = ShrinkWrap.create(WebArchive.class);
+        return war;
     }
-
+    
     @Test
     public void componentsTest() {
         final Components c = processConstructible(Components.class);
@@ -182,7 +185,7 @@ public class ModelConstructionTest extends Arquillian {
         checkMapEntry(c.getLinks(), linkKey, linkValue);
         
         final String parameterKey = "myParameter";
-        final Parameter parameterValue = createConstructibleInstance(Parameter.class);
+        final Parameter<?> parameterValue = createConstructibleInstance(CookieParameter.class);
         checkSameObject(c, c.addParameter(parameterKey, parameterValue));
         checkMapEntry(c.getParameters(), parameterKey, parameterValue);
         
@@ -233,7 +236,7 @@ public class ModelConstructionTest extends Arquillian {
     public void operationTest() {
         final Operation o = processConstructible(Operation.class);
         
-        final Parameter p = createConstructibleInstance(Parameter.class);
+        final Parameter<?> p = createConstructibleInstance(CookieParameter.class);
         checkSameObject(o, o.addParameter(p));
         checkListEntry(o.getParameters(), p);
         
@@ -254,7 +257,7 @@ public class ModelConstructionTest extends Arquillian {
     public void pathItemTest() {
         final PathItem pi = processConstructible(PathItem.class);
         
-        final Parameter p = createConstructibleInstance(Parameter.class);
+        final Parameter<?> p = createConstructibleInstance(CookieParameter.class);
         checkSameObject(pi, pi.addParameter(p));
         checkListEntry(pi.getParameters(), p);
         
@@ -274,10 +277,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String pathItemKey2 = "myPathItem2";
         final PathItem pathItemValue2 = createConstructibleInstance(PathItem.class);
-        assertNull(p.put(pathItemKey2, pathItemValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", p.put(pathItemKey2, pathItemValue2));
         checkMapEntry(p, pathItemKey2, pathItemValue2);
         
-        assertEquals(p.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, p.size());
     }
     
     @Test
@@ -291,10 +294,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String pathItemKey2 = "myPathItem2";
         final PathItem pathItemValue2 = createConstructibleInstance(PathItem.class);
-        assertNull(c.put(pathItemKey2, pathItemValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", c.put(pathItemKey2, pathItemValue2));
         checkMapEntry(c, pathItemKey2, pathItemValue2);
         
-        assertEquals(c.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, c.size());
     }
     
     @Test
@@ -332,7 +335,7 @@ public class ModelConstructionTest extends Arquillian {
         final Link l = processConstructible(Link.class);
         
         final String parameterKey = "myParameter";
-        final Parameter parameterValue = createConstructibleInstance(Parameter.class);
+        final Parameter<?> parameterValue = createConstructibleInstance(CookieParameter.class);
         checkSameObject(l, l.addParameter(parameterKey, parameterValue));
         checkMapEntry(l.getParameters(), parameterKey, parameterValue);
     }
@@ -348,10 +351,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String mediaTypeKey2 = "myPathItem2";
         final MediaType mediaTypeValue2 = createConstructibleInstance(MediaType.class);
-        assertNull(c.put(mediaTypeKey2, mediaTypeValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", c.put(mediaTypeKey2, mediaTypeValue2));
         checkMapEntry(c, mediaTypeKey2, mediaTypeValue2);
         
-        assertEquals(c.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, c.size());
     }
     
     @Test
@@ -420,13 +423,27 @@ public class ModelConstructionTest extends Arquillian {
     }
     
     @Test
-    public void parameterTest() {
-        final Parameter p = processConstructible(Parameter.class);
-        
-        final String exampleKey = "myExample";
-        final Example exampleValue = createConstructibleInstance(Example.class);
-        checkSameObject(p, p.addExample(exampleKey, exampleValue));
-        checkMapEntry(p.getExamples(), exampleKey, exampleValue);
+    public void cookieParameterTest() {
+        final CookieParameter cp = processConstructible(CookieParameter.class);
+        checkParameterCommon(cp, Parameter.In.COOKIE, "cookie");
+    }
+
+    @Test
+    public void headerParameterTest() {
+        final HeaderParameter hp = processConstructible(HeaderParameter.class);
+        checkParameterCommon(hp, Parameter.In.HEADER, "header");
+    }
+    
+    @Test
+    public void pathParameterTest() {
+        final PathParameter pp = processConstructible(PathParameter.class);
+        checkParameterCommon(pp, Parameter.In.PATH, "path");
+    }
+    
+    @Test
+    public void queryParameterTest() {
+        final QueryParameter qp = processConstructible(QueryParameter.class);
+        checkParameterCommon(qp, Parameter.In.QUERY, "query");
     }
     
     @Test
@@ -460,10 +477,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String responseKey2 = "myResponse2";
         final APIResponse responseValue2 = createConstructibleInstance(APIResponse.class);
-        assertNull(responses.put(responseKey2, responseValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", responses.put(responseKey2, responseValue2));
         checkMapEntry(responses, responseKey2, responseValue2);
         
-        assertEquals(responses.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, responses.size());
     }
     
     @Test
@@ -487,10 +504,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String scopeKey2 = "myScope2";
         final String scopeValue2 = new String("myDescription2");
-        assertNull(s.put(scopeKey2, scopeValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", s.put(scopeKey2, scopeValue2));
         checkMapEntry(s, scopeKey2, scopeValue2);
         
-        assertEquals(s.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, s.size());
     }
     
     @Test
@@ -504,10 +521,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String schemeKey2 = "myResponse2";
         final List<String> schemeValue2 = new ArrayList<String>();
-        assertNull(sr.put(schemeKey2, schemeValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", sr.put(schemeKey2, schemeValue2));
         checkMapEntry(sr, schemeKey2, schemeValue2);
         
-        assertEquals(sr.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, sr.size());
     }
     
     @Test
@@ -540,10 +557,10 @@ public class ModelConstructionTest extends Arquillian {
         
         final String varKey2 = "myServerVariable2";
         final ServerVariable varValue2 = createConstructibleInstance(ServerVariable.class);
-        assertNull(svs.put(varKey2, varValue2), "No previous mapping expected.");
+        Assert.assertNull("No previous mapping expected.", svs.put(varKey2, varValue2));
         checkMapEntry(svs, varKey2, varValue2);
         
-        assertEquals(svs.size(), 2, "The map is expected to contain two entries.");
+        Assert.assertEquals("The map is expected to contain two entries.", 2, svs.size());
     }
     
     @Test
@@ -569,12 +586,12 @@ public class ModelConstructionTest extends Arquillian {
     private <T extends Constructible> T createConstructibleInstance(Class<T> clazz) {
         // Check that the OASFactory is able to create an instance of the given Class.
         final T o1 = OASFactory.createObject(clazz);
-        assertNotNull(o1, "The return value of OASFactory.createObject(" + clazz.getName() + ") must not be null.");
-        assertTrue(clazz.isInstance(o1), "The return value of OASFactory.createObject() is expected to be an instance of: " + clazz.getName());
+        Assert.assertNotNull("The return value of OASFactory.createObject(" + clazz.getName() + ") must not be null.", o1);
+        Assert.assertTrue("The return value of OASFactory.createObject() is expected to be an instance of: " + clazz.getName(), clazz.isInstance(o1));
         final T o2 = OASFactory.createObject(clazz);
-        assertNotNull(o2, "The return value of OASFactory.createObject(" + clazz.getName() + ") must not be null.");
-        assertTrue(clazz.isInstance(o2), "The return value of OASFactory.createObject() is expected to be an instance of: " + clazz.getName());
-        assertNotSame(o2, o1, "OASFactory.createObject(" + clazz.getName() + ") is expected to create a new object on each invocation.");
+        Assert.assertNotNull("The return value of OASFactory.createObject(" + clazz.getName() + ") must not be null.", o2);
+        Assert.assertTrue("The return value of OASFactory.createObject() is expected to be an instance of: " + clazz.getName(), clazz.isInstance(o2));
+        Assert.assertNotSame("OASFactory.createObject(" + clazz.getName() + ") is expected to create a new object on each invocation.", o1, o2);
         return o1;
     }
     
@@ -587,45 +604,45 @@ public class ModelConstructionTest extends Arquillian {
         e.addExtension(extensionName1, obj1);
         e.addExtension(extensionName2, obj2);
         final Map<String, Object> map = e.getExtensions();
-        assertEquals(map.size(), 2, "The extensions map is expected to contain two entries.");
-        assertTrue(map.containsKey(extensionName1), "The extensions map is expected to contain the key: " + extensionName1);
-        assertTrue(map.containsKey(extensionName2), "The extensions map is expected to contain the key: " + extensionName2);
-        assertSame(map.get(extensionName1), obj1,
-                "The value associated with the key: " + extensionName1 + " is expected to be the same one that was added.");
-        assertSame(map.get(extensionName2), obj2,
-                "The value associated with the key: " + extensionName2 + " is expected to be the same one that was added.");
+        Assert.assertEquals("The extensions map is expected to contain two entries.", 2, map.size());
+        Assert.assertTrue("The extensions map is expected to contain the key: " + extensionName1, map.containsKey(extensionName1));
+        Assert.assertTrue("The extensions map is expected to contain the key: " + extensionName2, map.containsKey(extensionName2));
+        Assert.assertSame("The value associated with the key: " + extensionName1 + " is expected to be the same one that was added.",
+                obj1, map.get(extensionName1));
+        Assert.assertSame("The value associated with the key: " + extensionName2 + " is expected to be the same one that was added.",
+                obj2, map.get(extensionName2));
         // Check that the extension map can be replaced with the setter and that it is returned by the getter.
         final Map<String, Object> newMap = new HashMap<>();
         e.setExtensions(newMap);
         final Map<String, Object> map2 = e.getExtensions();
-        assertEquals(map2.size(), 0, "The extensions map is expected to contain no entries.");
-        assertSame(map2, newMap, "The return value of getExtensions() is expected to be the same value that was set.");
+        Assert.assertEquals("The extensions map is expected to contain no entries.", 0, map2.size());
+        Assert.assertSame("The return value of getExtensions() is expected to be the same value that was set.", newMap, map2);
     }
     
     private void processReference(Reference<?> r) {
         // Check that the ref value can be set using the setter method and that the getter method returns the same value.
         final String myRef1 = createReference(r, "myRef1");
         r.setRef(myRef1);
-        assertEquals(r.getRef(), myRef1, "The return value of getRef() is expected to be equal to the value that was set.");
+        Assert.assertEquals("The return value of getRef() is expected to be equal to the value that was set.", myRef1, r.getRef());
         // Check that the short name ref value can be set using the setter method and that the getter method returns the expanded value.
         if (!(r instanceof PathItem)) {
             final String shortName = "myRef2";
             final String myRef2 = createReference(r, shortName);
             r.setRef(shortName);
-            assertEquals(r.getRef(), myRef2, "The return value of getRef() is expected to be a fully expanded name.");
+            Assert.assertEquals("The return value of getRef() is expected to be a fully expanded name.", myRef2, r.getRef());
         }
         // Check that the ref value can be set using the builder method and that the getter method returns the same value.
         final String myRef3 = createReference(r, "myRef3");
         final Reference<?> self = r.ref(myRef3);
-        assertSame(self, r, "The return value of ref() is expected to return the current instance.");
-        assertEquals(r.getRef(), myRef3, "The return value of getRef() is expected to be equal to the value that was set.");
+        Assert.assertSame("The return value of ref() is expected to return the current instance.", r, self);
+        Assert.assertEquals("The return value of getRef() is expected to be equal to the value that was set.", myRef3, r.getRef());
         // Check that the short name ref value can be set using the builder method and that the getter method returns the expanded value.
         if (!(r instanceof PathItem)) {
             final String shortName = "myRef4";
             final String myRef4 = createReference(r, shortName);
             final Reference<?> self2 = r.ref(shortName);
-            assertSame(self2, r, "The return value of ref() is expected to return the current instance.");
-            assertEquals(r.getRef(), myRef4, "The return value of getRef() is expected to be a fully expanded name.");
+            Assert.assertSame("The return value of ref() is expected to return the current instance.", r, self2);
+            Assert.assertEquals("The return value of getRef() is expected to be a fully expanded name.", myRef4, r.getRef());
         }
     }
     
@@ -633,30 +650,30 @@ public class ModelConstructionTest extends Arquillian {
         final Object value1 = getInstanceOf(p.getType(), false);
         p.invokeSetter(o, value1);
         if (!p.isPrimitive()) {
-            assertSame(p.invokeGetter(o), value1, "The return value of the getter method for property \"" + 
+            Assert.assertSame("The return value of the getter method for property \"" + 
                     p.getName() + "\" of interface \"" + enclosingInterface.getName() +
-                    "\" is expected to be the same as the value that was set.");
+                    "\" is expected to be the same as the value that was set.", value1, p.invokeGetter(o));
         }
         else {
-            assertEquals(p.invokeGetter(o), value1, "The return value of the getter method for property \"" + 
+            Assert.assertEquals("The return value of the getter method for property \"" + 
                     p.getName() + "\" of interface \"" + enclosingInterface.getName() +
-                    "\" is expected to be equal to the value that was set.");
+                    "\" is expected to be equal to the value that was set.", value1, p.invokeGetter(o));
         }
         if (p.hasBuilder()) {
             final Object value2 = getInstanceOf(p.getType(), true);
             final Object self = p.invokeBuilder(o, value2);
-            assertSame(self, o, "The return value of the builder method for property \"" + 
+            Assert.assertSame("The return value of the builder method for property \"" + 
                     p.getName() + "\" of interface \"" + enclosingInterface.getName() +
-                    "\" is expected to be the same as the value that was set.");
+                    "\" is expected to be the same as the value that was set.", o, self);
             if (!p.isPrimitive()) {
-                assertSame(p.invokeGetter(o), value2, "The return value of the getter method for property \"" + 
+                Assert.assertSame("The return value of the getter method for property \"" + 
                         p.getName() + "\" of interface \"" + enclosingInterface.getName() +
-                        "\" is expected to be the same as the value that was set.");
+                        "\" is expected to be the same as the value that was set.", value2, p.invokeGetter(o));
             }
             else {
-                assertEquals(p.invokeGetter(o), value2, "The return value of the getter method for property \"" + 
+                Assert.assertEquals("The return value of the getter method for property \"" + 
                         p.getName() + "\" of interface \"" + enclosingInterface.getName() +
-                        "\" is expected to be equal to the value that was set.");
+                        "\" is expected to be equal to the value that was set.", value2, p.invokeGetter(o));
             }
         }
     }
@@ -664,6 +681,9 @@ public class ModelConstructionTest extends Arquillian {
     // Returns instances for testing getter, setter and builder methods.
     @SuppressWarnings("unchecked")
     private Object getInstanceOf(Class<?> clazz, boolean alternateEnumValue) {
+        if (clazz == Parameter.class) {
+            clazz = CookieParameter.class;
+        }
         if (Constructible.class.isAssignableFrom(clazz)) {
             return createConstructibleInstance((Class<Constructible>) clazz);
         }
@@ -756,8 +776,18 @@ public class ModelConstructionTest extends Arquillian {
         sb.append(v);
         return sb.toString();
     }
-      
+    
     private Map<String,Property> collectProperties(Class<?> clazz) {
+        final Map<String,Property> properties = collectProperties0(clazz);
+        // Parameter has sub-types.
+        // Add the getter/setter/builder methods from the base type.
+        if (Parameter.class.isAssignableFrom(clazz)) {
+            properties.putAll(PARAMETER_PROPERTIES);
+        }
+        return properties;
+    }
+        
+    private static Map<String,Property> collectProperties0(Class<?> clazz) {
         final Map<String,Property> properties = new HashMap<>();
         final Method[] methods = clazz.getDeclaredMethods();
         Arrays.stream(methods).forEach(m -> {
@@ -814,18 +844,30 @@ public class ModelConstructionTest extends Arquillian {
         return properties;
     }
     
+    private <T extends Parameter<T>> void checkParameterCommon(Parameter<T> p, Parameter.In expectedIn, String name) {
+        final String exampleKey = "myExample";
+        final Example exampleValue = createConstructibleInstance(Example.class);
+        checkSameObject(p, p.addExample(exampleKey, exampleValue));
+        checkMapEntry(p.getExamples(), exampleKey, exampleValue);
+        
+        // Check value of read-only 'in' property.
+        Assert.assertEquals("The value of the 'in' property is expected to be '" + name + "'.",
+                expectedIn, p.getIn());
+    }
+    
     private <T> void checkMapEntry(Map<String,T> map, String key, T value) {
-        assertNotNull(map, "The map must not be null.");
-        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.");
+        Assert.assertNotNull("The map must not be null.", map);
+        Assert.assertTrue("The map is expected to contain the key: " + key, map.containsKey(key));
+        Assert.assertSame("The value associated with the key: " + key + " is expected to be the same one that was added.",
+                value, map.get(key));
     }
     
     private <T> void checkListEntry(List<T> list, T value) {
-        assertNotNull(list, "The list must not be null.");
-        assertTrue(list.stream().anyMatch((v) -> v == value), "The list is expected to contain the value: " + value);
+        Assert.assertNotNull("The list must not be null.", list);
+        Assert.assertTrue("The list is expected to contain the value: " + value, list.stream().anyMatch((v) -> v == value));
     }
     
     private <T> void checkSameObject(T expected, T actual) {
-        assertSame(actual, expected ,"Expecting same object.");
+        Assert.assertSame("Expecting same object.", expected, actual);
     }
 }
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASFactoryErrorTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASFactoryErrorTest.java
index aed710f..5f10996 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASFactoryErrorTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/OASFactoryErrorTest.java
@@ -22,13 +22,15 @@ import org.eclipse.microprofile.openapi.OASFactory;
 import org.eclipse.microprofile.openapi.models.Constructible;
 import org.eclipse.microprofile.openapi.models.info.License;
 import org.jboss.arquillian.container.test.api.Deployment;
-import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
-import org.testng.annotations.Test;
-
-public class OASFactoryErrorTest extends Arquillian {
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
+@RunWith(Arquillian.class)
+public class OASFactoryErrorTest {
+    
     public interface MyConstructible extends Constructible {}
     public interface MyLicense extends License {}
     public abstract class MyAbstractLicenseImpl implements License {}
@@ -62,43 +64,44 @@ public class OASFactoryErrorTest extends Arquillian {
             return null;
         }
     }
-
+    
     @Deployment
-    public static WebArchive createDeployment() {
-        return ShrinkWrap.create(WebArchive.class);
+    public static WebArchive createProxy() {
+        WebArchive war = ShrinkWrap.create(WebArchive.class);
+        return war;
     }
-
-    @Test(expectedExceptions = { NullPointerException.class })
+    
+    @Test(expected = NullPointerException.class)
     public void nullValueTest() {
         @SuppressWarnings("unused")
         final Object o = OASFactory.createObject(null);
     }
-
-    @Test(expectedExceptions = { IllegalArgumentException.class })
+    
+    @Test(expected = IllegalArgumentException.class)
     public void baseInterfaceTest() {
         @SuppressWarnings("unused")
         final Constructible c = OASFactory.createObject(Constructible.class);
     }
-
-    @Test(expectedExceptions = { IllegalArgumentException.class })
+    
+    @Test(expected = IllegalArgumentException.class)
     public void extendedBaseInterfaceTest() {
         @SuppressWarnings("unused")
         final MyConstructible m = OASFactory.createObject(MyConstructible.class);
     }
-
-    @Test(expectedExceptions = { IllegalArgumentException.class })
+    
+    @Test(expected = IllegalArgumentException.class)
     public void extendedInterfaceTest() {
         @SuppressWarnings("unused")
         final MyLicense m = OASFactory.createObject(MyLicense.class);
     }
-
-    @Test(expectedExceptions = { IllegalArgumentException.class })
+    
+    @Test(expected = IllegalArgumentException.class)
     public void customAbstractClassTest() {
         @SuppressWarnings("unused")
         final MyAbstractLicenseImpl m = OASFactory.createObject(MyAbstractLicenseImpl.class);
     }
-
-    @Test(expectedExceptions = { IllegalArgumentException.class })
+    
+    @Test(expected = IllegalArgumentException.class)
     public void customClassTest() {
         @SuppressWarnings("unused")
         final MyLicenseImpl m = OASFactory.createObject(MyLicenseImpl.class);
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/PetStoreAppTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/PetStoreAppTest.java
deleted file mode 100644
index a8989db..0000000
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/PetStoreAppTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * Copyright (c) 2017 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.equalTo;
-import static org.hamcrest.Matchers.hasEntry;
-import static org.hamcrest.Matchers.hasItems;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.nullValue;
-
-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 PetStoreAppTest extends AppTestBase {
-    @Deployment(name = "petstore")
-    public static WebArchive createDeployment() {
-        return ShrinkWrap.create(WebArchive.class, "petstore.war")
-                .addPackages(true, "org.eclipse.microprofile.openapi.apps.petstore");
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testSchema(String type) {
-        ValidatableResponse vr = callEndpoint(type);
-        // Schema and DiscriminatorMapping annotation tests
-        // Basic properties
-        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.default", equalTo("Dog"));
-        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.enum", hasItems("Cat", "Dog", "Lizard"));
-        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.externalDocs.description", equalTo("Pet Types"));
-        vr.body("paths.'/pet/findByTags'.get.parameters.find{ it.name == 'tags' }.schema.deprecated", equalTo(true));
-        vr.body("paths.'/store/order/{orderId}'.get.responses.'900'.schema", nullValue());
-
-        // Numerical properties
-        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.maximum", equalTo(101));
-        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.exclusiveMaximum", equalTo(true));
-        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.minimum", equalTo(9));
-        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.exclusiveMinimum", equalTo(true));
-        vr.body("paths.'/pet/{petId}'.get.parameters.find{ it.name == 'petId' }.schema.multipleOf", equalTo(10));
-
-        // String properties
-        vr.body("paths.'/pet/{petId}'.delete.parameters.find{ it.name == 'apiKey' }.schema.maxLength", equalTo(256));
-        vr.body("paths.'/pet/{petId}'.delete.parameters.find{ it.name == 'apiKey' }.schema.minLength", equalTo(32));
-
-        // Other properties
-        String storeOrderResponses = "paths.'/store/order/{orderId}'.get.responses";
-        vr.body("paths.'/pet/{petId}'.get.responses.'200'.content.'application/json'.schema.readonly", equalTo(true));
-        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.anyOf",
-                hasItems("#/components/schemas/Order", "#/components/schemas/BadOrder"));
-        vr.body(storeOrderResponses + ".'200'.content.'application/json'.schema.allOf",
-                hasItems("#/components/schemas/Order", "#/components/schemas/Pet"));
-        vr.body("paths.'/pet/{petId}'.get.responses.'200'.content.'application/json'.schema.oneOf",
-                hasItems("#/components/schemas/Cat", "#/components/schemas/Dog", "#/components/schemas/Lizard"));
-        vr.body(storeOrderResponses + ".'200'.content.'application/json'.schema.not", equalTo("#/components/schemas/BadOrder"));
-        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.discriminatorProperty", equalTo("id"));
-        vr.body(storeOrderResponses + ".'404'.content.'application/json'.schema.discriminatorMapping",
-                hasEntry("0", "#/components/schemas/BadOrder"));
-    }
-
-    @RunAsClient
-    @Test(dataProvider = "formatProvider")
-    public void testExtension(String type) {
-        // Extension annotation tests
-        ValidatableResponse vr = callEndpoint(type);
-
-        // extension on field
-        String componentExt = "components.schemas.User.extensions";
-        vr.body(componentExt, hasSize(3));
-        vr.body(componentExt + ".find{ it.name == 'x-mp-field1'}", equalTo(true));
-        vr.body(componentExt + ".find{ it.name == 'x-mp-field2'}", equalTo(true));
-        vr.body(componentExt + ".find{ it.name == 'x-mp-field3'}", equalTo(false));
-
-        // extension on method
-        String pathExt = "paths.'/pet/findByStatus'.get.extensions";
-        vr.body(pathExt, hasSize(3));
-        vr.body(pathExt + ".find{ it.name == 'x-mp-method1'}", equalTo(true));
-        vr.body(pathExt + ".find{ it.name == 'x-mp-method2'}", equalTo(true));
-        vr.body(pathExt + ".find{ it.name == 'x-mp-method3'}", equalTo(false));
-
-        // extension on parameter
-        String parmExt = "paths.'/pet/findByStatus'.parameters.find{ it.name == 'status' }.extensions";
-        vr.body(parmExt, hasSize(1));
-        vr.body(parmExt + ".find{ it.name == 'x-mp-parm1'}", equalTo(true));
-
-        // extension on type: app class
-        vr.body("extensions", hasSize(3));
-        vr.body("extensions.find{ it.name == 'x-mp-openapi1'}", equalTo(true));
-        vr.body("extensions.find{ it.name == 'x-mp-openapi2'}", equalTo(true));
-        vr.body("extensions.find{ it.name == 'x-mp-openapi3'}", equalTo(false));
-
-        // extension on type: resource class
-        endpointExtension(vr, "'/store/inventory'.get");
-        endpointExtension(vr, "'/store/order/{orderId}'.get");
-        endpointExtension(vr, "'/store/order'.post");
-        endpointExtension(vr, "'/store/order/{orderId}'.delete");
-    }
-
-    private void endpointExtension(ValidatableResponse vr, String endpoint) {
-        String ext1 = ".find{ it.name == 'x-mp-type1' }";
-        String ext2 = ".find{ it.name == 'x-mp-type2' }";
-        vr.body("paths." + endpoint + ".extensions", hasSize(2));
-        vr.body("paths." + endpoint + ".extensions" + ext1, equalTo(true));
-        vr.body("paths." + endpoint + ".extensions" + ext2, equalTo(false));
-    }
-}