Merge branch 'master' of
https://gitbox.apache.org/repos/asf/juneau-petstore.git

Conflicts:
	Dockerfile
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
index 5db76c5..76d184f 100644
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/PetStore.java
@@ -12,7 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.petstore;
 
-import static org.apache.juneau.http.HttpMethodName.*;
+import static org.apache.juneau.http.HttpMethod.*;
 
 import java.util.*;
 
diff --git a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
index 40c1222..c7fb76b 100644
--- a/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
+++ b/juneau-petstore-api/src/main/java/org/apache/juneau/petstore/dto/Pet.java
@@ -71,7 +71,7 @@
 		this.name = x.getName();
 		this.price = x.getPrice();
 		this.species = x.getSpecies();
-		this.tags = x.getTags() == null ? null : Arrays.asList(x.getTags());
+		this.tags = new ArrayList<>(Arrays.asList(x.getTags()));
 		return this;
 	}
 
@@ -86,7 +86,7 @@
 		this.name = x.getName();
 		this.price = x.getPrice();
 		this.species = x.getSpecies();
-		this.tags = x.getTags() == null ? null : Arrays.asList(x.getTags());
+		this.tags = x.getTags() == null ? null : new ArrayList<>(Arrays.asList(x.getTags()));
 		this.status = x.getStatus();
 		return this;
 	}
@@ -180,7 +180,7 @@
 	 * @return This object (for method chaining).
 	 */
 	public Pet tags(String...value) {
-		this.tags = Arrays.asList(value);
+		this.tags = new ArrayList<>(Arrays.asList(value));
 		return this;
 	}
 
