You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/06/20 22:09:09 UTC

incubator-juneau git commit: Bug fixes and code cleanup.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master 35cb8461b -> d05dd4b10


Bug fixes and code cleanup.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/d05dd4b1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/d05dd4b1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/d05dd4b1

Branch: refs/heads/master
Commit: d05dd4b10bddd0f70074d07283382602f4f5cd94
Parents: 35cb846
Author: JamesBognar <ja...@apache.org>
Authored: Tue Jun 20 18:09:03 2017 -0400
Committer: JamesBognar <ja...@apache.org>
Committed: Tue Jun 20 18:09:03 2017 -0400

----------------------------------------------------------------------
 .../apache/juneau/utils/StringUtilsTest.java    |  22 +-
 .../main/java/org/apache/juneau/BeanMap.java    |   3 +
 .../main/java/org/apache/juneau/BeanMeta.java   |   9 +-
 .../org/apache/juneau/BeanPropertyMeta.java     |   6 +-
 .../java/org/apache/juneau/BeanSession.java     |   2 +-
 .../main/java/org/apache/juneau/ObjectMap.java  |   4 +-
 .../juneau/html/HtmlDocSerializerSession.java   |   2 +-
 .../juneau/http/HeaderEntityValidatorArray.java |   2 +-
 .../apache/juneau/http/HeaderStringArray.java   |   2 +-
 .../org/apache/juneau/http/MediaTypeRange.java  |   2 +-
 .../org/apache/juneau/http/StringRange.java     |   2 +-
 .../java/org/apache/juneau/ini/ConfigFile.java  |   2 +-
 .../org/apache/juneau/internal/DateUtils.java   |  16 +-
 .../org/apache/juneau/internal/StringUtils.java |  12 +-
 .../java/org/apache/juneau/parser/Parser.java   |   2 +-
 .../apache/juneau/serializer/Serializer.java    |   2 +-
 .../org/apache/juneau/svl/DefaultingVar.java    |   2 +-
 .../org/apache/juneau/svl/MultipartVar.java     |   2 +-
 .../transform/AnnotationBeanFilterBuilder.java  |   4 +-
 .../transform/InterfaceBeanFilterBuilder.java   |   4 +-
 .../org/apache/juneau/utils/SearchArgs.java     |   6 +-
 juneau-core/src/main/javadoc/overview.html      |   8 +-
 .../juneau/microservice/RestMicroservice.java   |   2 +-
 .../apache/juneau/rest/client/RestClient.java   |   2 -
 .../juneau/rest/client/RestClientBuilder.java   |   2 +-
 .../juneau/rest/test/BpIncludesResource.java    | 140 ++++++++++
 .../java/org/apache/juneau/rest/test/Root.java  |   1 +
 .../org/apache/juneau/rest/test/TestUtils.java  |  16 ++
 .../apache/juneau/rest/test/BpIncludesTest.java | 253 +++++++++++++++++++
 .../java/org/apache/juneau/rest/CallMethod.java |  26 +-
 .../org/apache/juneau/rest/RequestHeaders.java  |   2 +-
 .../org/apache/juneau/rest/RestContext.java     |   4 +-
 .../org/apache/juneau/rest/RestRequest.java     |  24 ++
 .../org/apache/juneau/rest/RestServlet.java     |   6 +
 .../rest/vars/SerializedRequestAttrVar.java     |   2 +-
 35 files changed, 536 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
