http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
index 2a83eb5..0b165de 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -17,6 +17,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.parser.*;
 
 /**
@@ -49,9 +50,10 @@ public final class MsgPackParserSession extends 
ParserSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public MsgPackParserSession(MsgPackParserContext ctx, ObjectMap op, 
Object input, Method javaMethod, Object outer, Locale locale, TimeZone 
timeZone) {
-               super(ctx, op, input, javaMethod, outer, locale, timeZone);
+       public MsgPackParserSession(MsgPackParserContext ctx, ObjectMap op, 
Object input, Method javaMethod, Object outer, Locale locale, TimeZone 
timeZone, MediaType mediaType) {
+               super(ctx, op, input, javaMethod, outer, locale, timeZone, 
mediaType);
        }
 
        @Override /* ParserSession */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 4ff4c1b..93fa938 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -196,8 +196,8 @@ public class MsgPackSerializer extends 
OutputStreamSerializer {
        
//--------------------------------------------------------------------------------
 
        @Override /* Serializer */
-       public MsgPackSerializerSession createSession(Object output, ObjectMap 
op, Method javaMethod, Locale locale, TimeZone timeZone) {
-               return new 
MsgPackSerializerSession(getContext(MsgPackSerializerContext.class), op, 
output, javaMethod, locale, timeZone);
+       public MsgPackSerializerSession createSession(Object output, ObjectMap 
op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+               return new 
MsgPackSerializerSession(getContext(MsgPackSerializerContext.class), op, 
output, javaMethod, locale, timeZone, mediaType);
        }
 
        @Override /* Serializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
index d652405..aa3eb0f 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -16,6 +16,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.json.*;
 import org.apache.juneau.serializer.*;
 
@@ -39,9 +40,10 @@ public final class MsgPackSerializerSession extends 
SerializerSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       protected MsgPackSerializerSession(MsgPackSerializerContext ctx, 
ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone 
timeZone) {
-               super(ctx, op, output, javaMethod, locale, timeZone);
+       protected MsgPackSerializerSession(MsgPackSerializerContext ctx, 
ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone 
timeZone, MediaType mediaType) {
+               super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
index 8256a74..0084be8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
@@ -20,6 +20,7 @@ import java.text.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.transform.*;
@@ -134,23 +135,19 @@ public abstract class Parser extends CoreApi {
 
        /** General serializer properties currently set on this serializer. */
        private final List<ParserListener> listeners = new 
LinkedList<ParserListener>();
-       private final String[] mediaTypes;
-       private final MediaRange[] mediaRanges;
+       private final MediaType[] mediaTypes;
 
        // Hidden constructor to force subclass from InputStreamParser or 
ReaderParser.
        Parser() {
                Consumes c = ReflectionUtils.getAnnotation(Consumes.class, 
getClass());
                if (c == null)
                        throw new RuntimeException(MessageFormat.format("Class 
''{0}'' is missing the @Consumes annotation", getClass().getName()));
-               this.mediaTypes = StringUtils.split(c.value(), ',');
-               for (int i = 0; i < mediaTypes.length; i++) {
-                       mediaTypes[i] = 
mediaTypes[i].toLowerCase(Locale.ENGLISH);
-               }
 
-               List<MediaRange> l = new LinkedList<MediaRange>();
-               for (int i = 0; i < mediaTypes.length; i++)
-                       
l.addAll(Arrays.asList(MediaRange.parse(mediaTypes[i])));
-               mediaRanges = l.toArray(new MediaRange[l.size()]);
+               String[] mt = StringUtils.split(c.value(), ',');
+               this.mediaTypes = new MediaType[mt.length];
+               for (int i = 0; i < mt.length; i++) {
+                       mediaTypes[i] = MediaType.forString(mt[i]);
+               }
        }
 
        
//--------------------------------------------------------------------------------
@@ -159,7 +156,7 @@ public abstract class Parser extends CoreApi {
 
        /**
         * Workhorse method.  Subclasses are expected to implement this method.
-        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone)}.
+        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone, MediaType)}.
         *      If <jk>null</jk>, one will be created using {@link 
#createSession(Object)}.
         * @param type The class type of the object to create.
         *      If <jk>null</jk> or <code>Object.<jk>class</jk></code>, object 
type is based on what's being parsed.
@@ -184,7 +181,7 @@ public abstract class Parser extends CoreApi {
 
        /**
         * Parses the content of the reader and creates an object of the 
specified type.
-        * @param session The runtime session returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone)}.
+        * @param session The runtime session returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone, MediaType)}.
         * @param type The class type of the object to create.
         *      If <jk>null</jk> or <code>Object.<jk>class</jk></code>, object 
type is based on what's being parsed.
         *      For example, when parsing JSON text, it may return a 
<code>String</code>, <code>Number</code>, <code>ObjectMap</code>, etc...
@@ -366,10 +363,11 @@ public abstract class Parser extends CoreApi {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         * @return The new session.
         */
-       public ParserSession createSession(Object input, ObjectMap op, Method 
javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               return new ParserSession(getContext(ParserContext.class), op, 
input, javaMethod, outer, locale, timeZone);
+       public ParserSession createSession(Object input, ObjectMap op, Method 
javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               return new ParserSession(getContext(ParserContext.class), op, 
input, javaMethod, outer, locale, timeZone, mediaType);
        }
 
        /**
@@ -381,7 +379,7 @@ public abstract class Parser extends CoreApi {
         * @return The new context.
         */
        protected final ParserSession createSession(Object input) {
-               return createSession(input, null, null, null, null, null);
+               return createSession(input, null, null, null, null, null, 
getPrimaryMediaType());
        }
 
        
//--------------------------------------------------------------------------------
@@ -424,7 +422,7 @@ public abstract class Parser extends CoreApi {
        /**
         * Implementation method.
         * Default implementation throws an {@link 
UnsupportedOperationException}.
-        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone)}.
+        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone, MediaType)}.
         *      If <jk>null</jk>, one will be created using {@link 
#createSession(Object)}.
         * @param m The map being loaded.
         * @param keyType The class type of the keys, or <jk>null</jk> to 
default to <code>String.<jk>class</jk></code>.<br>
@@ -469,7 +467,7 @@ public abstract class Parser extends CoreApi {
        /**
         * Implementation method.
         * Default implementation throws an {@link 
UnsupportedOperationException}.
-        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone)}.
+        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone, MediaType)}.
         *      If <jk>null</jk>, one will be created using {@link 
#createSession(Object)}.
         * @param c The collection being loaded.
         * @param elementType The class type of the elements, or <jk>null</jk> 
to default to whatever is being parsed.
@@ -517,7 +515,7 @@ public abstract class Parser extends CoreApi {
        /**
         * Implementation method.
         * Default implementation throws an {@link 
UnsupportedOperationException}.
-        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone)}.
+        * @param session The runtime session object returned by {@link 
#createSession(Object, ObjectMap, Method, Object, Locale, TimeZone, MediaType)}.
         *      If <jk>null</jk>, one will be created using {@link 
#createSession(Object)}.
         * @param argTypes Specifies the type of objects to create for each 
entry in the array.
         *
@@ -660,17 +658,17 @@ public abstract class Parser extends CoreApi {
         *
         * @return The list of media types.  Never <jk>null</jk>.
         */
-       public String[] getMediaTypes() {
+       public MediaType[] getMediaTypes() {
                return mediaTypes;
        }
 
        /**
-        * Returns the results from {@link #getMediaTypes()} parsed as {@link 
MediaRange MediaRanges}.
+        * Returns the first media type specified on this parser via the {@link 
Consumes} annotation.
         *
-        * @return The list of media types parsed as ranges.  Never 
<jk>null</jk>.
+        * @return The media type.
         */
-       public MediaRange[] getMediaRanges() {
-               return mediaRanges;
+       public MediaType getPrimaryMediaType() {
+               return mediaTypes == null || mediaTypes.length == 0 ? null : 
mediaTypes[0];
        }
 
        
//--------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
index e7f157b..33b78fd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
@@ -16,7 +16,6 @@ import static org.apache.juneau.internal.ArrayUtils.*;
 
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
 
 import org.apache.juneau.*;
 
@@ -66,17 +65,25 @@ import org.apache.juneau.*;
  */
 public final class ParserGroup extends Lockable {
 
-       // Maps media-types to parsers.
-       private final Map<String,Parser> parserMap = new 
ConcurrentHashMap<String,Parser>();
-
-       // Maps Content-Type headers to matching media types.
-       private final Map<String,String> mediaTypeMappings = new 
ConcurrentHashMap<String,String>();
+       // Maps Content-Type headers to matches.
+       private final Map<String,ParserMatch> cache = new 
ConcurrentHashMap<String,ParserMatch>();
 
        private final CopyOnWriteArrayList<Parser> parsers = new 
CopyOnWriteArrayList<Parser>();
 
-       private final ReadWriteLock lock = new ReentrantReadWriteLock();
-       private final Lock rl = lock.readLock(), wl = lock.writeLock();
-
+       /**
+        * Adds the specified parser to the beginning of this group.
+        *
+        * @param p - The parser to add to this group.
+        * @return This object (for method chaining).
+        */
+       public ParserGroup append(Parser p) {
+               checkLock();
+               synchronized(parsers) {
+                       cache.clear();
+                       parsers.add(0, p);
+               }
+               return this;
+       }
 
        /**
         * Registers the specified parsers with this group.
@@ -86,22 +93,8 @@ public final class ParserGroup extends Lockable {
         * @throws Exception Thrown if {@link Parser} could not be constructed.
         */
        public ParserGroup append(Class<? extends Parser>...p) throws Exception 
{
-               checkLock();
-               wl.lock();
-               try {
-                       for (Class<? extends Parser> c : reverse(p)) {
-                               parserMap.clear();
-                               mediaTypeMappings.clear();
-                               try {
-                                       append(c);
-                               } catch (NoClassDefFoundError e) {
-                                       // Ignore if dependent library not 
found (e.g. Jena).
-                                       System.err.println(e);
-                               }
-                       }
-               } finally {
-                       wl.unlock();
-               }
+               for (Class<? extends Parser> pp : reverse(p))
+                       append(pp);
                return this;
        }
 
@@ -113,74 +106,85 @@ public final class ParserGroup extends Lockable {
         * @throws Exception Thrown if {@link Parser} could not be constructed.
         */
        public ParserGroup append(Class<? extends Parser> p) throws Exception {
-               checkLock();
-               wl.lock();
                try {
-                       parserMap.clear();
-                       mediaTypeMappings.clear();
-                       parsers.add(0, p.newInstance());
+                       append(p.newInstance());
                } catch (NoClassDefFoundError e) {
                        // Ignore if dependent library not found (e.g. Jena).
                        System.err.println(e);
-               } finally {
-                       wl.unlock();
                }
                return this;
        }
 
        /**
-        * Returns the parser registered to handle the specified media type.
-        * <p>
-        * The media-type string must not contain any parameters such as 
<js>";charset=X"</js>.
+        * Adds the parsers in the specified group to this group.
         *
-        * @param mediaType The media-type string (e.g. <js>"text/json"</js>).
-        * @return The REST parser that handles the specified request content 
type, or <jk>null</jk> if
-        *              no parser is registered to handle it.
+        * @param g The group containing the parsers to add to this group.
+        * @return This object (for method chaining).
         */
-       public Parser getParser(String mediaType) {
-               Parser p = parserMap.get(mediaType);
-               if (p == null) {
-                       String mt = findMatch(mediaType);
-                       if (mt != null)
-                               p = parserMap.get(mt);
-               }
-               return p;
+       public ParserGroup append(ParserGroup g) {
+               for (Parser p : reverse(g.parsers.toArray(new 
Parser[g.parsers.size()])))
+                       append(p);
+               return this;
        }
 
        /**
         * Searches the group for a parser that can handle the specified 
<l>Content-Type</l> header value.
         *
         * @param contentTypeHeader The HTTP <l>Content-Type</l> header value.
-        * @return The media type registered by one of the parsers that matches 
the <code>mediaType</code> string,
-        *      or <jk>null</jk> if no media types matched.
+        * @return The parser and media type that matched the content type 
header, or <jk>null</jk> if no match was made.
         */
-       public String findMatch(String contentTypeHeader) {
-               rl.lock();
-               try {
-                       String mt = mediaTypeMappings.get(contentTypeHeader);
-                       if (mt != null)
-                               return mt;
+       public ParserMatch getParserMatch(String contentTypeHeader) {
+               ParserMatch pm = cache.get(contentTypeHeader);
+               if (pm != null)
+                       return pm;
 
-                       MediaRange[] mr = MediaRange.parse(contentTypeHeader);
-                       if (mr.length == 0)
-                               mr = MediaRange.parse("*/*");
+               MediaType mt = MediaType.forString(contentTypeHeader);
+               return getParserMatch(mt);
+       }
 
-                       for (MediaRange a : mr) {
-                               for (Parser p : parsers) {
-                                       for (MediaRange a2 : 
p.getMediaRanges()) {
-                                               if (a.matches(a2)) {
-                                                       mt = a2.getMediaType();
-                                                       
mediaTypeMappings.put(contentTypeHeader, mt);
-                                                       parserMap.put(mt, p);
-                                                       return mt;
-                                               }
-                                       }
+       /**
+        * Same as {@link #getParserMatch(String)} but matches using a {@link 
MediaType} instance.
+        *
+        * @param mediaType The HTTP <l>Content-Type</l> header value as a 
media type.
+        * @return The parser and media type that matched the media type, or 
<jk>null</jk> if no match was made.
+        */
+       public ParserMatch getParserMatch(MediaType mediaType) {
+               ParserMatch pm = cache.get(mediaType.toString());
+               if (pm != null)
+                       return pm;
+
+               for (Parser p : parsers) {
+                       for (MediaType a2 : p.getMediaTypes()) {
+                               if (mediaType.matches(a2)) {
+                                       pm = new ParserMatch(a2, p);
+                                       cache.put(mediaType.toString(), pm);
+                                       return pm;
                                }
                        }
-                       return null;
-               } finally {
-                       rl.unlock();
                }
+               return null;
+       }
+
+       /**
+        * Same as {@link #getParserMatch(String)} but returns just the matched 
parser.
+        *
+        * @param contentTypeHeader The HTTP <l>Content-Type</l> header string.
+        * @return The parser that matched the content type header, or 
<jk>null</jk> if no match was made.
+        */
+       public Parser getParser(String contentTypeHeader) {
+               ParserMatch pm = getParserMatch(contentTypeHeader);
+               return pm == null ? null : pm.getParser();
+       }
+
+       /**
+        * Same as {@link #getParserMatch(MediaType)} but returns just the 
matched parser.
+        *
+        * @param mediaType The HTTP media type.
+        * @return The parser that matched the media type, or <jk>null</jk> if 
no match was made.
+        */
+       public Parser getParser(MediaType mediaType) {
+               ParserMatch pm = getParserMatch(mediaType);
+               return pm == null ? null : pm.getParser();
        }
 
        /**
@@ -190,10 +194,10 @@ public final class ParserGroup extends Lockable {
         *
         * @return The list of media types.
         */
-       public List<String> getSupportedMediaTypes() {
-               List<String> l = new ArrayList<String>();
+       public List<MediaType> getSupportedMediaTypes() {
+               List<MediaType> l = new ArrayList<MediaType>();
                for (Parser p : parsers)
-                       for (String mt : p.getMediaTypes())
+                       for (MediaType mt : p.getMediaTypes())
                                if (! l.contains(mt))
                                        l.add(mt);
                return l;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/parser/ParserMatch.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserMatch.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserMatch.java
new file mode 100644
index 0000000..a7ee50e
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserMatch.java
@@ -0,0 +1,53 @@
+// 
***************************************************************************************************************************
+// * 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.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.parser;
+
+import org.apache.juneau.*;
+
+/**
+ * Represents a parser and media type that matches an HTTP 
<code>Content-Type</code> header value.
+ */
+public final class ParserMatch {
+
+       private final MediaType mediaType;
+       private final Parser parser;
+
+       /**
+        * Constructor.
+        *
+        * @param mediaType - The media type of the match.
+        * @param parser - The parser that matched.
+        */
+       public ParserMatch(MediaType mediaType, Parser parser) {
+               this.mediaType = mediaType;
+               this.parser = parser;
+       }
+
+       /**
+        * Returns the media type of the parser that matched the HTTP 
<code>Content-Type</code> header value.
+        *
+        * @return The media type of the match.
+        */
+       public MediaType getMediaType() {
+               return mediaType;
+       }
+
+       /**
+        * Returns the parser that matched the HTTP <code>Content-Type</code> 
header value.
+        *
+        * @return The parser of the match.
+        */
+       public Parser getParser() {
+               return parser;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java 
b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
index 4fff1fa..e471056 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -69,9 +69,10 @@ public class ParserSession extends BeanSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public ParserSession(ParserContext ctx, ObjectMap op, Object input, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               super(ctx, op, locale, timeZone);
+       public ParserSession(ParserContext ctx, ObjectMap op, Object input, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               super(ctx, op, locale, timeZone, mediaType);
                if (op == null || op.isEmpty()) {
                        trimStrings = ctx.trimStrings;
                        strict = ctx.strict;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
index 2d68073..c2264aa 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -44,27 +44,23 @@ import org.apache.juneau.soap.*;
  */
 public abstract class Serializer extends CoreApi {
 
-       private final String[] mediaTypes;
-       private final MediaRange[] mediaRanges;
-       private final String contentType;
+       private final MediaType[] mediaTypes;
+       private final MediaType contentType;
 
        // Hidden constructors to force subclass from OuputStreamSerializer or 
WriterSerializer.
        Serializer() {
                Produces p = ReflectionUtils.getAnnotation(Produces.class, 
getClass());
                if (p == null)
                        throw new RuntimeException(MessageFormat.format("Class 
''{0}'' is missing the @Produces annotation", getClass().getName()));
-               this.mediaTypes = StringUtils.split(p.value(), ',');
-               for (int i = 0; i < mediaTypes.length; i++) {
-                       mediaTypes[i] = 
mediaTypes[i].toLowerCase(Locale.ENGLISH);
-               }
 
-               List<MediaRange> l = new LinkedList<MediaRange>();
-               for (int i = 0; i < mediaTypes.length; i++)
-                       
l.addAll(Arrays.asList(MediaRange.parse(mediaTypes[i])));
-               mediaRanges = l.toArray(new MediaRange[l.size()]);
+               String[] mt = StringUtils.split(p.value(), ',');
+               this.mediaTypes = new MediaType[mt.length];
+               for (int i = 0; i < mt.length; i++) {
+                       mediaTypes[i] = MediaType.forString(mt[i]);
+               }
 
-               String ct = p.contentType().isEmpty() ? this.mediaTypes[0] : 
p.contentType();
-               contentType = ct.isEmpty() ? null : ct;
+               String ct = p.contentType().isEmpty() ? 
this.mediaTypes[0].toString() : p.contentType();
+               contentType = ct.isEmpty() ? null : MediaType.forString(ct);
        }
 
        /**
@@ -82,7 +78,7 @@ public abstract class Serializer extends CoreApi {
         * Serializes a POJO to the specified output stream or writer.
         * <p>
         * This method should NOT close the context object.
-        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone)}.<br>
+        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone, MediaType)}.<br>
         *      If <jk>null</jk>, session is created using {@link 
#createSession(Object)}.
         * @param o The object to serialize.
         *
@@ -110,7 +106,7 @@ public abstract class Serializer extends CoreApi {
        /**
         * Serialize the specified object using the specified session.
         *
-        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone)}.<br>
+        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone, MediaType)}.<br>
         *      If <jk>null</jk>, session is created using {@link 
#createSession(Object)}.
         * @param o The object to serialize.
         * @throws SerializeException If a problem occurred trying to convert 
the output.
@@ -180,10 +176,11 @@ public abstract class Serializer extends CoreApi {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         * @return The new session.
         */
-       public SerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone) {
-               return new 
SerializerSession(getContext(SerializerContext.class), op, output, javaMethod, 
locale, timeZone);
+       public SerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+               return new 
SerializerSession(getContext(SerializerContext.class), op, output, javaMethod, 
locale, timeZone, mediaType);
        }
 
        /**
@@ -206,7 +203,7 @@ public abstract class Serializer extends CoreApi {
         * @return The new session.
         */
        protected SerializerSession createSession(Object output) {
-               return createSession(output, null, null, null, null);
+               return createSession(output, null, null, null, null, 
getPrimaryMediaType());
        }
 
        /**
@@ -241,17 +238,17 @@ public abstract class Serializer extends CoreApi {
         *
         * @return The list of media types.  Never <jk>null</jk>.
         */
-       public String[] getMediaTypes() {
+       public MediaType[] getMediaTypes() {
                return mediaTypes;
        }
 
        /**
-        * Returns the results from {@link #getMediaTypes()} parsed as {@link 
MediaRange MediaRanges}.
+        * Returns the first media type specified on this parser via the {@link 
Produces} annotation.
         *
-        * @return The list of media types parsed as ranges.  Never 
<jk>null</jk>.
+        * @return The media type.
         */
-       public MediaRange[] getMediaRanges() {
-               return mediaRanges;
+       public MediaType getPrimaryMediaType() {
+               return mediaTypes == null || mediaTypes.length == 0 ? null : 
mediaTypes[0];
        }
 
        /**
@@ -282,7 +279,7 @@ public abstract class Serializer extends CoreApi {
         *
         * @return The response content type.  If <jk>null</jk>, then the 
matched media type is used.
         */
-       public String getResponseContentType() {
+       public MediaType getResponseContentType() {
                return contentType;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
index 997b015..4761265 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
@@ -16,7 +16,6 @@ import static org.apache.juneau.internal.ArrayUtils.*;
 
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
 
 import org.apache.juneau.*;
 
@@ -67,17 +66,25 @@ import org.apache.juneau.*;
  */
 public final class SerializerGroup extends Lockable {
 
-       // Maps media-types to serializers.
-       private final Map<String,Serializer> serializerMap = new 
ConcurrentHashMap<String,Serializer>();
-
-       // Maps Accept headers to matching media types.
-       private final Map<String,String> mediaTypeMappings = new 
ConcurrentHashMap<String,String>();
+       // Maps Accept headers to matching serializers.
+       private final Map<String,SerializerMatch> cache = new 
ConcurrentHashMap<String,SerializerMatch>();
 
        private final CopyOnWriteArrayList<Serializer> serializers = new 
CopyOnWriteArrayList<Serializer>();
 
-       private final ReadWriteLock lock = new ReentrantReadWriteLock();
-       private final Lock rl = lock.readLock(), wl = lock.writeLock();
-
+       /**
+        * Adds the specified serializer to the beginning of this group.
+        *
+        * @param s - The serializer to add to this group.
+        * @return This object (for method chaining).
+        */
+       public SerializerGroup append(Serializer s) {
+               checkLock();
+               synchronized(serializers) {
+                       cache.clear();
+                       serializers.add(0, s);
+               }
+               return this;
+       }
 
        /**
         * Registers the specified serializers with this group.
@@ -87,62 +94,38 @@ public final class SerializerGroup extends Lockable {
         * @throws Exception Thrown if {@link Serializer} could not be 
constructed.
         */
        public SerializerGroup append(Class<? extends Serializer>...s) throws 
Exception {
-               checkLock();
-               wl.lock();
-               try {
-                       serializerMap.clear();
-                       mediaTypeMappings.clear();
-                       for (Class<? extends Serializer> ss : reverse(s)) {
-                               try {
-                                       append(ss);
-                               } catch (NoClassDefFoundError e) {
-                                       // Ignore if dependent library not 
found (e.g. Jena).
-                                       System.err.println(e);
-                               }
-                       }
-               } finally {
-                       wl.unlock();
-               }
+               for (Class<? extends Serializer> ss : reverse(s))
+                       append(ss);
                return this;
        }
 
        /**
         * Same as {@link #append(Class[])}, except specify a single class to 
avoid unchecked compile warnings.
         *
-        * @param c The serializer to append to this group.
+        * @param s The serializer to append to this group.
         * @return This object (for method chaining).
         * @throws Exception Thrown if {@link Serializer} could not be 
constructed.
         */
-       public SerializerGroup append(Class<? extends Serializer> c) throws 
Exception {
-               checkLock();
-               wl.lock();
+       public SerializerGroup append(Class<? extends Serializer> s) throws 
Exception {
                try {
-                       serializerMap.clear();
-                       mediaTypeMappings.clear();
-                       serializers.add(0, c.newInstance());
+                       append(s.newInstance());
                } catch (NoClassDefFoundError e) {
                        // Ignore if dependent library not found (e.g. Jena).
                        System.err.println(e);
-               } finally {
-                       wl.unlock();
                }
                return this;
        }
 
        /**
-        * Returns the serializer registered to handle the specified media type.
-        * <p>
-        * The media-type string must not contain any parameters or q-values.
+        * Adds the serializers in the specified group to this group.
         *
-        * @param mediaType The media-type string (e.g. <js>"text/json"</js>
-        * @return The serializer that handles the specified accept content 
type, or <jk>null</jk> if
-        *              no serializer is registered to handle it.
+        * @param g The group containing the serializers to add to this group.
+        * @return This object (for method chaining).
         */
-       public Serializer getSerializer(String mediaType) {
-               Serializer s = serializerMap.get(mediaType);
-               if (s == null)
-                       s = serializerMap.get(findMatch(mediaType));
-               return s;
+       public SerializerGroup append(SerializerGroup g) {
+               for (Serializer s : reverse(g.serializers.toArray(new 
Serializer[g.serializers.size()])))
+                       append(s);
+               return this;
        }
 
        /**
@@ -174,36 +157,68 @@ public final class SerializerGroup extends Lockable {
         * </p>
         *
         * @param acceptHeader The HTTP <l>Accept</l> header string.
-        * @return The media type registered by one of the parsers that matches 
the <code>accept</code> string,
-        *      or <jk>null</jk> if no media types matched.
+        * @return The serializer and media type that matched the accept 
header, or <jk>null</jk> if no match was made.
         */
-       public String findMatch(String acceptHeader) {
-               rl.lock();
-               try {
-                       String mt = mediaTypeMappings.get(acceptHeader);
-                       if (mt != null)
-                               return mt;
-
-                       MediaRange[] mr = MediaRange.parse(acceptHeader);
-                       if (mr.length == 0)
-                               mr = MediaRange.parse("*/*");
-
-                       for (MediaRange a : mr) {
-                               for (Serializer s : serializers) {
-                                       for (MediaRange a2 : 
s.getMediaRanges()) {
-                                               if (a.matches(a2)) {
-                                                       mt = a2.getMediaType();
-                                                       
mediaTypeMappings.put(acceptHeader, mt);
-                                                       serializerMap.put(mt, 
s);
-                                                       return mt;
-                                               }
+       public SerializerMatch getSerializerMatch(String acceptHeader) {
+               SerializerMatch sm = cache.get(acceptHeader);
+               if (sm != null)
+                       return sm;
+
+               MediaRange[] mr = MediaRange.parse(acceptHeader);
+               if (mr.length == 0)
+                       mr = MediaRange.parse("*/*");
+
+               Map<Float,SerializerMatch> m = null;
+
+               for (MediaRange a : mr) {
+                       for (Serializer s : serializers) {
+                               for (MediaType a2 : s.getMediaTypes()) {
+                                       float q = a.matches(a2);
+                                       if (q == 1) {
+                                               sm = new SerializerMatch(a2, s);
+                                               cache.put(acceptHeader, sm);
+                                               return sm;
+                                       } else if (q > 0) {
+                                               if (m == null)
+                                                       m = new 
TreeMap<Float,SerializerMatch>(Collections.reverseOrder());
+                                               m.put(q, new 
SerializerMatch(a2, s));
                                        }
                                }
                        }
-                       return null;
-               } finally {
-                       rl.unlock();
                }
+
+               return (m == null ? null : m.values().iterator().next());
+       }
+
+       /**
+        * Same as {@link #getSerializerMatch(String)} but matches using a 
{@link MediaType} instance.
+        *
+        * @param mediaType The HTTP media type.
+        * @return The serializer and media type that matched the media type, 
or <jk>null</jk> if no match was made.
+        */
+       public SerializerMatch getSerializerMatch(MediaType mediaType) {
+               return getSerializerMatch(mediaType.toString());
+       }
+
+       /**
+        * Same as {@link #getSerializerMatch(String)} but returns just the 
matched serializer.
+        *
+        * @param acceptHeader The HTTP <l>Accept</l> header string.
+        * @return The serializer that matched the accept header, or 
<jk>null</jk> if no match was made.
+        */
+       public Serializer getSerializer(String acceptHeader) {
+               SerializerMatch sm = getSerializerMatch(acceptHeader);
+               return sm == null ? null : sm.getSerializer();
+       }
+
+       /**
+        * Same as {@link #getSerializerMatch(MediaType)} but returns just the 
matched serializer.
+        *
+        * @param mediaType The HTTP media type.
+        * @return The serializer that matched the accept header, or 
<jk>null</jk> if no match was made.
+        */
+       public Serializer getSerializer(MediaType mediaType) {
+               return getSerializer(mediaType == null ? null : 
mediaType.toString());
        }
 
        /**
@@ -213,10 +228,10 @@ public final class SerializerGroup extends Lockable {
         *
         * @return The list of media types.
         */
-       public List<String> getSupportedMediaTypes() {
-               List<String> l = new ArrayList<String>();
+       public List<MediaType> getSupportedMediaTypes() {
+               List<MediaType> l = new ArrayList<MediaType>();
                for (Serializer s : serializers)
-                       for (String mt : s.getMediaTypes())
+                       for (MediaType mt : s.getMediaTypes())
                                if (! l.contains(mt))
                                        l.add(mt);
                return l;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerMatch.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerMatch.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerMatch.java
new file mode 100644
index 0000000..05e6a7a
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerMatch.java
@@ -0,0 +1,47 @@
+// 
***************************************************************************************************************************
+// * 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.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.serializer;
+
+import org.apache.juneau.*;
+
+/**
+ * Represents a serializer and media type that matches an HTTP 
<code>Accept</code> header value.
+ */
+public final class SerializerMatch {
+
+       private final MediaType mediaType;
+       private final Serializer serializer;
+
+       SerializerMatch(MediaType mediaType, Serializer serializer) {
+               this.mediaType = mediaType;
+               this.serializer = serializer;
+       }
+
+       /**
+        * Returns the media type of the serializers that matched the HTTP 
<code>Accept</code> header value.
+        *
+        * @return The media type of the match.
+        */
+       public MediaType getMediaType() {
+               return mediaType;
+       }
+
+       /**
+        * Returns the serializer that matched the HTTP <code>Accept</code> 
header value.
+        *
+        * @return The serializer of the match.
+        */
+       public Serializer getSerializer() {
+               return serializer;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index d0f72f9..1ad5ee5 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -20,6 +20,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.transform.*;
 
@@ -91,9 +92,10 @@ public class SerializerSession extends BeanSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public SerializerSession(SerializerContext ctx, ObjectMap op, Object 
output, Method javaMethod, Locale locale, TimeZone timeZone) {
-               super(ctx, op, locale, timeZone);
+       public SerializerSession(SerializerContext ctx, ObjectMap op, Object 
output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               super(ctx, op, locale, timeZone, mediaType);
                this.javaMethod = javaMethod;
                this.output = output;
                if (op == null || op.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
index 4f44a8b..f291639 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/StringObject.java
@@ -77,7 +77,7 @@ public class StringObject implements CharSequence, Writable {
        }
 
        @Override /* Writable */
-       public String getMediaType() {
+       public MediaType getMediaType() {
                return s.getMediaTypes()[0];
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index 26f8357..a84b9f9 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -27,7 +27,7 @@ import org.apache.juneau.annotation.*;
  *     This class is typically the parent class of all character-based 
serializers.
  *     It has 2 abstract methods to implement...
  * <ul class='spaced-list'>
- *     <li>{@link #createSession(Object, ObjectMap, Method, Locale, TimeZone)}
+ *     <li>{@link #createSession(Object, ObjectMap, Method, Locale, TimeZone, 
MediaType)}
  *     <li>{@link #doSerialize(SerializerSession, Object)}
  * </ul>
  *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java 
b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
index e1239b3..f9027ec 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -99,8 +99,8 @@ import org.apache.juneau.serializer.*;
 public abstract class PojoSwap<T,S> {
 
        private final Class<T> normalClass;
-       private final Class<S> swapClass;
-       private ClassMeta<S> swapClassMeta;
+       private final Class<?> swapClass;
+       private ClassMeta<?> swapClassMeta;
 
        /**
         * Constructor.
@@ -108,7 +108,7 @@ public abstract class PojoSwap<T,S> {
        @SuppressWarnings("unchecked")
        protected PojoSwap() {
                normalClass = 
(Class<T>)ClassUtils.resolveParameterType(PojoSwap.class, 0, this);
-               swapClass = 
(Class<S>)ClassUtils.resolveParameterType(PojoSwap.class, 1, this);
+               swapClass = ClassUtils.resolveParameterType(PojoSwap.class, 1, 
this);
        }
 
        /**
@@ -117,7 +117,7 @@ public abstract class PojoSwap<T,S> {
         * @param normalClass The normal class (cannot be serialized).
         * @param swapClass The transformed class (serializable).
         */
-       protected PojoSwap(Class<T> normalClass, Class<S> swapClass) {
+       protected PojoSwap(Class<T> normalClass, Class<?> swapClass) {
                this.normalClass = normalClass;
                this.swapClass = swapClass;
        }
@@ -179,7 +179,7 @@ public abstract class PojoSwap<T,S> {
         *
         * @return The transformed form of this class.
         */
-       public Class<S> getSwapClass() {
+       public Class<?> getSwapClass() {
                return swapClass;
        }
 
@@ -191,7 +191,7 @@ public abstract class PojoSwap<T,S> {
         *      This is always going to be the same bean context that created 
this swap.
         * @return The {@link ClassMeta} of the transformed class type.
         */
-       public ClassMeta<S> getSwapClassMeta(BeanContext beanContext) {
+       public ClassMeta<?> getSwapClassMeta(BeanContext beanContext) {
                if (swapClassMeta == null)
                        swapClassMeta = beanContext.getClassMeta(swapClass);
                return swapClassMeta;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
index 42d4ee8..79feb29 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
@@ -18,6 +18,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
@@ -727,8 +728,8 @@ public class UonParser extends ReaderParser {
        
//--------------------------------------------------------------------------------
 
        @Override /* Parser */
-       public UonParserSession createSession(Object input, ObjectMap op, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               return new UonParserSession(getContext(UonParserContext.class), 
op, input, javaMethod, outer, locale, timeZone);
+       public UonParserSession createSession(Object input, ObjectMap op, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               return new UonParserSession(getContext(UonParserContext.class), 
op, input, javaMethod, outer, locale, timeZone, mediaType);
        }
 
        @Override /* Parser */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
index a894e80..c2ea7da 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
@@ -52,9 +52,10 @@ public class UonParserSession extends ParserSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public UonParserSession(UonParserContext ctx, ObjectMap op, Object 
input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               super(ctx, op, input, javaMethod, outer, locale, timeZone);
+       public UonParserSession(UonParserContext ctx, ObjectMap op, Object 
input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, 
MediaType mediaType) {
+               super(ctx, op, input, javaMethod, outer, locale, timeZone, 
mediaType);
                if (op == null || op.isEmpty()) {
                        decodeChars = ctx.decodeChars;
                        whitespaceAware = ctx.whitespaceAware;
@@ -80,7 +81,7 @@ public class UonParserSession extends ParserSession {
         *      </ul>
         */
        public UonParserSession(UonParserContext ctx, Object input) {
-               super(ctx, null, input, null, null, null, null);
+               super(ctx, null, input, null, null, null, null, null);
                decodeChars = false;
                whitespaceAware = ctx.whitespaceAware;
        }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
index 7095eef..c65f674 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
@@ -404,8 +404,8 @@ public class UonSerializer extends WriterSerializer {
        
//--------------------------------------------------------------------------------
 
        @Override /* Serializer */
-       public UonSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone) {
-               return new 
UonSerializerSession(getContext(UonSerializerContext.class), op, output, 
javaMethod, locale, timeZone);
+       public UonSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+               return new 
UonSerializerSession(getContext(UonSerializerContext.class), op, output, 
javaMethod, locale, timeZone, mediaType);
        }
 
        @Override /* Serializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
index 39ace7a..f758b99 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
@@ -43,9 +43,10 @@ public class UonSerializerSession extends SerializerSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       protected UonSerializerSession(UonSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone) {
-               super(ctx, op, output, javaMethod, locale, timeZone);
+       protected UonSerializerSession(UonSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
                if (op == null || op.isEmpty()) {
                        simpleMode = ctx.simpleMode;
                        useWhitespace = ctx.useWhitespace;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index d0e11e2..32a68f2 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -18,6 +18,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
@@ -481,8 +482,8 @@ public class UrlEncodingParser extends UonParser {
        
//--------------------------------------------------------------------------------
 
        @Override /* Parser */
-       public UrlEncodingParserSession createSession(Object input, ObjectMap 
op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               return new 
UrlEncodingParserSession(getContext(UrlEncodingParserContext.class), op, input, 
javaMethod, outer, locale, timeZone);
+       public UrlEncodingParserSession createSession(Object input, ObjectMap 
op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, 
MediaType mediaType) {
+               return new 
UrlEncodingParserSession(getContext(UrlEncodingParserContext.class), op, input, 
javaMethod, outer, locale, timeZone, mediaType);
        }
 
        @Override /* Parser */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
index 5adee94..62234b9 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
@@ -50,9 +50,10 @@ public class UrlEncodingParserSession extends 
UonParserSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public UrlEncodingParserSession(UrlEncodingParserContext ctx, ObjectMap 
op, Object input, Method javaMethod, Object outer, Locale locale, TimeZone 
timeZone) {
-               super(ctx, op, input, javaMethod, outer, locale, timeZone);
+       public UrlEncodingParserSession(UrlEncodingParserContext ctx, ObjectMap 
op, Object input, Method javaMethod, Object outer, Locale locale, TimeZone 
timeZone, MediaType mediaType) {
+               super(ctx, op, input, javaMethod, outer, locale, timeZone, 
mediaType);
                if (op == null || op.isEmpty()) {
                        expandedParams = ctx.expandedParams;
                } else {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 5b8116c..64c420f 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -382,7 +382,7 @@ public class UrlEncodingSerializer extends UonSerializer {
                                        return o.toString();
 
                        StringWriter w = new StringWriter();
-                       UonSerializerSession s = createSession(w, null, null, 
null, null);
+                       UonSerializerSession s = createSession(w, null, null, 
null, null, MediaType.UON);
                        super.doSerialize(s, o);
                        return w.toString();
                } catch (Exception e) {
@@ -396,8 +396,8 @@ public class UrlEncodingSerializer extends UonSerializer {
        
//--------------------------------------------------------------------------------
 
        @Override /* Serializer */
-       public UrlEncodingSerializerSession createSession(Object output, 
ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone) {
-               return new 
UrlEncodingSerializerSession(getContext(UrlEncodingSerializerContext.class), 
op, output, javaMethod, locale, timeZone);
+       public UrlEncodingSerializerSession createSession(Object output, 
ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               return new 
UrlEncodingSerializerSession(getContext(UrlEncodingSerializerContext.class), 
op, output, javaMethod, locale, timeZone, mediaType);
        }
 
        @Override /* Serializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index e239a5c..a09d9b0 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -42,9 +42,10 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public UrlEncodingSerializerSession(UrlEncodingSerializerContext ctx, 
ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone 
timeZone) {
-               super(ctx, op, output, javaMethod, locale, timeZone);
+       public UrlEncodingSerializerSession(UrlEncodingSerializerContext ctx, 
ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone 
timeZone, MediaType mediaType) {
+               super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
                if (op == null || op.isEmpty()) {
                        expandedParams = ctx.expandedParams;
                } else {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index 378c22b..8d0932a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -22,6 +22,7 @@ import java.util.*;
 import javax.xml.stream.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.MediaType;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transform.*;
@@ -506,8 +507,8 @@ public class XmlParser extends ReaderParser {
        
//--------------------------------------------------------------------------------
 
        @Override /* Parser */
-       public XmlParserSession createSession(Object input, ObjectMap op, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               return new XmlParserSession(getContext(XmlParserContext.class), 
op, input, javaMethod, outer, locale, timeZone);
+       public XmlParserSession createSession(Object input, ObjectMap op, 
Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               return new XmlParserSession(getContext(XmlParserContext.class), 
op, input, javaMethod, outer, locale, timeZone, mediaType);
        }
 
        @Override /* Parser */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index fce4243..e6a7e13 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -65,9 +65,10 @@ public class XmlParserSession extends ParserSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public XmlParserSession(XmlParserContext ctx, ObjectMap op, Object 
input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone) {
-               super(ctx, op, input, javaMethod, outer, locale, timeZone);
+       public XmlParserSession(XmlParserContext ctx, ObjectMap op, Object 
input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, 
MediaType mediaType) {
+               super(ctx, op, input, javaMethod, outer, locale, timeZone, 
mediaType);
                if (op == null || op.isEmpty()) {
                        xsiNs = ctx.xsiNs;
                        validating = ctx.validating;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
index 4a0938e..3d9782e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
@@ -90,7 +90,7 @@ public class XmlSchemaSerializer extends XmlSerializer {
        /**
         * Returns an XML-Schema validator based on the output returned by 
{@link #doSerialize(SerializerSession, Object)};
         *
-        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone)}.<br>
+        * @param session The serializer session object return by {@link 
#createSession(Object, ObjectMap, Method, Locale, TimeZone, MediaType)}.<br>
         *      Can be <jk>null</jk>.
         * @param o The object to serialize.
         * @return The new validator.
@@ -575,11 +575,11 @@ public class XmlSchemaSerializer extends XmlSerializer {
        }
 
        @Override /* Serializer */
-       public XmlSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone) {
+       public XmlSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
                // This serializer must always have namespaces enabled.
                if (op == null)
                        op = new ObjectMap();
                op.put(XmlSerializerContext.XML_enableNamespaces, true);
-               return new 
XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, 
javaMethod, locale, timeZone);
+               return new 
XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, 
javaMethod, locale, timeZone, mediaType);
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 0d07a99..fc8385f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -754,8 +754,8 @@ public class XmlSerializer extends WriterSerializer {
        }
 
        @Override /* Serializer */
-       public XmlSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone) {
-               return new 
XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, 
javaMethod, locale, timeZone);
+       public XmlSerializerSession createSession(Object output, ObjectMap op, 
Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+               return new 
XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, 
javaMethod, locale, timeZone, mediaType);
        }
 
        @Override /* CoreApi */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java 
b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index 6a13cb4..5b1ae85 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -56,9 +56,10 @@ public class XmlSerializerSession extends SerializerSession {
         *      If <jk>null</jk>, then the locale defined on the context is 
used.
         * @param timeZone The session timezone.
         *      If <jk>null</jk>, then the timezone defined on the context is 
used.
+        * @param mediaType The session media type (e.g. 
<js>"application/json"</js>).
         */
-       public XmlSerializerSession(XmlSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone) {
-               super(ctx, op, output, javaMethod, locale, timeZone);
+       public XmlSerializerSession(XmlSerializerContext ctx, ObjectMap op, 
Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType 
mediaType) {
+               super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
                if (op == null || op.isEmpty()) {
                        enableNamespaces = ctx.enableNamespaces;
                        autoDetectNamespaces = ctx.autoDetectNamespaces;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html 
b/juneau-core/src/main/javadoc/overview.html
index 8dabebb..620e8b5 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -1570,7 +1570,7 @@
        <xt>&lt;/feed&gt;</xt>          
                </p>
                <p>
-                       The {@link org.apache.juneau.html.XmlParser} class can 
be used convert these Atom documents back
+                       The {@link org.apache.juneau.xml.XmlParser} class can 
be used convert these Atom documents back
                        into POJOs.
                </p>
                <p>
@@ -5337,12 +5337,15 @@
                                <li>{@link 
org.apache.juneau.BeanContext#BEAN_debug} - Debug setting.  Replaces individual 
debug properties in the serializer and parser contexts.
                                <li>{@link 
org.apache.juneau.BeanContext#BEAN_locale} - Specifies a default locale at the 
context level.
                                <li>{@link 
org.apache.juneau.BeanContext#BEAN_timeZone} - Specifies a default timezone at 
the context level.
+                               <li>{@link 
org.apache.juneau.BeanContext#BEAN_mediaType} - Specifies a default media type 
at the context level.
                        </ul>
                        <li>Simplified {@link 
org.apache.juneau.transform.PojoSwap} class.  Now just two methods:
                        <ul>
                                <li>{@link 
org.apache.juneau.transform.PojoSwap#swap(BeanSession,Object)}
                                <li>{@link 
org.apache.juneau.transform.PojoSwap#unswap(BeanSession,Object,ClassMeta)}
                        </ul>
+                       <li>Session-level media type now available through 
{@link org.apache.juneau.BeanSession#getMediaType()} method.
+                               Allows for swaps and serializer/parser behavior 
to be tailored to individual media types.
                        <li>Several new {@link java.util.Calendar} and {@link 
java.util.Date} swaps:
                        <ul>
                                <li>{@link 
org.apache.juneau.transforms.CalendarSwap.ToString},{@link 
org.apache.juneau.transforms.DateSwap.ToString} - To {@link java.lang.String 
Strings} using the {@code Date.toString()} method.
@@ -5369,6 +5372,9 @@
                                <li>{@link 
org.apache.juneau.transforms.CalendarSwap.DateTimeMedium},{@link 
org.apache.juneau.transforms.DateSwap.DateTimeMedium} - To {@link 
java.text.DateFormat#MEDIUM} date-time strings.
                                <li>{@link 
org.apache.juneau.transforms.CalendarSwap.DateTimeShort},{@link 
org.apache.juneau.transforms.DateSwap.DateTimeShort} - To {@link 
java.text.DateFormat#SHORT} date-time strings.
                        </ul>  
+                       <li>New method {@link 
org.apache.juneau.serializer.SerializerGroup#getSerializerMatch(String)} that 
returns the matched serializer and media type.
+                       <li>New method {@link 
org.apache.juneau.parser.ParserGroup#getParserMatch(String)} that returns the 
matched parser and media type.
+                       <li>New method {@link 
org.apache.juneau.encoders.EncoderGroup#getEncoderMatch(String)} that returns 
the matched encoder and encoding.
                        <li>General improvements to Bean Dictionary support.
                                <ul>
                                        <li>New {@link 
org.apache.juneau.BeanDictionary} class can be used for defining reusable sets 
of bean dictionaries.
@@ -5485,13 +5491,13 @@
                        <li>New methods on {@link 
org.apache.juneau.parser.Parser}:
                                <ul>
                                        
<li><code>org.apache.juneau.parser.Parser.createSession(ObjectMap,Method,Object)</code>
-                                       <li>{@link 
org.apache.juneau.parser.Parser#getMediaRanges()}
+                                       
<li><code><del>Parser.getMediaRanges()</del></code>
                                </ul>
                        </li>
                        <li>New methods on {@link 
org.apache.juneau.serializer.Serializer}:
                                <ul>
                                        
<li><code>org.apache.juneau.serializer.Serializer.createSession(ObjectMap,Method)</code>
-                                       <li>{@link 
org.apache.juneau.serializer.Serializer#getMediaRanges()}
+                                       
<li><code><del>Serializer.getMediaRanges()</del></code>
                                </ul>
                        </li>
                        <li>New {@link org.apache.juneau.annotation.Bean#sort() 
@Bean.sort()} annotation.
@@ -5623,7 +5629,7 @@
                        <li>New <del><code>StringMapVar</code></del> class.
                        <li>New <del><code>StringVars</code></del> class with 
reusable common <del><code>StringVar</code></del> instances.
                        <li>New {@link org.apache.juneau.internal.JuneauLogger} 
class.
-                       <li>Default value for {@link 
org.apache.juneau.xml.XmlParserContext#XML_trimWhitespace} changed to 
<jk>true</jk>.                       
+                       <li>Default value for 
<code><del>XmlParserContext.XML_trimWhitespace</del></code> changed to 
<jk>true</jk>.                     
                </ul>
 
                <h6 class='topic'>Server</h6>
@@ -5966,7 +5972,7 @@
                                <ul>
                                        <li>{@link 
org.apache.juneau.rest.RestRequest#getReaderResource(String)} - Replaces 
<code>getVarResource(String)</code>.
                                        <li>{@link 
org.apache.juneau.rest.RestRequest#getReaderResource(String,boolean)} 
-                                       <li>{@link 
org.apache.juneau.rest.RestRequest#getReaderResource(String,boolean,String)}
+                                       
<li><code><del>RestRequest.getReaderResource(String,boolean,String)</del></code>
                                </ul>
                        <li>Changes in {@link 
org.apache.juneau.rest.RestResponse}:
                                <ul>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 7b481d3..a088461 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -384,7 +384,7 @@ public class RestClient extends CoreApi {
         */
        public RestClient setParser(Parser parser) {
                this.parser = parser;
-               this.accept = parser.getMediaTypes()[0];
+               this.accept = 
StringUtils.toString(parser.getPrimaryMediaType());
                return this;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
index be84893..712c043 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
@@ -36,8 +36,8 @@ public final class RestRequestEntity extends BasicHttpEntity {
        public RestRequestEntity(Object input, Serializer serializer) {
                this.output = input;
                this.serializer = serializer;
-               if (serializer != null)
-                       setContentType(new BasicHeader("Content-Type", 
serializer.getResponseContentType()));
+               if (serializer != null && serializer.getResponseContentType() 
!= null)
+                       setContentType(new BasicHeader("Content-Type", 
serializer.getResponseContentType().toString()));
        }
 
        @Override /* BasicHttpEntity */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
index 81ca270..51de853 100644
--- 
a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
+++ 
b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
@@ -59,7 +59,7 @@ public final class SerializedNameValuePair implements 
NameValuePair {
                        char c = name.charAt(0);
                        if (c == '$' || c == '(') {
                                try {
-                                       UonSerializerSession s = 
serializer.createSession(new StringWriter(), op, null, null, null);
+                                       UonSerializerSession s = 
serializer.createSession(new StringWriter(), op, null, null, null, 
MediaType.UON);
                                        serializer.serialize(s, name);
                                        return s.getWriter().toString();
                                } catch (Exception e) {
@@ -73,7 +73,7 @@ public final class SerializedNameValuePair implements 
NameValuePair {
        @Override /* NameValuePair */
        public String getValue() {
                try {
-                       UonSerializerSession s = serializer.createSession(new 
StringWriter(), op, null, null, null);
+                       UonSerializerSession s = serializer.createSession(new 
StringWriter(), op, null, null, null, MediaType.UON);
                        serializer.serialize(s, value);
                        return s.getWriter().toString();
                } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
 
b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
index 2381736..bc2242f 100644
--- 
a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
+++ 
b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
@@ -21,6 +21,7 @@ import java.util.*;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.ext.*;
 
 import org.apache.juneau.*;
@@ -84,17 +85,17 @@ public class BaseProvider implements 
MessageBodyReader<Object>, MessageBodyWrite
 
        @Override /* MessageBodyWriter */
        public boolean isWriteable(Class<?> type, Type gType, Annotation[] a, 
MediaType mediaType) {
-               return serializers.findMatch(mediaType.toString()) != null;
+               return serializers.getSerializerMatch(mediaType.toString()) != 
null;
        }
 
        @Override /* MessageBodyWriter */
        public void writeTo(Object o, Class<?> type, Type gType, Annotation[] 
a, MediaType mediaType,
                        MultivaluedMap<String,Object> headers, OutputStream 
out) throws IOException, WebApplicationException {
                try {
-                       String mt = serializers.findMatch(mediaType.toString());
-                       if (mt == null)
+                       SerializerMatch sm = 
serializers.getSerializerMatch(mediaType.toString());
+                       if (sm == null)
                                throw new 
WebApplicationException(SC_NOT_ACCEPTABLE);
-                       Serializer s = serializers.getSerializer(mt);
+                       Serializer s = sm.getSerializer();
                        ObjectMap mp = getMethodProperties(a);
                        mp.append("mediaType", mediaType.toString());
                        Locale locale = getLocale(headers);
@@ -102,13 +103,13 @@ public class BaseProvider implements 
MessageBodyReader<Object>, MessageBodyWrite
                        if (s.isWriterSerializer()) {
                                WriterSerializer s2 = (WriterSerializer)s;
                                OutputStreamWriter w = new 
OutputStreamWriter(out, IOUtils.UTF8);
-                               SerializerSession session = s.createSession(w, 
mp, null, locale, timeZone);
+                               SerializerSession session = s.createSession(w, 
mp, null, locale, timeZone, sm.getMediaType());
                                s2.serialize(session, o);
                                w.flush();
                                w.close();
                        } else {
                                OutputStreamSerializer s2 = 
(OutputStreamSerializer)s;
-                               SerializerSession session = s.createSession(s2, 
mp, null, locale, timeZone);
+                               SerializerSession session = s.createSession(s2, 
mp, null, locale, timeZone, sm.getMediaType());
                                s2.serialize(session, o);
                                out.flush();
                                out.close();
@@ -120,17 +121,17 @@ public class BaseProvider implements 
MessageBodyReader<Object>, MessageBodyWrite
 
        @Override /* MessageBodyReader */
        public boolean isReadable(Class<?> type, Type gType, Annotation[] a, 
MediaType mediaType) {
-               return parsers.findMatch(mediaType.toString()) != null;
+               return parsers.getParserMatch(mediaType.toString()) != null;
        }
 
        @Override /* MessageBodyReader */
        public Object readFrom(Class<Object> type, Type gType, Annotation[] a, 
MediaType mediaType,
                        MultivaluedMap<String,String> headers, InputStream in) 
throws IOException, WebApplicationException {
                try {
-                       String mt = parsers.findMatch(mediaType.toString());
-                       if (mt == null)
+                       ParserMatch pm = 
parsers.getParserMatch(mediaType.toString());
+                       if (pm == null)
                                throw new 
WebApplicationException(SC_UNSUPPORTED_MEDIA_TYPE);
-                       Parser p = parsers.getParser(mt);
+                       Parser p = pm.getParser();
                        BeanContext bc = p.getBeanContext();
                        ClassMeta<?> cm = bc.getClassMeta(gType);
                        ObjectMap mp = getMethodProperties(a);
@@ -140,11 +141,11 @@ public class BaseProvider implements 
MessageBodyReader<Object>, MessageBodyWrite
                        if (p.isReaderParser()) {
                                ReaderParser p2 = (ReaderParser)p;
                                InputStreamReader r = new InputStreamReader(in, 
IOUtils.UTF8);
-                               ParserSession session = p2.createSession(r, mp, 
null, null, locale, timeZone);
+                               ParserSession session = p2.createSession(r, mp, 
null, null, locale, timeZone, pm.getMediaType());
                                return p2.parse(session, cm);
                        }
                        InputStreamParser p2 = (InputStreamParser)p;
-                       ParserSession session = p2.createSession(in, mp, null, 
null, locale, timeZone);
+                       ParserSession session = p2.createSession(in, mp, null, 
null, locale, timeZone, pm.getMediaType());
                        return p2.parse(session, cm);
                } catch (ParseException e) {
                        throw new IOException(e);
@@ -158,7 +159,7 @@ public class BaseProvider implements 
MessageBodyReader<Object>, MessageBodyWrite
                        if (h != null) {
                                MediaRange[] mr = MediaRange.parse(h);
                                if (mr.length > 0)
-                                       return toLocale(mr[0].getType());
+                                       return 
toLocale(mr[0].getMediaType().getType());
                        }
                }
                return null;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java 
b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
index 22e4fda..d73fdb6 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
@@ -236,7 +236,7 @@ public class GzipTest {
 
                // Should match identity
                r = c.doGet(url).setHeader("Accept-Encoding", 
"*;q=0.8,myencoding;q=0.6");
-               assertEquals("foo", decompress(r.getInputStream()));
+               assertEquals("foo", r.getResponseAsString());
 
                // Shouldn't match
                try {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/74a90ffa/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
----------------------------------------------------------------------
diff --git 
a/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java 
b/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
index 193c1ce..2dc65a1 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/ReaderResource.java
@@ -29,7 +29,7 @@ import org.apache.juneau.svl.*;
 public class ReaderResource implements Writable {
 
        private String contents;
-       private String mediaType;
+       private MediaType mediaType;
        private VarResolverSession varSession;
        private Map<String,String> headers = new LinkedHashMap<String,String>();
 
@@ -39,7 +39,7 @@ public class ReaderResource implements Writable {
         * @param contents The contents of this resource.
         * @param mediaType The HTTP media type.
         */
-       protected ReaderResource(String contents, String mediaType) {
+       protected ReaderResource(String contents, MediaType mediaType) {
                this.contents = contents;
                this.mediaType = mediaType;
        }
@@ -86,7 +86,7 @@ public class ReaderResource implements Writable {
        }
 
        @Override /* Streamable */
-       public String getMediaType() {
+       public MediaType getMediaType() {
                return mediaType;
        }
 

Reply via email to