diff --git a/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java b/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
index 47b1fce..7560b14 100644
--- a/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
+++ b/juneau-petstore-client/src/main/java/org/apache/juneau/petstore/Main.java
@@ -17,16 +17,11 @@
 import java.io.*;
 import java.util.*;
 
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.petstore.dto.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 
 /**
  * Example code showing how to connect to the PetStore application using a remote proxy.
@@ -39,36 +34,22 @@
 
 	private static final JsonParser JSON_PARSER = JsonParser.create().ignoreUnknownBeanProperties().build();
 
-	@SuppressWarnings("deprecation")
-	public static void main(String[] args) {
+	public static void main(String[] args) throws ParseException, IOException {
 
-		// TODO - This is broken until we can update to Juneau 8.1.3 which has a fix for handling how Spring Security
-		// processes Basic Auth requests.
+		RestClient restClient = RestClient.create().simpleJson().basicAuth("localhost", 5000, "admin", "password").build();
 
-		// Set up BASIC auth.
-		// User/passwords are hardcoded in SpringSecurityConfig.
-		Credentials up = new UsernamePasswordCredentials("admin", "password");
-		CredentialsProvider p = new BasicCredentialsProvider();
-		p.setCredentials(AuthScope.ANY, up);
+		// Instantiate our proxy.
+		PetStore petStore = restClient.getRemote(PetStore.class, "http://localhost:5000");
 
-		// Create a RestClient with JSON serialization support.
-		try (RestClient rc = RestClient.create(SimpleJsonSerializer.class, JsonParser.class).defaultCredentialsProvider(p).build()) {
+		// Print out the pets in the store.
+		Collection<Pet> pets = petStore.getPets();
 
-			// Instantiate our proxy.
-			PetStore petStore = rc.getRemote(PetStore.class, "http://localhost:5000");
+		// Pretty-print them to SYSOUT.
+		SimpleJson.DEFAULT_READABLE.println(pets);
 
-			// Print out the pets in the store.
-			Collection<Pet> pets = petStore.getPets();
+		// Initialize the application through REST calls.
+		init(new PrintWriter(System.out), petStore);
 
-			// Pretty-print them to SYSOUT.
-			SimpleJson.DEFAULT_READABLE.println(pets);
-
-			// Initialize the application through REST calls.
-			init(new PrintWriter(System.out), petStore);
-
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
 	}
 
 	/**
diff --git a/juneau-petstore-server/pom.xml b/juneau-petstore-server/pom.xml
index b9f2320..f90efeb 100644
--- a/juneau-petstore-server/pom.xml
+++ b/juneau-petstore-server/pom.xml
@@ -41,7 +41,7 @@
 
         <maven.javadoc.skip>true</maven.javadoc.skip>
 
-        <juneau.version>8.1.2</juneau.version>
+        <juneau.version>8.2.0</juneau.version>
         <javax.inject.version>1</javax.inject.version>
         <servlet.version>3.1.0</servlet.version>
         <hibernate.version>5.0.9.Final</hibernate.version>
@@ -122,7 +122,7 @@
         <dependency>
            <groupId>org.apache.juneau</groupId>
            <artifactId>juneau-rest-mock</artifactId>
-           <version>8.1.2</version>
+           <version>${juneau.version}</version>
            <scope>test</scope>
         </dependency>
      
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
index 5afbec2..a124a63 100644
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/App.java
@@ -12,10 +12,14 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.petstore;
 
+import java.io.*;
+
+import org.apache.juneau.petstore.service.*;
 import org.apache.juneau.rest.springboot.JuneauRestInitializer;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.*;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 
 /**
@@ -28,12 +32,18 @@
 public class App {
 
 	public static void main(String[] args) {
-        new App().start(args);
-    }
+		new App().start(args);
+	}
 
-    protected void start(String[] args) {
-        new SpringApplicationBuilder(App.class)
-        	.initializers(new JuneauRestInitializer(App.class)) // Needed for Juneau resources as injectible Spring beans.
-        	.run(args);
-    }
+	protected void start(String[] args) {
+		ConfigurableApplicationContext ctx = new SpringApplicationBuilder(App.class)
+			.initializers(new JuneauRestInitializer(App.class)) // Needed for Juneau resources as injectible Spring beans.
+			.run(args);
+
+		try {
+			ctx.getBean(PetStoreService.class).initDirect(new PrintWriter(System.out));
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
 }
diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
index 0d2dbcc..84bd414 100644
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/PetStoreResource.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.petstore.rest;

 

 import static org.apache.juneau.dto.swagger.ui.SwaggerUI.*;

-import static org.apache.juneau.http.HttpMethodName.*;

+import static org.apache.juneau.http.HttpMethod.*;

 import static org.apache.juneau.http.response.Ok.*;

 

 import java.util.*;

diff --git a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
index c836f13..a2b5127 100644
--- a/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
+++ b/juneau-petstore-server/src/main/java/org/apache/juneau/petstore/rest/RootResources.java
@@ -16,7 +16,6 @@
 import org.apache.juneau.rest.*;

 import org.apache.juneau.rest.annotation.*;

 import org.apache.juneau.rest.widget.*;

-import org.apache.juneau.serializer.annotation.*;

 

 /**

  * Sample REST resource showing how to implement a "router" resource page.

diff --git a/juneau-petstore-server/src/main/resources/htdocs/images/asf.png b/juneau-petstore-server/src/main/resources/htdocs/images/asf.png
new file mode 100644
index 0000000..ce28113
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/images/asf.png
Binary files differ
diff --git a/juneau-petstore-server/src/main/resources/htdocs/images/juneau.png b/juneau-petstore-server/src/main/resources/htdocs/images/juneau.png
new file mode 100644
index 0000000..42a1656
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/images/juneau.png
Binary files differ
diff --git a/juneau-petstore-server/src/main/resources/htdocs/styles/SwaggerUI.css b/juneau-petstore-server/src/main/resources/htdocs/styles/SwaggerUI.css
new file mode 100644
index 0000000..b55ffc6
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/styles/SwaggerUI.css
@@ -0,0 +1,342 @@
+/*
+ ***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+ * to you 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                                                              *
+ *                                                                                                                         *
+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+ *                                                                                                                         *
+ * 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.                                              *
+ ***************************************************************************************************************************
+*/
+
+.swagger-ui {	
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Header key-value pairs
+ ----------------------------------------------------------------------------------------------------------*/
+
+.swagger-ui table.header {
+    margin-bottom: 15px;
+	width: 95%;
+	border: none;
+}
+
+.swagger-ui table.header * {
+	vertical-align: middle;
+}
+
+.swagger-ui table.header th {
+    font-weight: bold;
+    padding: 5px 10px;
+    text-align: left;
+    white-space: nowrap;
+	border: none;
+	border-radius: 3px;
+}
+
+.swagger-ui table.header td {
+	padding: 5px 10px;
+    text-align: left;
+    vertical-align: middle;
+	border: none;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Method buttons (e.g GET/PUT/... buttons)                                                                
+ ----------------------------------------------------------------------------------------------------------*/
+.method-button {
+  	display: inline-block;
+    font-weight: bold;
+    min-width: 60px;
+    padding: 6px 15px;
+    text-align: center;
+    border-radius: 3px;
+    text-shadow: 0 1px 0 rgba(0,0,0,.1);
+    color: #fff;
+}
+.get .method-button        { background: rgb(97,175,254); }
+.put .method-button        { background: rgb(252,161,48); }
+.post .method-button       { background: rgb(73,204,144); }
+.delete .method-button     { background: rgb(249,62,62); }
+.options .method-button    { background: rgb(153,102,255); }
+.deprecated .method-button { background: rgb(170,170,170); }
+.model .method-button      { background: rgb(150,150,150); min-width: 120px;}
+.other .method-button      { background: rgb(230,230,0); }
+
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Tag block                                                                                                -
+ - Encapsulates one or more op-blocks.
+ ----------------------------------------------------------------------------------------------------------*/
+
+.tag-block {
+	min-width: 800px;
+}
+
+.tag-block-summary {
+	margin: 10px 0px;
+	padding: 5px 0px;
+    align-items: center;
+    cursor: pointer;
+	border-bottom: 1px solid rgba(59,65,81,.2);
+	user-select: none;
+	transition: all .2s;
+}
+.tag-block-summary:hover {
+	background-color: rgba(59,65,81,.1);
+}
+
+.tag-block-summary .name {
+	font-size: 18px;
+	padding: 0px 20px;
+}
+.tag-block-summary .description {
+	font-size: 14px;
+	padding: 0px 20px;
+}
+.tag-block-summary .extdocs {
+	float: right;
+	font-size: 14px;
+	padding: 0px 20px;
+}
+
+.tag-block-open .tag-block-contents { display: block; }
+.tag-block-closed .tag-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block                                                                                          
+ - Encapsulates a single http-method + http-path
+ ----------------------------------------------------------------------------------------------------------*/
+
+.op-block {
+	margin-bottom: 10px;
+    align-items: center;
+    border-radius: 4px;
+}
+
+.op-block.get        { background: rgba(97,175,254,.1); border: 1px solid rgb(97,175,254); }
+.op-block.put        { background: rgba(252,161,48,.1); border: 1px solid rgb(252,161,48); }
+.op-block.post       { background: rgba(73,204,144,.1); border: 1px solid rgb(73,204,144); }
+.op-block.options    { background: rgba(153,102,255,.1); border: 1px solid rgb(153,102,255); }
+.op-block.delete     { background: rgba(249,62,62,.1); border: 1px solid rgb(249,62,62); }
+.op-block.deprecated { background: rgba(170,170,170,.1); border: 1px solid rgb(170,170,170); }
+.op-block.model      { background: rgba(0,0,0,.05); border: 1px solid rgb(170,170,170); }
+.op-block.other      { background: rgba(230,230,0,0.1); border: 1px solid rgb(230,230,0); }
+
+.op-block-summary {	
+	padding: 5px;
+    cursor: pointer;
+	user-select: none;
+}
+
+.op-block-summary .path {
+	font-size: 14px;
+	word-break: break-all;
+    font-family: monospace;
+    font-weight: bold;
+    padding:10px;
+}
+
+.op-block.deprecated .op-block-summary .path { color: #8f9199; text-decoration: line-through;}
+.op-block.deprecated .op-block-summary .description { color: #8f9199 }
+
+.op-block-summary .summary {
+    font-size: 14px;
+    padding: 10px;
+}
+
+.op-block-description {
+    font-size: 14px;
+    padding: 10px;
+}
+
+
+.op-block-open .op-block-contents { display: block; }
+.op-block-closed .op-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block section header                                                                                               -
+ - 'Parameters' and 'Responses' subsections in an op-block
+ ----------------------------------------------------------------------------------------------------------*/
+
+.op-block-section-header {
+    padding: 8px 15px;
+    background: hsla(0,0%,100%,.3);
+    box-shadow: 1px 2px 3px rgba(0,0,0,.3);
+    margin: 10px;
+    border-radius: 4px;
+}
+
+.op-block-section-header .title {
+    font-size: 14px;
+    margin: 0px;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameters and Responses sections
+ ----------------------------------------------------------------------------------------------------------*/
+
+table.parameters, table.responses {
+    border-collapse: collapse;
+    margin: 20px;
+	width: 95%;
+	border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+th.parameter-key, th.response-key {
+	font-size: 12px;
+    font-weight: bold;
+    text-align: left;
+	border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+	background-color: inherit;
+}
+
+td.parameter-key, td.response-key {
+	font-size: 12px;
+    padding: 10px;
+    text-align: left;
+	border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+	background-color: inherit;
+}
+
+td.parameter-value, td.response-value {
+    padding: 10px;
+    text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameter name
+ ----------------------------------------------------------------------------------------------------------*/
+
+.parameter-key .in {
+	font-size: 12px;
+    font-family: monospace;
+    font-weight: bold;
+    font-style: italic;
+    color: gray;
+}
+
+.parameter-key .name {
+	font-size: 14px;
+}
+
+.parameter-key .name.required {
+    font-weight: bold;
+}
+
+.parameter-key .requiredlabel {
+	font-size: 10px;
+    color: rgba(255,0,0,.6);    
+    font-weight: bold;
+}
+
+.parameter-key .type {
+    font-size: 12px;
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Examples
+ ----------------------------------------------------------------------------------------------------------*/
+ 
+.op-block-contents .example-select {
+    margin: 10px 0 5px 0;
+	border-width: 1px;
+	font-weight:bold;
+    padding: 5px 40px 5px 10px;
+    border: 1px solid #41444e;
+    border-radius: 4px;
+    box-shadow: 0 1px 2px 0 rgba(0,0,0,.25);
+    background: hsla(0,0%,100%,.3);
+}
+
+.op-block-contents .example-select:disabled {
+    color: rgba(0,0,0,.50);
+    border: 1px solid rgba(0,0,0,.50);
+}
+
+.op-block-contents .example {
+    margin: 0;
+    padding: 5px 20px;
+    white-space: pre-wrap;
+    word-wrap: break-word;
+    hyphens: auto;
+    border-radius: 4px;
+    background: #41444e;
+    overflow-wrap: break-word;
+    font-family: monospace;
+    font-weight: 400;
+    color: limegreen;
+	display: none;
+	max-width: 800px;
+	max-height: 800px;
+	text-overflow: auto;
+	overflow: auto;
+}
+
+.op-block-contents .example.active {
+	display:block;
+}
+
+.op-block-contents .model {
+	display: none;
+}
+
+.op-block-contents .model.active {
+	display:block;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Headers
+ ----------------------------------------------------------------------------------------------------------*/
+
+.section {
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.headers .name {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+div.headers {
+	margin: 20px 0px;
+}
+
+.headers .type {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+.section-name {
+	display: inline-block;
+	vertical-align: top;
+	margin-right: 20px;
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.section-table {
+/*	display: inline-block;*/
+}
+
+.responses .section-table td {
+	padding: 5px 20px 5px 0px;
+	text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
diff --git a/juneau-petstore-server/src/main/resources/htdocs/themes/dark.css b/juneau-petstore-server/src/main/resources/htdocs/themes/dark.css
new file mode 100644
index 0000000..0a34995
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/themes/dark.css
@@ -0,0 +1,285 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+ * to you 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                                                              *
+ *                                                                                                                         *
+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+ *                                                                                                                         *
+ * 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.                                              *
+ ***************************************************************************************************************************/
+ 
+/** Dark look-and-feel */ 
+ 
+/**********************************************************************************************************************/
+/**  Body                                                                                                            **/
+/**********************************************************************************************************************/
+
+body {
+	background-color: #212121 ;
+	margin: 0px;
+	font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
+	color: #EEE;
+	height: 100%;
+}
+
+body {
+	font-size: 14px;
+}
+
+body textarea, body pre {
+	-moz-tab-size: 3; 
+	-o-tab-size: 3; 
+	-webkit-tab-size: 3; 
+	tab-size: 3; 
+}
+
+/**********************************************************************************************************************/
+/**  Header                                                                                                        **/
+/**********************************************************************************************************************/
+
+header {
+	background-color: #373a3c;
+}
+
+header * {
+    font-size: 14px;
+	color: #B3B3B3;
+	margin: 0px;
+	text-decoration: none;
+	font-weight: normal;
+}
+
+header h1 {
+	padding: 10px 20px;
+	font-size: 16px;
+	border-bottom: 2px solid #000000;
+	color: white;
+}
+
+header h2 {
+	padding: 10px 20px;
+	font-size: 14px;
+	border-bottom: 2px solid #000000;
+}
+
+/**********************************************************************************************************************/
+/**  Nav                                                                                                             **/
+/**********************************************************************************************************************/
+
+nav {
+	margin: 10px 20px 10px 20px;
+	color: #94A3AB;
+}
+
+nav>ol {
+	list-style-type: none;
+	margin: 0px 10px;
+	padding: 0px;
+}
+
+nav>ol>li {
+	display: inline;
+}
+
+nav li:not(:first-child):before {
+	content: " - ";
+}
+
+nav a {
+	font-size: 10pt;
+	color: #94A3AB;
+	text-decoration: none;
+	margin: 0px 15px;
+	text-transform: uppercase;
+	cursor: pointer;
+}
+
+nav a:active, nav a:hover {
+	color: white;
+	text-decoration: underline;
+}
+
+/**********************************************************************************************************************/
+/**  Content                                                                                                        **/
+/**********************************************************************************************************************/
+
+section {
+	display: table;
+	width: 100%;
+}
+
+article {
+	display: table-cell;
+}
+
+article * {
+	font-size: 9pt;
+	color: #EEE;
+}
+
+article textarea, article input, article button {
+	color: #111;
+}
+
+article textarea, article input {
+	background-color: #EEE;
+}
+
+article div.data {
+	padding: 10px;
+	background-color: #373a3c;
+	border-radius: 4px;
+	margin: 20px;
+	display: inline-block;
+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+	font-family: sans-serif;
+}
+
+article table {
+	border: none;
+	width: 100%;
+}
+
+article th {
+	padding: 4px 8px;
+	font-weight: normal;
+	text-align: center;
+	background-color: #0275d8;
+}
+
+article td {
+	vertical-align: top;
+	border-bottom: 1px solid #000000;
+	border-right: 1px solid #000000;
+	padding: 2px 5px;
+}
+
+article td:last-child {
+    width: 100%;
+}
+
+article ul {
+	margin: 0px;
+	padding-left: 20px;
+}
+
+article a {
+	color: #3d8bb5;
+	text-decoration: none;
+}
+
+article a:hover {
+	text-decoration: underline;
+}
+
+article iframe {
+	background-color: #F6F7F9;
+	border: 1px solid gray;
+	padding: 0px;
+	overflow: hidden;
+	width: 100%;
+	min-height: 400px;
+}
+
+aside {
+	display: table-cell;
+	vertical-align: top;
+	padding: 20px 20px;
+}
+
+/**********************************************************************************************************************/
+/**  Footer                                                                                                          **/
+/**********************************************************************************************************************/
+
+footer { 
+	padding: 10px;
+	width: 100%;
+	bottom: 0;
+	position: fixed;
+	background-color: #373a3c;
+	border-top: 2px solid #000000;
+}
+
+/**********************************************************************************************************************/
+/**  Popup windows                                                                                                   **/
+/**********************************************************************************************************************/
+
+.popup-content {
+	display: none;
+	position: absolute;
+	background-color: #DDD;
+	white-space: nowrap;
+	padding: 5px;
+	box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
+	z-index: 1;
+	margin-top: 10px;
+	border-radius: 4px;
+}
+
+.popup-content * {
+	color: black;
+	font-size: 11px;
+}
+
+.popup-content a:hover {
+	color: #94A3AB;
+}
+
+.popup-show {
+	display:block;
+}
+
+/**********************************************************************************************************************/
+/**  Tooltips                                                                                                        **/
+/**********************************************************************************************************************/
+
+.tooltip {
+	position: relative;
+	display: inline-block;	    
+}
+
+.tooltip .tooltiptext {
+	visibility: hidden;
+	background-color: #FEF9E7;
+	color: black;
+	padding: 5px;
+	border-radius: 6px;
+	position: absolute;
+	z-index: 1;
+	top: 0;
+	left: 0;
+	margin-left: 30px;
+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);
+	opacity: 0;
+	transition: opacity 0.5s;
+	font-weight: normal;
+}
+
+.tooltip .tooltiptext * {
+	color: black;
+}
+
+.tooltip:hover .tooltiptext {
+	visibility: visible;
+	opacity: 1;
+}	
+
+.tooltiptext {
+	white-space: nowrap;
+	float: left;
+	border: 1px solid black;
+}
+
+/**********************************************************************************************************************/
+/**  Other classes                                                                                                   **/
+/**********************************************************************************************************************/
+
+.table {display:table;}
+.row {display:table-row;}
+.cell {display:table-cell;}
+.monospace {font-family:monospace;}
+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}
+.link:hover { text-decoration: underline; }
diff --git a/juneau-petstore-server/src/main/resources/htdocs/themes/devops.css b/juneau-petstore-server/src/main/resources/htdocs/themes/devops.css
new file mode 100644
index 0000000..d757a92
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/themes/devops.css
@@ -0,0 +1,275 @@
+/***************************************************************************************************************************

+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *

+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *

+ * to you 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                                                              *

+ *                                                                                                                         *

+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *

+ *                                                                                                                         *

+ * 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.                                              *

+ ***************************************************************************************************************************/

+ 

+/** DevOps look-and-feel */ 

+ 

+/**********************************************************************************************************************/

+/**  Body                                                                                                            **/

+/**********************************************************************************************************************/

+

+body {

+	background-color: #3B4B54;

+	margin: 0px;

+	font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;

+	color: #B3B3B3;

+	height: 100%;	

+}

+

+body {

+	font-size: 14px;

+}

+

+body textarea, body pre {

+	-moz-tab-size: 3; 

+	-o-tab-size: 3; 

+	-webkit-tab-size: 3; 

+	tab-size: 3; 

+}

+

+/**********************************************************************************************************************/

+/**  Header                                                                                                        **/

+/**********************************************************************************************************************/

+

+header {

+	background-color: #26343F;

+}

+

+header * {

+    font-size: 14px;

+	color: #B3B3B3;

+	margin: 0px;

+	text-decoration: none;

+	font-weight: normal;

+}

+

+header h1 {

+	padding: 10px 20px;

+	font-size: 16px;

+	border-bottom: 2px solid #34534B;

+	color: white;

+}

+

+header h2 {

+	padding: 10px 20px;

+	font-size: 14px;

+	border-bottom: 2px solid #34534B;

+}

+

+/**********************************************************************************************************************/

+/**  Nav                                                                                                             **/

+/**********************************************************************************************************************/

+

+nav {

+	margin: 10px 20px 10px 20px;

+	color: #94A3AB;

+}

+

+nav>ol {

+	list-style-type: none;

+	margin: 0px 10px;

+	padding: 0px;

+}

+

+nav>ol>li {

+	display: inline;

+}

+

+nav li:not(:first-child):before {

+	content: " - ";

+}

+

+nav a {

+	font-size: 10pt;

+	color: #94A3AB;

+	text-decoration: none;

+	margin: 0px 15px;

+	text-transform: uppercase;

+	cursor: pointer;

+}

+

+nav a:active, nav a:hover {

+	color: white;

+	text-decoration: underline;

+}

+

+/**********************************************************************************************************************/

+/**  Content                                                                                                        **/

+/**********************************************************************************************************************/

+

+section {

+	display: table;

+	width: 100%;

+}

+

+article {

+	display: table-cell;

+}

+

+article * {

+	font-size: 9pt;

+	color: #26343F;

+}

+

+article div.data {

+	padding: 10px;

+	background-color: white;

+	border-radius: 4px;

+	margin: 20px;

+	display: inline-block;

+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);

+	font-family: sans-serif;

+	color: #26343F;

+}

+

+article table {

+	border: none;

+	width: 100%;

+}

+

+article th {

+	border-top: 1px solid #D9DCDE;

+	padding: 4px 8px;

+	font-weight: bold;

+	text-align: center;

+	background-color: #F4F6F9;

+}

+

+article td {

+	vertical-align: top;

+	border-bottom: 1px solid #d9dcde;

+	border-right: 1px solid #d9dcde;

+	padding: 2px 5px;

+}

+

+article td:last-child {

+    width: 100%;

+}

+

+article ul {

+	margin: 0px;

+	padding-left: 20px;

+}

+

+article a {

+	color: #116998;

+	text-decoration: none;

+}

+

+article a:hover {

+	text-decoration: underline;

+}

+

+article iframe {

+	background-color: #F6F7F9;

+	border: 1px solid gray;

+	padding: 0px;

+	overflow: hidden;

+	width: 100%;

+	min-height: 400px;

+}

+

+aside {

+	display: table-cell;

+	vertical-align: top;

+	padding: 20px 20px;

+}

+

+/**********************************************************************************************************************/

+/**  Footer                                                                                                          **/

+/**********************************************************************************************************************/

+

+footer { 

+	padding: 10px;

+	width: 100%;

+	bottom: 0;

+	position: fixed;

+	background-color: #26343F;

+}

+

+/**********************************************************************************************************************/

+/**  Popup windows                                                                                                   **/

+/**********************************************************************************************************************/

+

+.popup-content {

+	display: none;

+	position: absolute;

+	background-color: #f4f6f9;

+	white-space: nowrap;

+	padding: 5px;

+	box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);

+	z-index: 1;

+	margin-top: 10px;

+	border-radius: 4px;

+}

+

+.popup-content * {

+	color: black;

+	font-size: 11px;

+}

+

+.popup-content a:hover {

+	color: #94A3AB;

+}

+

+.popup-show {

+	display:block;

+}

+

+/**********************************************************************************************************************/

+/**  Tooltips                                                                                                        **/

+/**********************************************************************************************************************/

+

+.tooltip {

+	position: relative;

+	display: inline-block;	    

+}

+

+.tooltip .tooltiptext {

+	visibility: hidden;

+	background-color: #FEF9E7;

+	color: black;

+	padding: 5px;

+	border-radius: 6px;

+	position: absolute;

+	z-index: 1;

+	top: 0;

+	left: 0;

+	margin-left: 30px;

+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);

+	opacity: 0;

+	transition: opacity 0.5s;

+	font-weight: normal;

+}

+

+.tooltip:hover .tooltiptext {

+	visibility: visible;

+	opacity: 1;

+}	

+

+.tooltiptext {

+	white-space: nowrap;

+	float: left;

+	border: 1px solid black;

+}

+

+/**********************************************************************************************************************/

+/**  Other classes                                                                                                   **/

+/**********************************************************************************************************************/

+

+.table {display:table;}

+.row {display:table-row;}

+.cell {display:table-cell;}

+.monospace {font-family:monospace;}

+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}

+.link:hover { text-decoration: underline; }

+

diff --git a/juneau-petstore-server/src/main/resources/htdocs/themes/light.css b/juneau-petstore-server/src/main/resources/htdocs/themes/light.css
new file mode 100644
index 0000000..3875da3
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/themes/light.css
@@ -0,0 +1,272 @@
+/***************************************************************************************************************************

+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *

+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *

+ * to you 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                                                              *

+ *                                                                                                                         *

+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *

+ *                                                                                                                         *

+ * 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.                                              *

+ ***************************************************************************************************************************/

+ 

+/** Light look-and-feel */ 

+ 

+/**********************************************************************************************************************/

+/**  Body                                                                                                            **/

+/**********************************************************************************************************************/

+

+body {

+	margin: 0px;

+	font-size: 10px;

+	font-family: HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;

+	color: #2c4557;

+	height: 100%;	

+}

+

+body * {

+	font-size: 14px;

+}

+

+body textarea, body pre {

+	-moz-tab-size: 3; 

+	-o-tab-size: 3; 

+	-webkit-tab-size: 3; 

+	tab-size: 3; 

+}

+

+/**********************************************************************************************************************/

+/**  Header                                                                                                          **/

+/**********************************************************************************************************************/

+

+header {

+	background-color: #e8ebef;

+	padding: 10px 20px;

+	box-shadow: 5px 5px 2px #999999;

+	text-shadow: rgba(1,1,1,.2) 2px 4px 5px, rgba(125,32,191,.05) 0 -10px 30px;

+	white-space: nowrap;

+}

+

+header * {

+	color: #af2222;;

+	font-weight: lighter;

+}

+

+header h1 {

+	font-size: 18px;

+	margin: 0px;

+	padding: 2px;

+}

+

+header h2 {

+	font-size: 14px;

+	margin: 0px;

+	padding: 2px;

+}

+

+/**********************************************************************************************************************/

+/**  Nav                                                                                                             **/

+/**********************************************************************************************************************/

+

+nav {

+	margin: 10px;

+	padding: 5px;

+	box-shadow: 5px 5px 2px #999999;

+	background-color: #eef3f7;

+}

+

+nav * {

+	font-size: 12px;

+	font-weight: lighter;

+}

+

+nav>ol {

+	list-style-type: none;

+	margin: 0px 10px;

+	padding: 0px;

+}

+

+nav>ol>li {

+	display: inline;

+}

+

+nav li:not(:first-child):before {

+	content: " - ";

+}

+

+nav a {

+	font-size: 10pt;

+	color: #2c4557;

+	text-decoration: none;

+	margin: 0px 10px;

+	text-transform: uppercase;

+	cursor: pointer;

+}

+

+nav a:active, nav a:hover {

+	text-decoration: none;

+	color: #94a3ab;

+}

+

+/**********************************************************************************************************************/

+/**  Content                                                                                                         **/

+/**********************************************************************************************************************/

+

+section {

+	display: table;

+	width: 100%;

+}

+

+article {

+	display: table-cell;

+	padding: 20px 40px;

+}

+

+article * {

+	font-size: 9pt;

+}

+

+article div.data {

+	padding: 0px;

+	margin: 0px;

+	display: inline-block;

+	font-family: sans-serif;

+}

+

+article table {

+	border: none;

+	width: 100%;

+}

+

+article td {

+	vertical-align: top;

+	border-bottom: 1px solid #d9dcde;

+	border-right: 1px solid #d9dcde;

+	padding: 2px 5px;

+}

+

+article td:last-child {

+    width: 100%;

+}

+

+article th {

+	padding: 4px 8px;

+	text-align: center;

+	background-color: #eef3f7;

+	box-shadow: 1px 1px 2px #999999;

+}

+

+article ul {

+	margin: 0px;

+	padding-left: 20px;

+}

+

+article a {

+	color: #416e8e;

+	text-decoration: none;

+}

+

+article iframe {

+	background-color: #F6F7F9;

+	border: 1px solid gray;

+	padding: 0px;

+	overflow: hidden;

+	width: 100%;

+	min-height: 400px;

+}

+

+aside {

+	display: table-cell;

+	vertical-align: top;

+	padding: 20px 20px;

+}

+

+/**********************************************************************************************************************/

+/**  Footer                                                                                                          **/

+/**********************************************************************************************************************/

+

+footer { 

+	padding: 10px;

+	width: 100%;

+	bottom: 0;

+	position: fixed;

+	background-color: #e8ebef;

+}

+

+/**********************************************************************************************************************/

+/**  Popup windows                                                                                                   **/

+/**********************************************************************************************************************/

+

+.popup-content {

+	display: none;

+	position: absolute;

+	background-color: #eef3f7;

+	white-space: nowrap;

+	padding: 5px;

+	box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);

+	z-index: 1;

+	margin-top: 10px;

+	border-radius: 4px;

+}

+

+.popup-content * {

+	color: #2c4557;

+	font-size: 10pt;

+}

+

+.popup-content a:hover {

+	color: #94A3AB;

+}

+

+.popup-show {

+	display: block;

+}

+

+/**********************************************************************************************************************/

+/**  Tooltips                                                                                                        **/

+/**********************************************************************************************************************/

+

+.tooltip {

+	position: relative;

+	display: inline-block;	    

+}

+

+.tooltip .tooltiptext {

+	visibility: hidden;

+	background-color: #FEF9E7;

+	color: black;

+	padding: 5px;

+	border-radius: 6px;

+	position: absolute;

+	z-index: 1;

+	top: 0;

+	left: 0;

+	margin-left: 30px;

+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);

+	opacity: 0;

+	transition: opacity 0.5s;

+	font-weight: normal;

+}

+

+.tooltip:hover .tooltiptext {

+	visibility: visible;

+	opacity: 1;

+}	

+

+.tooltiptext {

+	white-space: nowrap;

+	float: left;

+	border: 1px solid black;

+}

+

+/**********************************************************************************************************************/

+/**  Other classes                                                                                                   **/

+/**********************************************************************************************************************/

+

+.table {display:table;}

+.row {display:table-row;}

+.cell {display:table-cell;}

+.monospace {font-family:monospace;}

+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}

+.link:hover { text-decoration: underline; }

diff --git a/juneau-petstore-server/src/main/resources/htdocs/themes/original.css b/juneau-petstore-server/src/main/resources/htdocs/themes/original.css
new file mode 100644
index 0000000..722feb3
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/htdocs/themes/original.css
@@ -0,0 +1,236 @@
+/***************************************************************************************************************************

+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *

+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *

+ * to you 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                                                              *

+ *                                                                                                                         *

+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *

+ *                                                                                                                         *

+ * 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.                                              *

+ ***************************************************************************************************************************/

+

+/** Original look-and-feel */ 

+ 

+/**********************************************************************************************************************/

+/**  Body                                                                                                            **/

+/**********************************************************************************************************************/

+

+body {

+	background-image: linear-gradient(top, #CDDDDF 0, #EAEDED 20px, #FFFFFF 70px);

+	background-image: -webkit-linear-gradient(top, #CDDDDF 0, #EAEDED 20px, #FFFFFF 70px);

+	background-attachment: fixed;

+	font-family: Sans-Serif;

+	color: #2c4557;

+	height: 100%;

+	margin: 0px;

+}

+

+body * {

+	font-size: 12px;

+}

+

+body textarea, body pre {

+	-moz-tab-size: 3; 

+	-o-tab-size: 3; 

+	-webkit-tab-size: 3; 

+	tab-size: 3; 

+}

+

+/**********************************************************************************************************************/

+/**  Header                                                                                                          **/

+/**********************************************************************************************************************/

+

+header {

+	padding: 10px 20px;

+}

+

+header h1 {

+    font-size: 16px;

+	margin-bottom: 10px;

+	margin-right: 40px;

+	padding: 5px 30px;

+	border-radius: 15px;

+	text-decoration: none;

+	font-weight: normal;

+	background: linear-gradient(to bottom, #F5F5F5, #DEE3E9) repeat scroll 0% 0% transparent;

+	background: -webkit-gradient(linear, left top, left bottom, from(#F5F5F5), to(#DEE3E9));

+}

+

+header h2 {

+	font-weight: normal;

+	margin-left: 20px;

+}

+

+/**********************************************************************************************************************/

+/**  Nav                                                                                                             **/

+/**********************************************************************************************************************/

+

+nav {

+	margin: 0px 25px;	

+}

+

+nav>ol {

+	list-style-type: none;

+	margin: 0px 10px;

+	padding: 0px;

+}

+

+nav>ol>li {

+	display: inline;

+}

+

+nav li:not(:first-child):before {

+    content: " - ";

+}

+

+nav a {

+	text-decoration: underline;

+	cursor: pointer;

+	color: -webkit-link;

+}

+

+/**********************************************************************************************************************/

+/**  Content                                                                                                        **/

+/**********************************************************************************************************************/

+

+section {

+	display: table;

+	width: 100%;

+}

+

+article {

+	display: table-cell;

+	padding: 20px 40px;

+}

+

+aside {

+	display: table-cell;

+	vertical-align: top;

+	padding: 20px 20px;

+}

+

+article div.data {

+	padding: 0px;

+	margin: 0px;

+	display: inline-block;

+	font-family: sans-serif;

+}

+

+article table {

+	border:1px solid #CCCC99;

+	border-collapse: collapse;

+	margin: 5px 0px;

+	width: 100%;

+}

+

+article th {

+	border-top: 1px solid #CCCC99;

+	padding: 3px 5px;

+	color: #666666;

+	text-align: center;

+	background-image: linear-gradient(top, #FBF9E4 0%, #F3F2C2 100%);

+	background-image: -webkit-linear-gradient(top, #FBF9E4 0%, #F3F2C2 100%);

+}

+

+article td {

+	border: 1px solid #E9EACB;

+	padding: 2px 5px;

+	color: #005C87;

+	vertical-align: top;

+}

+

+article td:last-child {

+    width: 100%;

+}

+

+article ul {

+	margin: 0px;

+	padding-left: 20px;

+}

+

+/**********************************************************************************************************************/

+/**  Footer                                                                                                          **/

+/**********************************************************************************************************************/

+

+footer { 

+	display: none;

+}

+

+/**********************************************************************************************************************/

+/**  Popup windows                                                                                                   **/

+/**********************************************************************************************************************/

+

+.popup-content {

+	display: none;

+	position: absolute;

+	background-color: #eef3f7;

+	white-space: nowrap;

+	padding: 5px;

+	box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);

+	z-index: 1;

+	margin-top: 10px;

+	border-radius: 4px;

+}

+

+.popup-content * {

+	font-size: 9pt;

+}

+

+.popup-content a:hover {

+	color: #94A3AB;

+}

+

+.popup-show {

+	display: block;

+}

+

+/**********************************************************************************************************************/

+/**  Tooltips                                                                                                        **/

+/**********************************************************************************************************************/

+

+.tooltip {

+	position: relative;

+	display: inline-block;	    

+}

+

+.tooltip .tooltiptext {

+	visibility: hidden;

+	background-color: #FEF9E7;

+	color: black;

+	padding: 5px;

+	border-radius: 6px;

+	position: absolute;

+	z-index: 1;

+	top: 0;

+	left: 0;

+	margin-left: 30px;

+	box-shadow: 2px 3px 3px 0px rgba(0, 0, 0, 0.5);

+	opacity: 0;

+	transition: opacity 0.5s;

+	font-weight: normal;

+}

+

+.tooltip:hover .tooltiptext {

+	visibility: visible;

+	opacity: 1;

+}	

+

+.tooltiptext {

+	white-space: nowrap;

+	float: left;

+	border: 1px solid black;

+}

+

+/**********************************************************************************************************************/

+/**  Other classes                                                                                                   **/

+/**********************************************************************************************************************/

+

+.table {display:table;}

+.row {display:table-row;}

+.cell {display:table-cell;}

+.monospace {font-family:monospace;}

+.link { color: #94A3AB; text-decoration: none; cursor: pointer;}

+.link:hover { text-decoration: underline; }

+

diff --git a/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Orders.json b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Orders.json
new file mode 100644
index 0000000..b306aa8
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Orders.json
@@ -0,0 +1,18 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you 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                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * 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.                                              *
+// ***************************************************************************************************************************
+
+[
+	{id:101,petId:101,shipDate:'2018-01-01',status:'PLACED'},
+	{id:102,petId:102,shipDate:'2018-01-01',status:'APPROVED'},
+	{id:103,petId:103,shipDate:'2018-01-01',status:'DELIVERED'}
+]
diff --git a/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Pets.json b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Pets.json
new file mode 100644
index 0000000..c0aa31f
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Pets.json
@@ -0,0 +1,24 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you 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                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * 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.                                              *
+// ***************************************************************************************************************************
+
+[
+	{species:'CAT', name:'Mr. Frisky', price:39.99, tags:['friendly'], status:'AVAILABLE'},
+	{species:'DOG', name:'Kibbles', price:99.99, tags:['loyal'], status:'AVAILABLE'},
+	{species:'RABBIT', name:'Hoppy', price:49.99, tags:['friendly','smells nice'], status:'AVAILABLE'},
+	{species:'RABBIT', name:'Hoppy 2', price:49.99, status:'AVAILABLE'},
+	{species:'RABBIT', name:'Hoppy 3', price:49.99, status:'AVAILABLE'},
+	{species:'RABBIT', name:'Hoppy 4', price:49.99, status:'AVAILABLE'},
+	{species:'FISH', name:'Gorton', price:1.99, status:'PENDING'},
+	{species:'MOUSE', name:'Hackwrench', price:4.99, status:'SOLD'},
+	{species:'SNAKE', name:'Just Snake', price:9.99, status:'SOLD'}
+]
\ No newline at end of file
diff --git a/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Users.json b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Users.json
new file mode 100644
index 0000000..7f02a3c
--- /dev/null
+++ b/juneau-petstore-server/src/main/resources/org/apache/juneau/petstore/service/init/Users.json
@@ -0,0 +1,18 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you 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                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * 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.                                              *
+// ***************************************************************************************************************************
+
+[
+	{username:'mwatson',firstName:'Marie',lastName:'Watson',email:'marie.watson@fakemail.com',password:'123456',phone:'444-555-7777',userStatus:'ACTIVE'},
+	{username:'dvaughn',firstName:'Daniel',lastName:'Vaughn',email:'daniel.vaughn@test.com',password:'123456',phone:'666-777-3333',userStatus:'ACTIVE'},
+	{username:'bfuller',firstName:'Brenda',lastName:'Fuller',email:'brenda.fuller@example.com',password:'123456',phone:'777-888-3333',userStatus:'INACTIVE'}
+]
diff --git a/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java b/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
index 0416b2a..29a3244 100644
--- a/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
+++ b/juneau-petstore-server/src/test/java/org/apache/juneau/petstore/test/MockTest.java
@@ -1,11 +1,10 @@
 package org.apache.juneau.petstore.test;
 
-import java.io.IOException;
-import javax.servlet.ServletException;
 import org.apache.juneau.petstore.App;
-import org.apache.juneau.petstore.repository.UserRepository;
+import org.apache.juneau.petstore.dto.*;
 import org.apache.juneau.petstore.rest.PetStoreResource;
-import org.apache.juneau.rest.mock2.MockRest;
+import org.apache.juneau.rest.client2.*;
+import org.apache.juneau.rest.mock2.*;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -22,112 +21,99 @@
 
 	@Autowired
 	PetStoreResource petStoreResource;
-	MockRest petStoreRest;
-	UserRepository userRepository;
+
+	private RestClient petStoreRest;
 
 	@Before
 	public void setup() {
-
-		petStoreRest = MockRest.create(petStoreResource).simpleJson().build();
-
+		// Wrap our resource in a MockRest object for testing.
+		petStoreRest = MockRestClient.create(petStoreResource).simpleJson().build();
 	}
 
-	// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+	// -----------------------------------------------------------------------------------------------------------------
 	// Pets
-	// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-	private String createTestPet() throws AssertionError, ServletException, IOException {
+	// -----------------------------------------------------------------------------------------------------------------
 
-		String petId = petStoreRest
-				.post("/pet", "{name:'Sunshine',tags:['nice'], price:100.0,species:'BIRD'}")
-				.execute()
-				.assertStatus(200)
-				.getBodyAsString();
+	private int createTestPet() throws Exception {
+
+		int petId = petStoreRest
+			.post("/pet", new CreatePet().name("Sunshine").price(100f).species(Species.BIRD).tags("nice"))
+			.run()
+			.assertStatus().code().is(200)
+			.getBody().as(int.class);
 
 		return petId;
 	}
 
-	private void deleteTestPets() throws AssertionError, ServletException, IOException {
-
+	private void deleteTestPets() throws Exception {
 		petStoreRest
-		.delete("/pets")
-		.execute()
-		.assertStatus(200);
-
+			.delete("/pets")
+			.complete()  // Use complete() because we're not consuming response.
+			.assertStatus().code().is(200);
 	}
 
 	// Delete pet by Id
-
 	@Test
 	public void testDeletePet() throws Exception {
 
-		String petId = createTestPet();
+		int petId = createTestPet();
 		petStoreRest
-		.delete("/pet/" + petId)
-		.execute()
-		.assertStatus(200);
-
+			.delete("/pet/" + petId)
+			.complete()
+			.assertStatus().code().is(200);
 	}
 
 	// Getting all pets
-
 	@Test
 	public void testGettingPets() throws Exception {
 
-		String petId = createTestPet();
-
+		int petId = createTestPet();
 		petStoreRest
-		.get("/pet")
-		.execute()
-		.assertStatus(200)
-		.assertBody(
-				"[{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}]");
+			.get("/pet")
+			.run()
+			.assertStatus().code().is(200)
+			.assertBody().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',price:100.0,status:'AVAILABLE'}]");
+
 		deleteTestPets();
 	}
 
 	// Posting pet
-
 	@Test
 	public void testPostPet() throws Exception {
 
 		petStoreRest
-		.post("/pet", "{name:'Sunshine',tags:['nice'], price:100.0,species:'BIRD'}")
-		.execute()
-		.assertStatus(200);
+			.post("/pet", new CreatePet().name("Sunshine").price(100f).species(Species.BIRD).tags("nice"))
+			.complete()
+			.assertStatus().code().is(200);
 
 		deleteTestPets();
 	}
 
 	// Find pet by Id
-
 	@Test
 	public void testfindPet() throws Exception {
 
-		String petId = createTestPet();
-
+		int petId = createTestPet();
 		petStoreRest
-		.get("/pet/" + petId)
-		.execute()
-		.assertStatus(200)
-		.assertBody(
-				"{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}");
+			.get("/pet/" + petId)
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}");
 
 		deleteTestPets();
 
 	}
 
 	// Find pet by status
-
 	@Test
-	public void testfindPetByStatus() throws Exception {
+	public void testFindPetByStatus() throws Exception {
 
-		String petId = createTestPet();
-
+		int petId = createTestPet();
 		petStoreRest
-		.get("/pet/findByStatus?status=AVAILABLE")
-		.execute()
-		.assertStatus(200)
-		.assertBody(
-				"[{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}]");
+			.get("/pet/findByStatus?status=AVAILABLE")
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("[{id:" + petId + ",species:'BIRD',name:'Sunshine',tags:['nice'],price:100.0,status:'AVAILABLE'}]");
 
 		deleteTestPets();
 	}
@@ -137,205 +123,207 @@
 	@Test
 	public void testUpdatePet() throws Exception {
 
-		String petId = createTestPet();
-
+		int petId = createTestPet();
 		petStoreRest
-				.put("/pet/" + petId,
-						"{id: " + petId
-								+ ",name:'Daisy1',price:1000.0,species:'BIRD'tags:['nice'], status:'AVAILABLE' }")
-				.execute()
-				.assertStatus(200);
+			.put(
+				"/pet/" + petId,
+				new UpdatePet().id(petId).name("Daisy1").price(1000f).species(Species.BIRD).status(PetStatus.AVAILABLE).tags("nice")
+			)
+			.complete()
+			.assertCode().is(200);
 
 		deleteTestPets();
-
 	}
 
-	// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+	// -----------------------------------------------------------------------------------------------------------------
 	// Users
-	// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+	// -----------------------------------------------------------------------------------------------------------------
 
-	private void deleteTestUsers() throws AssertionError, ServletException, IOException {
-
+	private void deleteTestUsers() throws Exception {
 		petStoreRest
-		.delete("/users/")
-		.execute()
-		.assertStatus(200);
-
+			.delete("/users/")
+			.complete()
+			.assertCode().is(200);
 	}
 
-	private String createTestUser(String username) throws AssertionError, ServletException, IOException {
-
+	private String createTestUser(String username) throws Exception {
 		petStoreRest
-				.post("/user", "{username:" + username + ",firstName: 'Tom',lastName: 'Simon', userStatus: 'ACTIVE'}")
-				.execute()
-				.assertStatus(200);
+			.post(
+				"/user",
+				new User().username(username).firstName("Tom").lastName("Simon").userStatus(UserStatus.ACTIVE)
+			)
+			.complete()
+			.assertCode().is(200);
 
 		return username;
 	}
 
 	// Create user
-
 	@Test
 	public void testCreateUser() throws Exception {
-
 		petStoreRest
-		.post("/user", "{username:'catlover',firstName: 'Tom',lastName: 'Simon', userStatus: 'ACTIVE'}")
-		.execute()
-		.assertStatus(200);
+			.post(
+				"/user",
+				new User().username("catlover").firstName("Tom").lastName("Simon").userStatus(UserStatus.ACTIVE)
+			)
+			.complete()
+			.assertCode().is(200);
 
 		deleteTestUsers();
 	}
 
 	// Delete user
-
 	@Test
 	public void testDeleteUser() throws Exception {
 
 		petStoreRest
-		.delete("/user/" + "catlover1")
-		.execute()
-		.assertStatus(200);
+			.delete("/user/" + "catlover1")
+			.complete()
+			.assertCode().is(200);
 
 	}
 
 	// Create list of users
-
 	@Test
 	public void testCreateUsers() throws Exception {
 
 		petStoreRest
-				.post("/user/createWithArray",
-						"[{username:'billy',firstName: 'Billy',lastName: 'Bob', userStatus: 'ACTIVE'},"
-								+ "{username:'peter',firstName: 'Peter',lastName: 'Adams', userStatus: 'ACTIVE'}]")
-				.execute()
-				.assertStatus(200);
+			.post(
+				"/user/createWithArray",
+				new User[] {
+					new User().username("billy").firstName("Billy").lastName("Bob").userStatus(UserStatus.ACTIVE),
+					new User().username("peter").firstName("Peter").lastName("Adams").userStatus(UserStatus.ACTIVE)
+				}
+			)
+			.complete()
+			.assertCode().is(200);
 
 		deleteTestUsers();
 	}
 
 	// Getting all users
-
 	@Test
 	public void testGettingUsers() throws Exception {
 
 		createTestUser("doglover");
 		petStoreRest
-		.get("/user")
-		.execute()
-		.assertStatus(200)
-		.assertBody("[{username:'doglover',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}]");
+			.get("/user")
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("[{username:'doglover',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}]");
 
 		deleteTestUsers();
 	}
 
 	// Get user by user name
-
 	@Test
 	public void testFindUserByName() throws Exception {
 
 		createTestUser("garfield");
 		petStoreRest
-		.get("/user/garfield")
-		.execute()
-		.assertStatus(200)
-		.assertBody("{username:'garfield',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}");
+			.get("/user/garfield")
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("{username:'garfield',firstName:'Tom',lastName:'Simon',userStatus:'ACTIVE'}");
 
 		deleteTestUsers();
 	}
 
 	// Updating user
-
 	@Test
 	public void testUpdateUser() throws Exception {
 
 		createTestUser("snoopy");
 		petStoreRest
-		.put("/user/snoopy", "{username:'snoopy',phone: '34562345'}")
-		.execute()
-		.assertStatus(200);
+			.put(
+				"/user/snoopy",
+				new User().username("snoopy").phone("34562345")
+			)
+			.complete()
+			.assertCode().is(200);
 
 		deleteTestUsers();
 	}
 
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+	// -----------------------------------------------------------------------------------------------------------------
 	// Orders
-	// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-	private void deleteTestOrders() throws AssertionError, ServletException, IOException {
+	// -----------------------------------------------------------------------------------------------------------------
 
+	private void deleteTestOrders() throws Exception {
 		petStoreRest
-		.delete("/orders")
-		.execute()
-		.assertStatus(200);
-
+			.delete("/orders")
+			.complete()
+			.assertCode().is(200);
 	}
 
-	private String createTestOrder() throws AssertionError, ServletException, IOException {
+	private int createTestOrder() throws Exception {
 
-		String petId = createTestPet();
-		String orderId = petStoreRest
-				.post("/store/order", "{petId:" + petId + " + ,username: 'catlover'}")
-				.execute()
-				.assertStatus(200)
-				.getBodyAsString();
+		int petId = createTestPet();
+		int orderId = petStoreRest
+			.post(
+				"/store/order",
+				new CreateOrder().petId(petId).username("catlover")
+			)
+			.run()
+			.assertCode().is(200)
+			.getBody().as(int.class);
 
 		return orderId;
 	}
 
 	// Posting order
-
 	@Test
 	public void testPostOrder() throws Exception {
 
 		petStoreRest
-		.post("/store/order", "{petId:'1',username: 'snoopy'}")
-		.execute()
-		.assertStatus(200);
+			.post(
+				"/store/order",
+				new CreateOrder().petId(1).username("snoopy")
+			)
+			.complete()
+			.assertCode().is(200);
 
 		deleteTestOrders();
 
 	}
 
 	// Getting all orders
-
 	@Test
 	public void testGettingOrders() throws Exception {
 
-		String orderId = createTestOrder();
+		int orderId = createTestOrder();
 		petStoreRest
-		.get("/store/order")
-		.execute()
-		.assertStatus(200)
-		.assertBody("[{id:" + orderId + ",petId:0,status:'PLACED'}]");
+			.get("/store/order")
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("[{id:" + orderId + ",petId:0,status:'PLACED'}]");
 
 		deleteTestOrders();
 
 	}
 
 	// Find order by Id
-
 	@Test
 	public void testfindOrder() throws Exception {
 
-		String orderId = createTestOrder();
+		int orderId = createTestOrder();
 		petStoreRest
-		.get("/store/order/" + orderId)
-		.execute()
-		.assertStatus(200)
-		.assertBody("{id:" + orderId + ",petId:0,status:'PLACED'}");
+			.get("/store/order/" + orderId)
+			.run()
+			.assertCode().is(200)
+			.assertBody().is("{id:" + orderId + ",petId:0,status:'PLACED'}");
 
 		deleteTestOrders();
 	}
 
 	// Delete order by Id
-
 	@Test
 	public void testDeleteOrder() throws Exception {
 
-		String orderId = createTestOrder();
+		int orderId = createTestOrder();
 		petStoreRest
-		.delete("/store/order/" + orderId)
-		.execute()
-		.assertStatus(200);
-
+			.delete("/store/order/" + orderId)
+			.complete()
+			.assertCode().is(200);
 	}
 }
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 32a0465..bb1c4d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
         <junit.version>4.11</junit.version>
         <servlet.version>3.1.0</servlet.version>
         <httpclient.version>4.5.6</httpclient.version>
-        <juneau.version>8.1.2</juneau.version>
+        <juneau.version>8.2.0</juneau.version>
         <derby.version>10.10.2.0</derby.version>
         <hibernate.version>5.0.9.Final</hibernate.version>
         <javax.inject.version>1</javax.inject.version>