index c7c3052..243c905 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
@@ -483,30 +483,30 @@ public class StringUtilsTest {
 	public void testSplit() throws Exception {
 		String[] r;
 
-		assertNull(split((String)null, ','));
-		assertObjectEquals("[]", split("", ','));
-		assertObjectEquals("['1']", split("1", ','));
-		assertObjectEquals("['1','2']", split("1,2", ','));
-		assertObjectEquals("['1,2']", split("1\\,2", ','));
+		assertNull(split((String)null));
+		assertObjectEquals("[]", split(""));
+		assertObjectEquals("['1']", split("1"));
+		assertObjectEquals("['1','2']", split("1,2"));
+		assertObjectEquals("['1,2']", split("1\\,2"));
 
-		r = split("1\\\\,2", ',');
+		r = split("1\\\\,2");
 		assertEquals("1\\", r[0]);
 		assertEquals("2", r[1]);
 
-		r = split("1\\\\\\,2", ',');
+		r = split("1\\\\\\,2");
 		assertEquals(1, r.length);
 		assertEquals("1\\,2", r[0]);
 
-		r = split("1,2\\", ',');
+		r = split("1,2\\");
 		assertEquals("2\\", r[1]);
 
-		r = split("1,2\\\\", ',');
+		r = split("1,2\\\\");
 		assertEquals("2\\", r[1]);
 
-		r = split("1,2\\,", ',');
+		r = split("1,2\\,");
 		assertEquals("2,", r[1]);
 
-		r = split("1,2\\\\,", ',');
+		r = split("1,2\\\\,");
 		assertEquals("2\\", r[1]);
 		assertEquals("", r[2]);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
index 6f259ad..1bdacfa 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.annotation.*;
@@ -156,6 +157,8 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 				for (Map.Entry<String,Object> e : propertyCache.entrySet())
 					put(e.getKey(), e.getValue());
 				propertyCache = null;
+			} catch (IllegalArgumentException e) {
+				throw new BeanRuntimeException("IllegalArgumentException occurred on call to class constructor ''{0}'' with argument types ''{1}''", c.getName(), JsonSerializer.DEFAULT_LAX.toString(ClassUtils.getClasses(args)));
 			} catch (Exception e) {
 				throw new BeanRuntimeException(e);
 			}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
index 770236b..777a2b4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -211,7 +211,7 @@ public class BeanMeta<T> {
 						if (constructor != null)
 							throw new BeanRuntimeException(c, "Multiple instances of '@BeanConstructor' found.");
 						constructor = (Constructor<T>)x;
-						constructorArgs = split(x.getAnnotation(BeanConstructor.class).properties(), ',');
+						constructorArgs = split(x.getAnnotation(BeanConstructor.class).properties());
 						if (constructorArgs.length != x.getParameterTypes().length)
 							throw new BeanRuntimeException(c, "Number of properties defined in '@BeanConstructor' annotation does not match number of parameters in constructor.");
 						if (! setAccessible(constructor))
@@ -441,7 +441,7 @@ public class BeanMeta<T> {
 			if (! name.isEmpty()) {
 				if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
 					return name;
-				throw new BeanRuntimeException(classMeta.getInnerClass(), "Method property ''{0}'' identified in @BeanProperty, but missing from @Bean", name);
+				return null;  // Could happen if filtered via BEAN_includeProperties/BEAN_excludeProperties.
 			}
 			name = propertyNamer.getPropertyName(f.getName());
 			if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
@@ -604,9 +604,10 @@ public class BeanMeta<T> {
 						n = bpName;
 						if (! fixedBeanProps.isEmpty())
 							if (! fixedBeanProps.contains(n))
-								throw new BeanRuntimeException(c, "Method property ''{0}'' identified in @BeanProperty, but missing from @Bean", n);
+								n = null;  // Could happen if filtered via BEAN_includeProperties/BEAN_excludeProperties
 					}
-					l.add(new BeanMethod(n, isSetter, m));
+					if (n != null)
+						l.add(new BeanMethod(n, isSetter, m));
 				}
 			}
 		}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index 6c84fd6..edf7ab2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -129,7 +129,7 @@ public class BeanPropertyMeta {
 				if (p != null) {
 					swap = getPropertyPojoSwap(p);
 					if (! p.properties().isEmpty())
-						properties = split(p.properties(), ',');
+						properties = split(p.properties());
 					bdClasses.addAll(Arrays.asList(p.beanDictionary()));
 				}
 			}
@@ -143,7 +143,7 @@ public class BeanPropertyMeta {
 					if (swap == null)
 						swap = getPropertyPojoSwap(p);
 					if (properties != null && ! p.properties().isEmpty())
-						properties = split(p.properties(), ',');
+						properties = split(p.properties());
 					bdClasses.addAll(Arrays.asList(p.beanDictionary()));
 				}
 			}
@@ -157,7 +157,7 @@ public class BeanPropertyMeta {
 					if (swap == null)
 						swap = getPropertyPojoSwap(p);
 					if (properties != null && ! p.properties().isEmpty())
-						properties = split(p.properties(), ',');
+						properties = split(p.properties());
 					bdClasses.addAll(Arrays.asList(p.beanDictionary()));
 				}
 			}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
index 2e5ab64..cf957d0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanSession.java
@@ -488,7 +488,7 @@ public class BeanSession extends Session {
 				else if (startsWith(value.toString(), '['))
 					return (T)toArray(type, new ObjectList(value.toString()).setBeanSession(this));
 				else
-					return (T)toArray(type, new ObjectList((Object[])StringUtils.split(value.toString(), ',')).setBeanSession(this));
+					return (T)toArray(type, new ObjectList((Object[])StringUtils.split(value.toString())).setBeanSession(this));
 			}
 
 			// Target type is some sort of Map that needs to be converted.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
