REST refactoring.
diff --git a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/Messages_Test.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/Messages_Test.java
index 4e4d49e..df86893 100644
--- a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/Messages_Test.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/cp/Messages_Test.java
@@ -75,7 +75,7 @@
 		assertString(x1.forLocale(CHINA).getString("file")).is("MessageBundleTest1.properties");
 		assertString(x1.forLocale((Locale)null).getString("file")).is("MessageBundleTest1.properties");
 
-		Messages x2 = Messages.create(MessageBundleTest1.class).locale(null).build();
+		Messages x2 = Messages.create(MessageBundleTest1.class).locale((Locale)null).build();
 		assertString(x2.getString("file")).is("MessageBundleTest1.properties");
 		assertString(x2.forLocale(JAPANESE).getString("file")).is("MessageBundleTest1_ja.properties");
 		assertString(x2.forLocale(JAPAN).getString("file")).is("MessageBundleTest1_ja_JP.properties");
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/MessagesBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/MessagesBuilder.java
index 9f698a2..67db127 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/MessagesBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/MessagesBuilder.java
@@ -94,6 +94,18 @@
 	}
 
 	/**
+	 * Specifies the locale.
+	 *
+	 * @param locale
+	 * 	The locale.
+	 * 	If <jk>null</jk>, the default locale is used.
+	 * @return This object (for method chaining).
+	 */
+	public MessagesBuilder locale(String locale) {
+		return locale(locale == null ? null : Locale.forLanguageTag(locale));
+	}
+
+	/**
 	 * Creates a new {@link Messages} based on the setting of this builder.
 	 *
 	 * @return A new {@link Messages} object.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 7579c7f..5f0cef5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -52,6 +52,7 @@
 import org.apache.juneau.httppart.bean.*;

 import org.apache.juneau.json.*;

 import org.apache.juneau.jsonschema.*;

+import org.apache.juneau.marshall.*;

 import org.apache.juneau.msgpack.*;

 import org.apache.juneau.mstat.*;

 import org.apache.juneau.oapi.*;

@@ -3345,29 +3346,25 @@
 			consumes = getListProperty(REST_consumes, MediaType.class, parsers.getSupportedMediaTypes());

 			produces = getListProperty(REST_produces, MediaType.class, serializers.getSupportedMediaTypes());

 

-			Tuple2<Class<?>,String>[] mbl = getInstanceArrayProperty(REST_messages, Tuple2.class);

-			Messages msgs = null;

-			for (int i = mbl.length-1; i >= 0; i--)

-				msgs = Messages.create(firstNonNull(mbl[i].getA(), rci.inner())).name(mbl[i].getB()).parent(msgs).build();

-			this.msgs = msgs;

+			msgs = createMessages(r);

 

-			this.fullPath = (builder.parentContext == null ? "" : (builder.parentContext.fullPath + '/')) + builder.getPath();

+			fullPath = (builder.parentContext == null ? "" : (builder.parentContext.fullPath + '/')) + builder.getPath();

 

 			String p = builder.getPath();

 			if (! p.endsWith("/*"))

 				p += "/*";

-			this.pathMatcher = UrlPathMatcher.of(p);

+			pathMatcher = UrlPathMatcher.of(p);

 

-			this.childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());  // Not unmodifiable on purpose so that children can be replaced.

+			childResources = Collections.synchronizedMap(new LinkedHashMap<String,RestContext>());  // Not unmodifiable on purpose so that children can be replaced.

 

-			this.startCallMethods = createStartCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

-			this.endCallMethods = createEndCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

-			this.postInitMethods = createPostInitMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

-			this.postInitChildFirstMethods = createPostInitChildFirstMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

-			this.destroyMethods = createDestroyMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

+			startCallMethods = createStartCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

+			endCallMethods = createEndCallMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

+			postInitMethods = createPostInitMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

+			postInitChildFirstMethods = createPostInitChildFirstMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

+			destroyMethods = createDestroyMethods(r).stream().map(this::toMethodInvoker).toArray(MethodInvoker[]::new);

 

-			this.preCallMethods = createPreCallMethods(r).stream().map(this::toRestMethodInvoker).toArray(RestMethodInvoker[]:: new);

-			this.postCallMethods = createPostCallMethods(r).stream().map(this::toRestMethodInvoker).toArray(RestMethodInvoker[]:: new);

+			preCallMethods = createPreCallMethods(r).stream().map(this::toRestMethodInvoker).toArray(RestMethodInvoker[]:: new);

+			postCallMethods = createPostCallMethods(r).stream().map(this::toRestMethodInvoker).toArray(RestMethodInvoker[]:: new);

 

 			//----------------------------------------------------------------------------------------------------

 			// Initialize the child resources.

@@ -4620,6 +4617,37 @@
 	}

 

 	/**

+	 * Instantiates the messages for this REST object.

+	 *

+	 * @param resource The REST resource object.

+	 * @return The messages for this REST object.

+	 * @throws Exception An error occurred.

+	 */

+	protected Messages createMessages(Object resource) throws Exception {

+		Tuple2<Class<?>,String>[] mbl = getInstanceArrayProperty(REST_messages, Tuple2.class);

+		Messages msgs = null;

+		for (int i = mbl.length-1; i >= 0; i--) {

+			Class<?> c = firstNonNull(mbl[i].getA(), resource.getClass());

+			String value = mbl[i].getB();

+			if (isJsonObject(value,true)) {

+				MessagesString x = SimpleJson.DEFAULT.read(value, MessagesString.class);

+				msgs = Messages.create(c).name(x.name).baseNames(split(x.baseNames, ',')).locale(x.locale).parent(msgs).build();

+			} else {

+				msgs = Messages.create(c).name(value).parent(msgs).build();

+			}

+		}

+		if (msgs == null)

+			msgs = Messages.create(resource.getClass()).build();

+		return msgs;

+	}

+

+	private static class MessagesString {

+		public String name;

+		public String[] baseNames;

+		public String locale;

+	}

+

+	/**

 	 * Instantiates the list of {@link HookEvent#START_CALL} methods.

 	 *

 	 * @param resource The REST resource object.

diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index 283006b..b1eedd1 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -697,6 +697,26 @@
 	 *

 	 * Identifies the location of the resource bundle for this class.

 	 *

+	 * <p>

+	 * There are two possible formats:

+	 * <ul>

+	 * 	<li>A simple string - Represents the {@link MessagesBuilder#name(String) name} of the resource bundle.

+	 * 		<br><br><i>Example:</i>

+	 * 		<p class='bcode w800'>

+	 * 	<jc>// Bundle name is Messages.properties.</jc>

+	 * 	<ja>@Rest</ja>(messages=<js>"Messages"</js>)

+	 * 		</p>

+	 * 	<li>Simplified JSON - Represents parameters for the {@link MessagesBuilder} class.

+	 * 		<br><br><i>Example:</i>

+	 * 		<p class='bcode w800'>

+	 * 	<jc>// Bundles can be found in two packages.</jc>

+	 * 	<ja>@Rest</ja>(messages=<js>"{name:'Messages',baseNames:['{package}.{name}','{package}.i18n.{name}']"</js>)

+	 * 		</p>

+	 * </ul>

+	 *

+	 * <p>

+	 * If the bundle name is not specified, the class name of the resource object is used.

+	 *

 	 * <ul class='notes'>

 	 * 	<li>

 	 * 		Supports {@doc RestSvlVariables}