index d3d4b87..5e00901 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
@@ -602,7 +602,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 */
 	public String[] getStringArray(String key) {
 		String s = get(String.class, key);
-		return (s == null ? new String[0] : split(s, ','));
+		return (s == null ? new String[0] : split(s));
 	}
 
 	/**
@@ -614,7 +614,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 */
 	public String[] getStringArray(String key, String[] def) {
 		String s = get(String.class, key);
-		String[] r = (s == null ? new String[0] : split(s, ','));
+		String[] r = (s == null ? new String[0] : split(s));
 		return (r.length == 0 ? def : r);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
index b874628..9f09744 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
@@ -84,7 +84,7 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession {
 			Map m = op.getMap(HTMLDOC_links, ctx.links);
 			links = ObjectUtils.isEmpty(m) ? null : new LinkedHashMap(m);
 			cssUrl = op.getString(HTMLDOC_cssUrl, ctx.cssUrl);
-			css = split(op.getString(HTMLDOC_css, null), ',');
+			css = split(op.getString(HTMLDOC_css, null));
 			nowrap = op.getBoolean(HTMLDOC_cssUrl, ctx.nowrap);
 			noResultsMessage = op.getString(HTMLDOC_noResultsMessage, ctx.noResultsMessage);
 			template = ClassUtils.newInstance(HtmlDocTemplate.class, op.get(HTMLDOC_template, ctx.template));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
index a05cc0b..3571a97 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
@@ -39,7 +39,7 @@ public class HeaderEntityValidatorArray {
 	 * @param value The raw header value.
 	 */
 	protected HeaderEntityValidatorArray(String value) {
-		String[] s = StringUtils.split(value, ',');
+		String[] s = StringUtils.split(value);
 		this.value = new EntityValidator[s.length];
 		for (int i = 0; i < s.length; i++) {
 			this.value[i] = new EntityValidator(s[i]);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java b/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
index 25a3046..78e15b8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/HeaderStringArray.java
@@ -37,7 +37,7 @@ public class HeaderStringArray {
 	 * @param value The raw header value.
 	 */
 	protected HeaderStringArray(String value) {
-		this.value = StringUtils.split(value, ',');
+		this.value = StringUtils.split(value);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/http/MediaTypeRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/MediaTypeRange.java b/juneau-core/src/main/java/org/apache/juneau/http/MediaTypeRange.java
index 7ee7a16..4ef6ff2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/MediaTypeRange.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/MediaTypeRange.java
@@ -69,7 +69,7 @@ public final class MediaTypeRange implements Comparable<MediaTypeRange>  {
 
 		Set<MediaTypeRange> ranges = new TreeSet<MediaTypeRange>();
 
-		for (String r : StringUtils.split(value, ',')) {
+		for (String r : StringUtils.split(value)) {
 			r = r.trim();
 
 			if (r.isEmpty())

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java b/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
index d347aec..4445909 100644
--- a/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
+++ b/juneau-core/src/main/java/org/apache/juneau/http/StringRange.java
@@ -75,7 +75,7 @@ public final class StringRange implements Comparable<StringRange>  {
 
 		Set<StringRange> ranges = new TreeSet<StringRange>();
 
-		for (String r : StringUtils.split(value, ',')) {
+		for (String r : StringUtils.split(value)) {
 			r = r.trim();
 
 			if (r.isEmpty())

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFile.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFile.java b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFile.java
index 12c7dfc..2cef648 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFile.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFile.java
@@ -577,7 +577,7 @@ public abstract class ConfigFile implements Map<String,Section> {
 		String s = getString(key);
 		if (s == null)
 			return def;
-		String[] r = StringUtils.isEmpty(s) ? new String[0] : split(s, ',');
+		String[] r = StringUtils.isEmpty(s) ? new String[0] : split(s);
 		return r.length == 0 ? def : r;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
index 9ca1b5e..c0a5847 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/DateUtils.java
@@ -107,6 +107,18 @@ public final class DateUtils {
 	}
 
 	/**
+	 * Parses an ISO8601 string and converts it to a {@link Calendar}.
+	 * 
+	 * @param s The string to parse.
+	 * @return The parsed value, or <jk>null</jk> if the string was <jk>null</jk> or empty.
+	 */
+	public static Calendar parseISO8601Calendar(String s) {
+		if (StringUtils.isEmpty(s))
+			return null;
+		return DatatypeConverter.parseDateTime(toValidISO8601DT(s));
+	}
+
+	/**
 	 * Formats the given date according to the RFC 1123 pattern.
 	 *
 	 * @param date The date to format.
@@ -140,10 +152,6 @@ public final class DateUtils {
 		DateFormatHolder.clearThreadLocal();
 	}
 
-	/** This class should not be instantiated. */
-	private DateUtils() {
-	}
-
 	/**
 	 * A factory for {@link SimpleDateFormat}s. The instances are stored in a threadlocal way because SimpleDateFormat
 	 * is not threadsafe as noted in {@link SimpleDateFormat its javadoc}.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
index b91727c..4e78fd0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -454,6 +454,16 @@ public final class StringUtils {
 	}
 
 	/**
+	 * Shortcut for calling <code>split(s, <js>','</js>)</code>
+	 *
+	 * @param s The string to split.  Can be <jk>null</jk>.
+	 * @return The tokens, or <jk>null</jk> if the string was null.
+	 */
+	public static String[] split(String s) {
+		return split(s, ',');
+	}
+
+	/**
 	 * Splits a character-delimited string into a string array.
 	 * Does not split on escaped-delimiters (e.g. "\,");
 	 * Resulting tokens are trimmed of whitespace.
@@ -470,7 +480,7 @@ public final class StringUtils {
 	 *
 	 * @param s The string to split.  Can be <jk>null</jk>.
 	 * @param c The character to split on.
-	 * @return The tokens.
+	 * @return The tokens, or <jk>null</jk> if the string was null.
 	 */
 	public static String[] split(String s, char c) {
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/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 6c94fc3..2eb4a5f 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
@@ -146,7 +146,7 @@ public abstract class Parser extends CoreObject {
 		if (c == null)
 			throw new RuntimeException(MessageFormat.format("Class ''{0}'' is missing the @Consumes annotation", getClass().getName()));
 
-		String[] mt = split(c.value(), ',');
+		String[] mt = split(c.value());
 		this.mediaTypes = new MediaType[mt.length];
 		for (int i = 0; i < mt.length; i++) {
 			mediaTypes[i] = MediaType.forString(mt[i]);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/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 8350093..5e6e5a5 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
@@ -56,7 +56,7 @@ public abstract class Serializer extends CoreObject {
 		if (p == null)
 			throw new RuntimeException(MessageFormat.format("Class ''{0}'' is missing the @Produces annotation", getClass().getName()));
 
-		String[] mt = split(p.value(), ',');
+		String[] mt = split(p.value());
 		this.mediaTypes = new MediaType[mt.length];
 		for (int i = 0; i < mt.length; i++) {
 			mediaTypes[i] = MediaType.forString(mt[i]);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/svl/DefaultingVar.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/DefaultingVar.java b/juneau-core/src/main/java/org/apache/juneau/svl/DefaultingVar.java
index 3d5d6da..a1142c2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/DefaultingVar.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/DefaultingVar.java
@@ -40,7 +40,7 @@ public abstract class DefaultingVar extends SimpleVar {
 		int i = s.indexOf(',');
 		if (i == -1)
 			return resolve(session, s.trim());
-		String[] s2 = split(s, ',');
+		String[] s2 = split(s);
 		String v = resolve(session, s2[0]);
 		if (v == null)
 			v = s2[1];

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/svl/MultipartVar.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/MultipartVar.java b/juneau-core/src/main/java/org/apache/juneau/svl/MultipartVar.java
index c360eb9..43cb6f7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/MultipartVar.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/MultipartVar.java
@@ -43,7 +43,7 @@ public abstract class MultipartVar extends SimpleVar {
 
 	@Override /* Var */
 	public String resolve(VarResolverSession session, String s) {
-		String[] s2 = s.indexOf(',') == -1 ? new String[]{s.trim()} : split(s, ',');
+		String[] s2 = s.indexOf(',') == -1 ? new String[]{s.trim()} : split(s);
 		return resolve(session, s2);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
index 4c1956e..4b31f35 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
@@ -41,7 +41,7 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
 			Bean b = li.previous();
 
 			if (! b.properties().isEmpty())
-				properties(split(b.properties(), ','));
+				properties(split(b.properties()));
 
 			if (! b.typeName().isEmpty())
 				typeName(b.typeName());
@@ -50,7 +50,7 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
 				sortProperties(true);
 
 			if (! b.excludeProperties().isEmpty())
-				excludeProperties(split(b.excludeProperties(), ','));
+				excludeProperties(split(b.excludeProperties()));
 
 			if (b.propertyNamer() != PropertyNamerDefault.class)
 				propertyNamer(b.propertyNamer());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
index 80f49cf..5e7faa1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
@@ -44,7 +44,7 @@ public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
 			Bean b = li.previous();
 
 			if (! b.properties().isEmpty())
-				properties(split(b.properties(), ','));
+				properties(split(b.properties()));
 
 			if (! b.typeName().isEmpty())
 				typeName(b.typeName());
@@ -53,7 +53,7 @@ public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
 				sortProperties(true);
 
 			if (! b.excludeProperties().isEmpty())
-				excludeProperties(split(b.excludeProperties(), ','));
+				excludeProperties(split(b.excludeProperties()));
 
 			try {
 				if (b.propertyNamer() != PropertyNamerDefault.class)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-core/src/main/java/org/apache/juneau/utils/SearchArgs.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/SearchArgs.java b/juneau-core/src/main/java/org/apache/juneau/utils/SearchArgs.java
index 3c486c7..b44297a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/utils/SearchArgs.java
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/SearchArgs.java
@@ -77,7 +77,7 @@ public class SearchArgs {
 		 */
 		public Builder search(String searchTerms) {
 			if (searchTerms != null) {
-				for (String s : StringUtils.split(searchTerms, ',')) {
+				for (String s : StringUtils.split(searchTerms)) {
 					int i = StringUtils.indexOf(s, '=', '>', '<');
 					if (i == -1)
 						throw new RuntimeException("Invalid search terms: '"+searchTerms+"'");
@@ -122,7 +122,7 @@ public class SearchArgs {
 		 */
 		public Builder view(String columns) {
 			if (columns != null)
-				return view(Arrays.asList(StringUtils.split(columns, ',')));
+				return view(Arrays.asList(StringUtils.split(columns)));
 			return this;
 		}
 
@@ -162,7 +162,7 @@ public class SearchArgs {
 		 */
 		public Builder sort(String sortArgs) {
 			if (sortArgs != null)
-				sort(Arrays.asList(StringUtils.split(sortArgs, ',')));
+				sort(Arrays.asList(StringUtils.split(sortArgs)));
 			return this;
 		}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/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 15aa1eb..31cf85f 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -6184,12 +6184,18 @@
 				<br>Search columns containing lists and maps.
 				<br>Sort columns containing lists and maps.
 			<li>New {@link org.apache.juneau.remoteable.RemoteMethod#returns()} annotation.
+			<li>Fixed bugs with {@link org.apache.juneau.BeanContext#BEAN_includeProperties} and {@link org.apache.juneau.BeanContext#BEAN_excludeProperties} settings.
 		</ul>
 
 		<h6 class='topic'>org.apache.juneau.rest</h6>
 		<ul class='spaced-list'>
-			<li>{@link org.apache.juneau.rest.widgets.QueryWidget} improvements.
+			<li>{@link org.apache.juneau.rest.widget.QueryWidget} improvements.
 				<br>Fields are prefilled with current search arguments.
+			<li>Two convenience methods added to {@link org.apache.juneau.rest.RestRequest}:
+				<ul>
+					<li>{@link org.apache.juneau.rest.RestRequest#attr(String,Object) attr(String,Object)}
+					<li>{@link org.apache.juneau.rest.RestRequest#prop(String,Object) prop(String,Object)}
+				</ul>
 		</ul>
 	</div>
 	

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
index a4e4953..931d4d9 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
@@ -366,7 +366,7 @@ public class RestMicroservice extends Microservice {
 			// We're using Jetty 8 that doesn't allow regular expression matching in SslContextFactory.setExcludeCipherSuites(),
 			// so to prevent having the config file list all old cipher suites, exclude the known bad ones.
 			String[] excludeCipherSuites = combine(
-				split("SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,SSL_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA", ','),
+				split("SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,SSL_DHE_DSS_WITH_DES_CBC_SHA,SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA"),
 				sslContextFactory.getExcludeCipherSuites()
 			);
 			sslContextFactory.setExcludeCipherSuites(excludeCipherSuites);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/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 6d06825..5f8d1e9 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
@@ -534,8 +534,6 @@ public class RestClient extends CoreObject {
 
 			String path = r == null ? "" : trimSlashes(r.path());
 			if (path.indexOf("://") == -1) {
-				if (path.isEmpty())
-					path = interfaceClass.getName();
 				if (rootUrl == null)
 					throw new RemoteableMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remoteable proxy.");
 				path = trimSlashes(rootUrl) + '/' + path;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index ed1d272..55d3a1c 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -219,7 +219,7 @@ public class RestClientBuilder extends CoreObjectBuilder {
 				default: throw new RuntimeException("Programmer error");
 			}
 
-			for (String p : split(sslOpts.getProtocols(), ',')) {
+			for (String p : split(sslOpts.getProtocols())) {
 				try {
 					TrustManager tm = new SimpleX509TrustManager(sslOpts.getCertValidate() == SSLOpts.CertValidate.LAX);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/BpIncludesResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/BpIncludesResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/BpIncludesResource.java
new file mode 100644
index 0000000..8960870
--- /dev/null
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/BpIncludesResource.java
@@ -0,0 +1,140 @@
+// ***************************************************************************************************************************
+// * 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.rest.test;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.jena.*;
+
+/**
+ * JUnit automated testcase resource.
+ */
+@RestResource(
+	path="/testBpIncludes"
+)
+public class BpIncludesResource extends RestServletJenaDefault {
+	private static final long serialVersionUID = 1L;
+
+	//====================================================================================================
+	// Validates that the @RestMethod(bpIncludes,bpExcludes) properties work.
+	//====================================================================================================
+
+	@RestMethod(name="GET", path="/test/a1", bpIncludes="{MyBeanA:'a,_b'}")
+	public Object testA1() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/a2", bpIncludes="{MyBeanA:'a'}")
+	public Object testA2() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/a3", bpIncludes="{MyBeanA:'_b'}")
+	public Object testA3() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/a4", bpExcludes="{MyBeanA:'a'}")
+	public Object testA4() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/a5", bpExcludes="{MyBeanA:'_b'}")
+	public Object testA5() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/a6", bpExcludes="{MyBeanA:'a,_b'}")
+	public Object testA6() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b1", bpIncludes="{MyBeanB:'a,_b'}")
+	public Object testB1() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b2", bpIncludes="{MyBeanB:'a'}")
+	public Object testB2() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b3", bpIncludes="{MyBeanB:'_b'}")
+	public Object testB3() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b4", bpExcludes="{MyBeanB:'a'}")
+	public Object testB4() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b5", bpExcludes="{MyBeanB:'_b'}")
+	public Object testB5() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/b6", bpExcludes="{MyBeanB:'a,_b'}")
+	public Object testB6() throws Exception {
+		return new MyBeanB().init();
+	}
+
+	@RestMethod(name="GET", path="/test/c1", bpIncludes="{*:'a'}")
+	public Object testC1() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	@RestMethod(name="GET", path="/test/c2", bpIncludes="{org.apache.juneau.rest.test.BpIncludesResource$MyBeanA:'a'}")
+	public Object testC2() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	// Should not match.
+	@RestMethod(name="GET", path="/test/d1", bpIncludes="{MyBean:'a'}")
+	public Object testD1() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	// Should not match.
+	@RestMethod(name="GET", path="/test/d2", bpIncludes="{MyBean*:'a'}")
+	public Object testD2() throws Exception {
+		return new MyBeanA().init();
+	}
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Beans
+	//-------------------------------------------------------------------------------------------------------------------
+
+	public static class MyBeanA {
+		public int a;
+		@BeanProperty("_b") public String b;
+
+		MyBeanA init() {
+			a = 1;
+			b = "foo";
+			return this;
+		}
+	}
+
+	@Bean(properties="_b,a")
+	public static class MyBeanB {
+		public int a;
+		@BeanProperty("_b") public String b;
+
+		MyBeanB init() {
+			a = 1;
+			b = "foo";
+			return this;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
index 3bee867..130611d 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/Root.java
@@ -22,6 +22,7 @@ import org.apache.juneau.rest.labels.*;
 	children={
 		AcceptCharsetResource.class,
 		BeanContextPropertiesResource.class,
+		BpIncludesResource.class,
 		CallbackStringsResource.class,
 		CharsetEncodingsResource.class,
 		ClientFuturesResource.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java
index 102c17e..a25626c 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/TestUtils.java
@@ -13,12 +13,14 @@
 package org.apache.juneau.rest.test;
 
 import java.text.*;
+import java.util.*;
 
 import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transforms.*;
 import org.junit.Assert;
+import org.junit.ComparisonFailure;
 
 import junit.framework.*;
 
@@ -76,4 +78,18 @@ public class TestUtils {
 		System.err.println(r); // NOT DEBUG
 		System.err.println("*** Response-End ***********************************************************************************"); // NOT DEBUG
 	}
+
+	public static void assertEqualsAfterSort(String expected, String actual, String msg, Object...args) {
+		String[] e = expected.trim().split("\n"), a = actual.trim().split("\n");
+
+		if (e.length != a.length)
+			throw new ComparisonFailure(MessageFormat.format(msg, args), expected, actual);
+
+		Arrays.sort(e);
+		Arrays.sort(a);
+
+		for (int i = 0; i < e.length; i++)
+			if (! e[i].equals(a[i]))
+				throw new ComparisonFailure(MessageFormat.format(msg, args), expected, actual);
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BpIncludesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BpIncludesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BpIncludesTest.java
new file mode 100644
index 0000000..7439d37
--- /dev/null
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BpIncludesTest.java
@@ -0,0 +1,253 @@
+// ***************************************************************************************************************************
+// * 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.rest.test;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.msgpack.*;
+import org.apache.juneau.rest.client.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class)
+public class BpIncludesTest extends RestTestcase {
+
+	@Parameterized.Parameters
+	public static Collection<Object[]> getParameters() {
+		return Arrays.asList(new Object[][] {
+			{	/* 0 */
+				"a1",
+				"{a:1,_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a><_b>foo</_b></object>",
+				"<table><tr><td>a</td><td>1</td></tr><tr><td>_b</td><td>foo</td></tr></table>",
+				"(a=1,_b=foo)",
+				"a=1&_b=foo",
+				"{a:1,_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 1 */
+				"a2",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 2 */
+				"a3",
+				"{_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><_b>foo</_b></object>",
+				"<table><tr><td>_b</td><td>foo</td></tr></table>",
+				"(_b=foo)",
+				"_b=foo",
+				"{_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 3 */
+				"a4",
+				"{_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><_b>foo</_b></object>",
+				"<table><tr><td>_b</td><td>foo</td></tr></table>",
+				"(_b=foo)",
+				"_b=foo",
+				"{_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 4 */
+				"a5",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 5 */
+				"a6",
+				"{}",
+				"<?xml version='1.0' encoding='UTF-8'?><object/>",
+				"<table></table>",
+				"()",
+				"",
+				"{}",
+				"<rdf:RDF>\n</rdf:RDF>"
+			},
+			{	/* 6 */
+				"b1",
+				"{_b:'foo',a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><_b>foo</_b><a>1</a></object>",
+				"<table><tr><td>_b</td><td>foo</td></tr><tr><td>a</td><td>1</td></tr></table>",
+				"(_b=foo,a=1)",
+				"_b=foo&a=1",
+				"{_b:'foo',a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 7 */
+				"b2",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 8 */
+				"b3",
+				"{_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><_b>foo</_b></object>",
+				"<table><tr><td>_b</td><td>foo</td></tr></table>",
+				"(_b=foo)",
+				"_b=foo",
+				"{_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 9 */
+				"b4",
+				"{_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><_b>foo</_b></object>",
+				"<table><tr><td>_b</td><td>foo</td></tr></table>",
+				"(_b=foo)",
+				"_b=foo",
+				"{_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 10 */
+				"b5",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 11 */
+				"b6",
+				"{}",
+				"<?xml version='1.0' encoding='UTF-8'?><object/>",
+				"<table></table>",
+				"()",
+				"",
+				"{}",
+				"<rdf:RDF>\n</rdf:RDF>"
+			},
+			{	/* 12 */
+				"c1",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 13 */
+				"c2",
+				"{a:1}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a></object>",
+				"<table><tr><td>a</td><td>1</td></tr></table>",
+				"(a=1)",
+				"a=1",
+				"{a:1}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 14 */
+				"d1",
+				"{a:1,_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a><_b>foo</_b></object>",
+				"<table><tr><td>a</td><td>1</td></tr><tr><td>_b</td><td>foo</td></tr></table>",
+				"(a=1,_b=foo)",
+				"a=1&_b=foo",
+				"{a:1,_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			},
+			{	/* 15 */
+				"d2",
+				"{a:1,_b:'foo'}",
+				"<?xml version='1.0' encoding='UTF-8'?><object><a>1</a><_b>foo</_b></object>",
+				"<table><tr><td>a</td><td>1</td></tr><tr><td>_b</td><td>foo</td></tr></table>",
+				"(a=1,_b=foo)",
+				"a=1&_b=foo",
+				"{a:1,_b:'foo'}",
+				"<rdf:RDF>\n<rdf:Description>\n<jp:a>1</jp:a>\n<jp:_b>foo</jp:_b>\n</rdf:Description>\n</rdf:RDF>"
+			}
+		});
+	}
+
+	private String label;
+	private String json, xml, html, uon, urlEnc, msgPack, rdfXml;
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
+
+	public BpIncludesTest(String label, String json, String xml, String html, String uon, String urlEnc, String msgPack, String rdfXml) {
+		this.label = label;
+		this.json = json;
+		this.xml = xml;
+		this.html = html;
+		this.uon = uon;
+		this.urlEnc = urlEnc;
+		this.msgPack = msgPack;
+		this.rdfXml = rdfXml;
+	}
+
+	@Test
+	public void a01_json() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("text/json+simple").getResponseAsString();
+		assertEquals(json, r);
+	}
+
+	@Test
+	public void a02_xml() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("text/xml").getResponseAsString().replace('"', '\'');
+		assertEquals(xml, r);
+	}
+
+	@Test
+	public void a03_html() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("text/html+stripped").getResponseAsString();
+		assertEquals(html, r);
+	}
+
+	@Test
+	public void a04_uon() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("text/uon").getResponseAsString();
+		assertEquals(uon, r);
+	}
+
+	@Test
+	public void a05_urlEnc() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("application/x-www-form-urlencoded").getResponseAsString();
+		assertEquals(urlEnc, r);
+	}
+
+	@Test
+	public void a06_msgPack() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("octal/msgpack").parser(MsgPackParser.DEFAULT).getResponse(ObjectMap.class).toString();
+		assertEquals(msgPack, r);
+	}
+
+	@Test
+	public void a07_rdfXml() throws Exception {
+		String r = client.doGet("/testBpIncludes/test/" + label).accept("text/xml+rdf+abbrev").getResponseAsString();
+		r = r.replaceAll("<rdf:RDF[^>]*>", "<rdf:RDF>").replace('"', '\'');
+		TestUtils.assertEqualsAfterSort(rdfXml, r, "a07_rdfXml failed");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
index 207e312..9376f0f 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/CallMethod.java
@@ -146,11 +146,13 @@ class CallMethod implements Comparable<CallMethod>  {
 
 		@SuppressWarnings({ "unchecked", "rawtypes" })
 		private Builder(Object servlet, java.lang.reflect.Method method, RestContext context) throws RestServletException {
+			String sig = method.getDeclaringClass().getName() + '.' + method.getName();
+
 			try {
 
 				RestMethod m = method.getAnnotation(RestMethod.class);
 				if (m == null)
-					throw new RestServletException("@RestMethod annotation not found on method ''{0}.{1}''", method.getDeclaringClass().getName(), method.getName());
+					throw new RestServletException("@RestMethod annotation not found on method ''{0}''", sig);
 
 				if (! m.description().isEmpty())
 					description = m.description();
@@ -260,9 +262,17 @@ class CallMethod implements Comparable<CallMethod>  {
 					for (Property p1 : m.properties())
 						sgb.property(p1.name(), p1.value());
 					if (! m.bpIncludes().isEmpty())
-						sgb.includeProperties((Map)JsonParser.DEFAULT.parse(m.bpIncludes(), Map.class, String.class, String.class));
+						try {
+							sgb.includeProperties((Map)JsonParser.DEFAULT.parse(m.bpIncludes(), Map.class, String.class, String.class));
+						} catch (ParseException e) {
+							throw new RestServletException("Invalid format for @RestMethod.bpIncludes() on method ''{0}''.  Must be a valid JSON object.  \nValue: {1}", sig, m.bpIncludes());
+						}
 					if (! m.bpExcludes().isEmpty())
-						sgb.excludeProperties((Map)JsonParser.DEFAULT.parse(m.bpExcludes(), Map.class, String.class, String.class));
+						try {
+							sgb.excludeProperties((Map)JsonParser.DEFAULT.parse(m.bpExcludes(), Map.class, String.class, String.class));
+						} catch (ParseException e) {
+							throw new RestServletException("Invalid format for @RestMethod.bpExcludes() on method ''{0}''.  Must be a valid JSON object.  \nValue: {1}", sig, m.bpExcludes());
+						}
 					sgb.beanFilters(m.beanFilters());
 					sgb.pojoSwaps(m.pojoSwaps());
 				}
@@ -304,7 +314,7 @@ class CallMethod implements Comparable<CallMethod>  {
 						try {
 							g.append(c);
 						} catch (Exception e) {
-							throw new RestServletException("Exception occurred while trying to instantiate Encoder ''{0}''", c.getSimpleName()).initCause(e);
+							throw new RestServletException("Exception occurred while trying to instantiate Encoder on method ''{0}'': ''{1}''", sig, c.getSimpleName()).initCause(e);
 						}
 					}
 					encoders = g.build();
@@ -314,7 +324,7 @@ class CallMethod implements Comparable<CallMethod>  {
 				for (String s : m.defaultRequestHeaders()) {
 					String[] h = RestUtils.parseKeyValuePair(s);
 					if (h == null)
-						throw new RestServletException("Invalid default request header specified: ''{0}''.  Must be in the format: ''name[:=]value''", s);
+						throw new RestServletException("Invalid default request header specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
 					defaultRequestHeaders.put(h[0], h[1]);
 				}
 
@@ -322,7 +332,7 @@ class CallMethod implements Comparable<CallMethod>  {
 				for (String s : m.defaultQuery()) {
 					String[] h = RestUtils.parseKeyValuePair(s);
 					if (h == null)
-						throw new RestServletException("Invalid default query parameter specified: ''{0}''.  Must be in the format: ''name[:=]value''", s);
+						throw new RestServletException("Invalid default query parameter specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
 					defaultQuery.put(h[0], h[1]);
 				}
 
@@ -330,7 +340,7 @@ class CallMethod implements Comparable<CallMethod>  {
 				for (String s : m.defaultFormData()) {
 					String[] h = RestUtils.parseKeyValuePair(s);
 					if (h == null)
-						throw new RestServletException("Invalid default form data parameter specified: ''{0}''.  Must be in the format: ''name[:=]value''", s);
+						throw new RestServletException("Invalid default form data parameter specified on method ''{0}'': ''{1}''.  Must be in the format: ''name[:=]value''", sig, s);
 					defaultFormData.put(h[0], h[1]);
 				}
 
@@ -376,7 +386,7 @@ class CallMethod implements Comparable<CallMethod>  {
 			} catch (RestServletException e) {
 				throw e;
 			} catch (Exception e) {
-				throw new RestServletException("Exception occurred while initializing method ''{0}''", method.getName()).initCause(e);
+				throw new RestServletException("Exception occurred while initializing method ''{0}''", sig).initCause(e);
 			}
 		}
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
index ea2d9de..992f954 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RequestHeaders.java
@@ -271,7 +271,7 @@ public class RequestHeaders extends TreeMap<String,String[]> {
 	 * @return A new headers object.
 	 */
 	public RequestHeaders subset(String headers) {
-		return subset(split(headers, ','));
+		return subset(split(headers));
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
index feadcdc..c04c22d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -631,7 +631,7 @@ public final class RestContext extends Context {
 			defaultCharset = ps.getProperty(REST_defaultCharset, String.class, "utf-8");
 			paramFormat = ps.getProperty(REST_paramFormat, String.class, "");
 
-			for (String m : split(ps.getProperty(REST_allowMethodParam, String.class, ""), ','))
+			for (String m : split(ps.getProperty(REST_allowMethodParam, String.class, "")))
 				if (m.equals("true"))  // For backwards compatibility when this was a boolean field.
 					allowMethodParams.add("*");
 				else
@@ -701,7 +701,7 @@ public final class RestContext extends Context {
 				for (Object o : sc.styleSheets) {
 					if (o instanceof Pair) {
 						Pair<Class<?>,String> p = (Pair<Class<?>,String>)o;
-						for (String path : split(vr.resolve(StringUtils.toString(p.second())), ','))
+						for (String path : split(vr.resolve(StringUtils.toString(p.second()))))
 							if (path.startsWith("file://"))
 								contents.add(new FileInputStream(path));
 							else

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
index faf062d..a77766d 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -213,6 +213,18 @@ public final class RestRequest extends HttpServletRequestWrapper {
 		return (o == null ? def : o);
 	}
 
+	/**
+	 * Shorthand method for calling {@link #setAttribute(String, Object)} fluently.
+	 *
+	 * @param name The request attribute name.
+	 * @param value The request attribute value.
+	 * @return This object (for method chaining).
+	 */
+	public RestRequest attr(String name, Object value) {
+		setAttribute(name, value);
+		return this;
+	}
+
 
 	//--------------------------------------------------------------------------------
 	// Properties
@@ -236,6 +248,18 @@ public final class RestRequest extends HttpServletRequestWrapper {
 	public ObjectMap getProperties() {
 		return this.properties;
 	}
+	
+	/**
+	 * Shortcut for calling <code>getProperties().append(name, value);</code> fluently.
+	 * 
+	 * @param name The property name.
+	 * @param value The property value.
+	 * @return This object (for method chaining).
+	 */
+	public RestRequest prop(String name, Object value) {
+		this.properties.append(name, value);
+		return this;
+	}
 
 
 	//--------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
index 7e6d98b..52d01b4 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -240,6 +240,12 @@ public abstract class RestServlet extends HttpServlet {
 	protected void log(Level level, Throwable cause, String msg, Object...args) {
 		if (context != null)
 			context.getLogger().log(level, cause, msg, args);
+		else {
+			// If context failed to initialize, log to the console.
+			System.err.println(MessageFormat.format(msg, args));
+			if (cause != null)
+				cause.printStackTrace();
+		}
 	}
 
 	@Override /* GenericServlet */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d05dd4b1/juneau-rest/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
index db22a53..da6f78f 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/vars/SerializedRequestAttrVar.java
@@ -51,7 +51,7 @@ public class SerializedRequestAttrVar extends StreamedVar {
 			int i = key.indexOf(',');
 			if (i == -1)
 				throw new RuntimeException("Invalid format for $SA var.  Must be of the format $SA{contentType,key[,defaultValue]}");
-			String[] s2 = split(key, ',');
+			String[] s2 = split(key);
 			RestRequest req = session.getSessionObject(RestRequest.class, RequestVar.SESSION_req);
 			if (req != null) {
 				Object o = req.getAttribute(key);