http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
new file mode 100644
index 0000000..93144eb
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
@@ -0,0 +1,819 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.utils.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+
+@SuppressWarnings({"rawtypes","javadoc"})
+public class PropertyStoreTest {
+
+       
//====================================================================================================
+       // testSimpleProperties()
+       
//====================================================================================================
+       @Test
+       public void testSimpleProperties() {
+               PropertyStore f = PropertyStore.create();
+
+               f.setProperty("A.f1", "1");
+               f.setProperty("A.f2", "2");
+
+               assertObjectEquals("{'A.f1':'1','A.f2':'2'}", 
f.getPropertyMap("A").asMap());
+
+               f.setProperty("B.f3", "3");
+               f.setProperty("A.f1", String.class);
+               f.setProperty("A.f2", 4);
+
+               assertObjectEquals("{'A.f1':'java.lang.String','A.f2':4}", 
f.getPropertyMap("A").asMap());
+
+               f.setProperty("A.f2", null);
+               f.setProperty("A.f2", null);
+               assertObjectEquals("{'A.f1':'java.lang.String'}", 
f.getPropertyMap("A").asMap());
+
+               try {
+                       f.setProperty(null, null);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Invalid property name specified: 'null'", 
e.getMessage());
+               }
+
+               try {
+                       f.addToProperty("A.f1", "foo");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot add value 'foo' (java.lang.String) 
to property 'A.f1' (SIMPLE).", e.getMessage());
+               }
+
+               try {
+                       f.removeFromProperty("A.f1", "foo");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot remove value 'foo' 
(java.lang.String) from property 'A.f1' (SIMPLE).", e.getMessage());
+               }
+
+               try {
+                       f.putToProperty("A.f1", "foo", "bar");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot put value 
'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1' (SIMPLE).", 
e.getMessage());
+               }
+
+               try {
+                       f.putToProperty("A.f1", "foo");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot put value 'foo' (java.lang.String) 
to property 'A.f1' (SIMPLE).", e.getMessage());
+               }
+       }
+
+       
//====================================================================================================
+       // testSetProperties()
+       
//====================================================================================================
+       @Test
+       public void testSetProperties() {
+               PropertyStore f = PropertyStore.create();
+               String key = "A.f1.set";
+
+               f.setProperty(key, Arrays.asList(2,3,1));
+               assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, 
null));
+
+               f.addToProperty(key, 0);
+               f.addToProperty(key, new int[]{4,5});
+               assertObjectEquals("[0,1,2,3,4,5]", f.getProperty(key, 
int[].class, null));
+               f.addToProperty(key, new 
HashSet<String>(Arrays.asList("6","7")));
+               assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, 
int[].class, null));
+               f.addToProperty(key, new int[]{4,5});
+               assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, 
int[].class, null));
+
+               f.removeFromProperty(key, 4);
+               f.removeFromProperty(key, new 
HashSet<String>(Arrays.asList("1")));
+               f.removeFromProperty(key, new String[]{"2","9"});
+               assertObjectEquals("[0,3,5,6,7]", f.getProperty(key, 
int[].class, null));
+               assertObjectEquals("['0','3','5','6','7']", f.getProperty(key, 
String[].class, null));
+
+               f.setProperty(key, Arrays.asList("foo","bar","baz"));
+               assertObjectEquals("['bar','baz','foo']", f.getProperty(key, 
String[].class, null));
+
+               f.setProperty(key, "[1,2,3]");
+               assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, 
null));
+
+               f.setProperty(key, "['1','2','3']");
+               assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, 
null));
+
+               try {
+                       f.putToProperty("A.f1.set", "foo");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot put value 'foo' (java.lang.String) 
to property 'A.f1.set' (SET).", e.getMessage());
+               }
+
+               try {
+                       f.putToProperty("A.f1.set", "foo", "bar");
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertEquals("Cannot put value 
'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1.set' 
(SET).", e.getMessage());
+               }
+       }
+
+       
//====================================================================================================
+       // testListProperties()
+       
//====================================================================================================
+       @Test
+       public void testListProperties() {
+               PropertyStore f = PropertyStore.create();
+               String key = "A.f1.list";
+
+               f.setProperty(key, Arrays.asList(2,3,1));
+               assertObjectEquals("[2,3,1]", f.getProperty(key, int[].class, 
null));
+
+               f.addToProperty(key, 0);
+               f.addToProperty(key, new int[]{4,5});
+               assertObjectEquals("[4,5,0,2,3,1]", f.getProperty(key, 
int[].class, null));
+               f.addToProperty(key, new 
TreeSet<String>(Arrays.asList("6","7")));
+               assertObjectEquals("[6,7,4,5,0,2,3,1]", f.getProperty(key, 
int[].class, null));
+               f.addToProperty(key, new int[]{4,5});
+               assertObjectEquals("[4,5,6,7,0,2,3,1]", f.getProperty(key, 
int[].class, null));
+
+               f.removeFromProperty(key, 4);
+               f.removeFromProperty(key, new 
HashSet<String>(Arrays.asList("1")));
+               f.removeFromProperty(key, new String[]{"2","9"});
+               assertObjectEquals("[5,6,7,0,3]", f.getProperty(key, 
int[].class, null));
+               assertObjectEquals("['5','6','7','0','3']", f.getProperty(key, 
String[].class, null));
+
+               f.setProperty(key, Arrays.asList("foo","bar","baz"));
+               assertObjectEquals("['foo','bar','baz']", f.getProperty(key, 
String[].class, null));
+       }
+
+       
//====================================================================================================
+       // testMapProperties()
+       
//====================================================================================================
+       @Test
+       public void testMapProperties() {
+               PropertyStore f = PropertyStore.create();
+               String key = "A.f1.map";
+
+               f.setProperty(key, new 
AMap<String,String>().append("1","1").append("3","3").append("2","2"));
+               assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, 
Integer.class, Integer.class, null));
+
+               f.setProperty(key, "{'1':1,'2':2,'3':3}");
+               assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, 
Integer.class, Integer.class, null));
+
+               f.putToProperty(key, "{'3':4,'4':5,'5':6}");
+               assertObjectEquals("{'1':1,'2':2,'3':4,'4':5,'5':6}", 
f.getMap(key, Integer.class, Integer.class, null));
+       }
+
+       
//====================================================================================================
+       // Hash code and comparison
+       
//====================================================================================================
+       @Test
+       public void testHashCodes() throws Exception {
+               PropertyStore f1 = PropertyStore.create();
+               f1.setProperty("A.a", 1);
+               f1.setProperty("A.b", true);
+               f1.setProperty("A.c", String.class);
+               f1.setProperty("A.d.set", new Object[]{1, true, String.class});
+               f1.setProperty("A.e.map", new 
AMap<Object,Object>().append(true,true).append(1,1).append(String.class,String.class));
+
+               PropertyStore f2 = PropertyStore.create();
+               f2.setProperty("A.e.map", new 
AMap<Object,Object>().append("1","1").append("true","true").append("java.lang.String","java.lang.String"));
+               f2.setProperty("A.d.set", new 
Object[]{"true","1","java.lang.String"});
+               f2.setProperty("A.c", "java.lang.String");
+               f2.setProperty("A.b", "true");
+               f2.setProperty("A.a", "1");
+
+               PropertyStore.PropertyMap p1 = f1.getPropertyMap("A");
+               PropertyStore.PropertyMap p2 = f2.getPropertyMap("A");
+               assertEquals(p1.hashCode(), p2.hashCode());
+       }
+
+       @SuppressWarnings("unchecked")
+       private static class ConversionTest {
+               PropertyStore config = PropertyStore.create();
+               String pName;
+               Object in;
+
+               private ConversionTest(String pName, Object in) {
+                       this.pName = pName;
+                       this.in = in;
+               }
+
+               private ConversionTest test(Class c, String expected) {
+                       try {
+                               config.setProperty(pName, in);
+                               assertObjectEquals(expected, 
config.getProperty(pName, c, null));
+                       } catch (Exception x) {
+                               assertEquals(expected.toString(), 
x.getLocalizedMessage());
+                       }
+                       return this;
+               }
+
+               private ConversionTest testMap(Class k, Class v, String 
expected) {
+                       try {
+                               config.setProperty(pName, in);
+                               assertObjectEquals(expected, 
config.getMap(pName, k, v, null));
+                       } catch (Exception x) {
+                               assertEquals(expected, x.getLocalizedMessage());
+                       }
+                       return this;
+               }
+       }
+
+       
//====================================================================================================
+       // Conversions on simple properties
+       
//====================================================================================================
+       @Test
+       public void testConversionsOnSimpleProperties() throws Exception {
+               String pName = "A.a";
+
+               
//--------------------------------------------------------------------------------
+               // boolean
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, true)
+                       .test(boolean.class, "true")
+                       .test(int.class, "1")
+                       .test(String.class, "'true'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 
'java.lang.Class'.  Value=true.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=true.")
+                       .test(String[].class, "['true']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 
'java.lang.Class[]'.  Value=true.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=true.")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Boolean' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=true.")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Boolean' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=true.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // int
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, 123)
+                       .test(boolean.class, "true")
+                       .test(int.class, "123")
+                       .test(String.class, "'123'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 
'java.lang.Class'.  Value=123.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=123.")
+                       .test(String[].class, "['123']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 
'java.lang.Class[]'.  Value=123.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=123.")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Integer' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=123.")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Integer' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=123.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, String.class)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 
'int'.  Value='java.lang.String'.")
+                       .test(String.class, "'java.lang.String'")
+                       .test(Class.class, "'java.lang.String'")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value='java.lang.String'.")
+                       .test(String[].class, "['class java.lang.String']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 
'java.lang.Class[]'.  Value='java.lang.String'.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value='java.lang.String'.")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Class' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value='java.lang.String'.")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Class' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value='java.lang.String'.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, "foo")
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 
'int'.  Value='foo'.")
+                       .test(String.class, "'foo'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 
'java.lang.Class'.  Value='foo'.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value='foo'.")
+                       .test(String[].class, "['foo']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 
'java.lang.Class[]'.  Value='foo'.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='foo'.")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.String' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='foo'.")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.String' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='foo'.")
+               ;
+               new ConversionTest(pName, "java.lang.String")
+                       .test(Class.class, "'java.lang.String'")
+               ;
+               new ConversionTest(pName, "true")
+                       .test(boolean.class, "true")
+               ;
+               new ConversionTest(pName, "ONE")
+                       .test(TestEnum.class, "'ONE'")
+               ;
+               new ConversionTest(pName, "123")
+                       .test(int.class, "123")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, TestEnum.ONE)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'int'.  Value='ONE'.")
+                       .test(String.class, "'ONE'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class'.  
Value='ONE'.")
+                       .test(TestEnum.class, "'ONE'")
+                       .test(String[].class, "['ONE']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class[]'.  
Value='ONE'.")
+                       .test(TestEnum[].class, "['ONE']")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='ONE'.")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='ONE'.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new String[]{"foo","bar"})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 
'int'.  Value=['foo','bar'].")
+                       .test(String.class, "'[\\'foo\\',\\'bar\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 
'java.lang.Class'.  Value=['foo','bar'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' 
to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['foo','bar'].")
+                       .test(String[].class, "['foo','bar']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 
'java.lang.Class[]'.  Value=['foo','bar'].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' 
to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value=['foo','bar'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.String[]' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['foo','bar'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.String[]' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['foo','bar'].")
+               ;
+               new ConversionTest(pName, new String[]{"ONE","TWO"})
+                       .test(TestEnum[].class, "['ONE','TWO']")
+               ;
+               new ConversionTest(pName, new String[]{"true","false"})
+                       .test(boolean[].class, "[true,false]")
+               ;
+               new ConversionTest(pName, new 
String[]{"java.lang.String","java.lang.Integer"})
+                       .test(Class[].class, 
"['java.lang.String','java.lang.Integer']")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
Class[]{String.class,Integer.class})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 
'int'.  Value=['java.lang.String','java.lang.Integer'].")
+                       .test(String.class, 
"'[\\'java.lang.String\\',\\'java.lang.Integer\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 
'java.lang.Class'.  Value=['java.lang.String','java.lang.Integer'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value=['java.lang.String','java.lang.Integer'].")
+                       .test(String[].class, 
"['java.lang.String','java.lang.Integer']")
+                       .test(Class[].class, 
"['java.lang.String','java.lang.Integer']")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to 
type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value=['java.lang.String','java.lang.Integer'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Class[]' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['java.lang.String','java.lang.Integer'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.lang.Class[]' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['java.lang.String','java.lang.Integer'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'int'.  
Value=['ONE','TWO'].")
+                       .test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.lang.Class'.  
Value=['ONE','TWO'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE','TWO'].")
+                       .test(String[].class, "['ONE','TWO']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.lang.Class[]'.  
Value=['ONE','TWO'].")
+                       .test(TestEnum[].class, "['ONE','TWO']")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['ONE','TWO'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['ONE','TWO'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<String,String>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<String,String> m1 = new 
LinkedHashMap<String,String>();
+               m1.put("foo","bar");
+               new ConversionTest(pName, m1)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'int'.  Value={foo:'bar'}.")
+                       .test(String.class, "'{foo:\\'bar\\'}'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'java.lang.Class'.  Value={foo:'bar'}.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 
'java.util.LinkedHashMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
+                       .test(String[].class, "['{foo=bar}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'java.lang.Class[]'.  Value={foo:'bar'}.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 
'java.util.LinkedHashMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
+                       .testMap(String.class, String.class, "{foo:'bar'}")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a'.  Invalid data conversion from type 
'java.util.LinkedHashMap' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value={foo:'bar'}.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<Class,Class>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<Class,Class> m2 = new 
LinkedHashMap<Class,Class>();
+               m2.put(String.class, Integer.class);
+               new ConversionTest(pName, m2)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'int'.  Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(String.class, 
"'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 
'java.util.LinkedHashMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(String[].class, "['{class java.lang.String=class 
java.lang.Integer}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to 
type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a'.  Invalid data conversion from type 
'java.util.LinkedHashMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .testMap(String.class, String.class, 
"{'java.lang.String':'java.lang.Integer'}")
+                       .testMap(Class.class, Class.class, 
"{'java.lang.String':'java.lang.Integer'}")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Namespace
+               
//--------------------------------------------------------------------------------
+               final Namespace n = new Namespace("foo","bar");
+               new ConversionTest(pName, n)
+                       .test(String.class, "'{name:\\'foo\\',uri:\\'bar\\'}'")
+                       .test(Namespace.class, "{name:'foo',uri:'bar'}");
+
+               
//--------------------------------------------------------------------------------
+               // Namespace[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new Namespace[]{n})
+                       .test(String.class, 
"'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+                       .test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
+
+               
//--------------------------------------------------------------------------------
+               // Map<Namespace,Namespace>
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
AMap<Namespace,Namespace>().append(n,n))
+                       .testMap(Namespace.class, Namespace.class, 
"{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
+                       .testMap(String.class, String.class, 
"{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
+       }
+
+       
//====================================================================================================
+       // Conversions on set properties
+       
//====================================================================================================
+       @Test
+       public void testConversionsOnSetProperties() throws Exception {
+               String pName = "A.a.set";
+
+               
//--------------------------------------------------------------------------------
+               // boolean
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, true)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[true].")
+                       .test(String.class, "'[true]'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=[true].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[true].")
+                       .test(String[].class, "['true']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=[true].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[true].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[true].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[true].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // int
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, 123)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[123].")
+                       .test(String.class, "'[123]'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=[123].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[123].")
+                       .test(String[].class, "['123']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=[123].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[123].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[123].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[123].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, String.class)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=['java.lang.String'].")
+                       .test(String.class, "'[\\'java.lang.String\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['java.lang.String'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['java.lang.String'].")
+                       .test(String[].class, "['java.lang.String']")
+                       .test(Class[].class, "['java.lang.String']")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['java.lang.String'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['java.lang.String'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['java.lang.String'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, "foo")
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['foo'].")
+                       .test(String.class, "'[\\'foo\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['foo'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['foo'].")
+                       .test(String[].class, "['foo']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=['foo'].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['foo'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['foo'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['foo'].")
+               ;
+               new ConversionTest(pName, Arrays.asList("java.lang.String"))
+                       .test(Class[].class, "['java.lang.String']")
+               ;
+               new ConversionTest(pName, Arrays.asList("true"))
+                       .test(boolean[].class, "[true]")
+               ;
+               new ConversionTest(pName, Arrays.asList("ONE"))
+                       .test(TestEnum[].class, "['ONE']")
+               ;
+               new ConversionTest(pName, Arrays.asList("123"))
+                       .test(int[].class, "[123]")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, TestEnum.ONE)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['ONE'].")
+                       .test(String.class, "'[\\'ONE\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['ONE'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE'].")
+                       .test(String[].class, "['ONE']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=['ONE'].")
+                       .test(TestEnum[].class, "['ONE']")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new String[]{"foo","bar"})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=['bar','foo'].")
+                       .test(String.class, "'[\\'bar\\',\\'foo\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['bar','foo'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['bar','foo'].")
+                       .test(String[].class, "['bar','foo']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=['bar','foo'].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['bar','foo'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['bar','foo'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['bar','foo'].")
+               ;
+               new ConversionTest(pName, new String[]{"ONE","TWO"})
+                       .test(TestEnum[].class, "['ONE','TWO']")
+               ;
+               new ConversionTest(pName, new String[]{"true","false"})
+                       .test(boolean[].class, "[false,true]")
+               ;
+               new ConversionTest(pName, new 
String[]{"java.lang.String","java.lang.Integer"})
+                       .test(Class[].class, 
"['java.lang.Integer','java.lang.String']")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
Class[]{String.class,Integer.class})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=['java.lang.Integer','java.lang.String'].")
+                       .test(String.class, 
"'[\\'java.lang.Integer\\',\\'java.lang.String\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['java.lang.Integer','java.lang.String'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value=['java.lang.Integer','java.lang.String'].")
+                       .test(String[].class, 
"['java.lang.Integer','java.lang.String']")
+                       .test(Class[].class, 
"['java.lang.Integer','java.lang.String']")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value=['java.lang.Integer','java.lang.String'].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['java.lang.Integer','java.lang.String'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['java.lang.Integer','java.lang.String'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=['ONE','TWO'].")
+                       .test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=['ONE','TWO'].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE','TWO'].")
+                       .test(String[].class, "['ONE','TWO']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=['ONE','TWO'].")
+                       .test(TestEnum[].class, "['ONE','TWO']")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=['ONE','TWO'].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=['ONE','TWO'].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<String,String>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<String,String> m1 = new 
LinkedHashMap<String,String>();
+               m1.put("foo","bar");
+               new ConversionTest(pName, m1)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=[{foo:'bar'}].")
+                       .test(String.class, "'[{foo:\\'bar\\'}]'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=[{foo:'bar'}].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[{foo:'bar'}].")
+                       .test(String[].class, "['{foo:\\'bar\\'}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=[{foo:'bar'}].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[{foo:'bar'}].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=[{foo:'bar'}].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=[{foo:'bar'}].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<Class,Class>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<Class,Class> m2 = new 
LinkedHashMap<Class,Class>();
+               m2.put(String.class, Integer.class);
+               new ConversionTest(pName, m2)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .test(String.class, 
"'[{\\'java.lang.String\\':\\'java.lang.Integer\\'}]'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .test(String[].class, 
"['{\\'java.lang.String\\':\\'java.lang.Integer\\'}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value=[{'java.lang.String':'java.lang.Integer'}].")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Namespace
+               
//--------------------------------------------------------------------------------
+               final Namespace n = new Namespace("foo","bar");
+               new ConversionTest(pName, Arrays.asList(n))
+                       .test(String.class, 
"'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+                       .test(Namespace.class, "Could not retrieve property 
store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'org.apache.juneau.xml.Namespace'.  Value=[{name:'foo',uri:'bar'}].");
+
+               
//--------------------------------------------------------------------------------
+               // Namespace[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new Namespace[]{n})
+                       .test(String.class, 
"'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+                       .test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
+
+               
//--------------------------------------------------------------------------------
+               // Map<Namespace,Namespace>
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
AMap<Namespace,Namespace>().append(n,n))
+                       .testMap(Namespace.class, Namespace.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<org.apache.juneau.xml.Namespace,org.apache.juneau.xml.Namespace>'.
  Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].")
+                       .testMap(String.class, String.class, "Could not 
retrieve property store property 'A.a.set'.  Invalid data conversion from type 
'java.util.concurrent.ConcurrentSkipListSet' to type 
'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  
Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].");
+       }
+
+
+       
//====================================================================================================
+       // Conversions on map properties
+       
//====================================================================================================
+       @Test
+       public void testConversionsOnMapProperties() throws Exception {
+               String pName = "A.a.map";
+
+               
//--------------------------------------------------------------------------------
+               // boolean
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, true)
+                       .test(boolean.class, "Cannot put value true 
(java.lang.Boolean) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // int
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, 123)
+                       .test(int.class, "Cannot put value 123 
(java.lang.Integer) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, String.class)
+                       .test(Class.class, "Cannot put value 'java.lang.String' 
(java.lang.Class) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, "foo")
+                       .test(String.class, "Cannot put value 'foo' 
(java.lang.String) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, TestEnum.ONE)
+                       .test(TestEnum.class, "Cannot put value 'ONE' 
(org.apache.juneau.PropertyStoreTest$TestEnum) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // String[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new String[]{"foo","bar"})
+                       .test(String[].class, "Cannot put value ['foo','bar'] 
(java.lang.String[]) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Class[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
Class[]{String.class,Integer.class})
+                       .test(Class[].class, "Cannot put value 
['java.lang.String','java.lang.Integer'] (java.lang.Class[]) to property 
'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // enum[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+                       .test(TestEnum[].class, "Cannot put value ['ONE','TWO'] 
(org.apache.juneau.PropertyStoreTest$TestEnum[]) to property 'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<String,String>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<String,String> m1 = new 
LinkedHashMap<String,String>();
+               m1.put("foo","bar");
+               new ConversionTest(pName, m1)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'int'.  Value={foo:'bar'}.")
+                       .test(String.class, "'{foo:\\'bar\\'}'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  
Value={foo:'bar'}.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
+                       .test(String[].class, "['{foo=bar}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  
Value={foo:'bar'}.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
+                       .testMap(String.class, String.class, "{foo:'bar'}")
+                       .testMap(Class.class, Class.class, "Could not retrieve 
property store property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 
'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  
Value={foo:'bar'}.")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<Class,Class>
+               
//--------------------------------------------------------------------------------
+               LinkedHashMap<Class,Class> m2 = new 
LinkedHashMap<Class,Class>();
+               m2.put(String.class, Integer.class);
+               new ConversionTest(pName, m2)
+                       .test(boolean.class, "false")
+                       .test(int.class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'int'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(String.class, 
"'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
+                       .test(Class.class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(TestEnum.class, "Could not retrieve property 
store property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(String[].class, "['{class java.lang.String=class 
java.lang.Integer}']")
+                       .test(Class[].class, "Could not retrieve property store 
property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .test(TestEnum[].class, "Could not retrieve property 
store property 'A.a.map'.  Invalid data conversion from type 
'java.util.Collections$SynchronizedMap' to type 
'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  
Value={'java.lang.String':'java.lang.Integer'}.")
+                       .testMap(String.class, String.class, 
"{'java.lang.String':'java.lang.Integer'}")
+                       .testMap(Class.class, Class.class, 
"{'java.lang.String':'java.lang.Integer'}")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Namespace
+               
//--------------------------------------------------------------------------------
+               final Namespace n = new Namespace("foo","bar");
+               new ConversionTest(pName, Arrays.asList(n))
+                       .test(String.class, "Cannot put value 
[{name:'foo',uri:'bar'}] (java.util.Arrays$ArrayList) to property 'A.a.map' 
(MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Namespace[]
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new Namespace[]{n})
+                       .test(String.class, "Cannot put value 
[{name:'foo',uri:'bar'}] (org.apache.juneau.xml.Namespace[]) to property 
'A.a.map' (MAP).")
+               ;
+
+               
//--------------------------------------------------------------------------------
+               // Map<Namespace,Namespace>
+               
//--------------------------------------------------------------------------------
+               new ConversionTest(pName, new 
AMap<Namespace,Namespace>().append(n,n))
+                       .testMap(Namespace.class, Namespace.class, 
"{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
+                       .testMap(String.class, String.class, 
"{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
+       }
+
+       public enum TestEnum {
+               ONE,TWO,TREE;
+       }
+
+       
//====================================================================================================
+       // testSystemPropertyDefaults()
+       
//====================================================================================================
+       @Test
+       public void testSystemPropertyDefaults() {
+               System.setProperty("Foo.f1", "true");
+               System.setProperty("Foo.f2", "123");
+               System.setProperty("Foo.f3", "TWO");
+
+               PropertyStore f = PropertyStore.create();
+
+               assertObjectEquals("true", f.getProperty("Foo.f1", 
boolean.class, false));
+               assertObjectEquals("123", f.getProperty("Foo.f2", int.class, 
0));
+               assertObjectEquals("'TWO'", f.getProperty("Foo.f3", 
TestEnum.class, TestEnum.ONE));
+
+               f.setProperty("Foo.f1", false);
+               f.setProperty("Foo.f2", 456);
+               f.setProperty("Foo.f3", TestEnum.TREE);
+
+               assertObjectEquals("false", f.getProperty("Foo.f1", 
boolean.class, false));
+               assertObjectEquals("456", f.getProperty("Foo.f2", int.class, 
0));
+               assertObjectEquals("'TREE'", f.getProperty("Foo.f3", 
TestEnum.class, TestEnum.ONE));
+       }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
new file mode 100755
index 0000000..9356686
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
@@ -0,0 +1,530 @@
+// 
***************************************************************************************************************************
+// * 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;
+
+import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.*;
+import javax.xml.parsers.*;
+import javax.xml.transform.dom.*;
+import javax.xml.transform.stream.*;
+import javax.xml.validation.*;
+
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transforms.*;
+import org.apache.juneau.utils.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+import org.w3c.dom.*;
+import org.w3c.dom.bootstrap.*;
+import org.w3c.dom.ls.*;
+import org.xml.sax.*;
+
+@SuppressWarnings({"javadoc"})
+public class TestUtils {
+
+       private static JsonSerializer js = new JsonSerializerBuilder()
+               .simple()
+               .trimNullProperties(false)
+               .build();
+
+       private static JsonSerializer jsSorted = new JsonSerializerBuilder()
+               .simple()
+               .sortCollections(true)
+               .sortMaps(true)
+               .trimNullProperties(false)
+               .build();
+
+
+       private static JsonSerializer js2 = new JsonSerializerBuilder()
+               .simple()
+               .pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+               .build();
+
+       private static JsonSerializer js3 = new JsonSerializerBuilder()
+               .simple()
+               .pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+               .sortProperties(true)
+               .build();
+
+       private static final BeanSession beanSession = 
BeanContext.DEFAULT.createSession();
+
+       /**
+        * Verifies that two objects are equivalent.
+        * Does this by doing a string comparison after converting both to JSON.
+        */
+       public static void assertEqualObjects(Object o1, Object o2) throws 
SerializeException {
+               assertEqualObjects(o1, o2, false);
+       }
+
+       /**
+        * Verifies that two objects are equivalent.
+        * Does this by doing a string comparison after converting both to JSON.
+        * @param sort If <jk>true</jk> sort maps and collections before 
comparison.
+        */
+       public static void assertEqualObjects(Object o1, Object o2, boolean 
sort) throws SerializeException {
+               JsonSerializer s = (sort ? jsSorted : js);
+               String s1 = s.serialize(o1);
+               String s2 = s.serialize(o2);
+               if (s1.equals(s2))
+                       return;
+               throw new ComparisonFailure(null, s1, s2);
+       }
+
+       /**
+        * Validates that the whitespace is correct in the specified XML.
+        */
+       public static void checkXmlWhitespace(String out) throws 
SerializeException {
+               if (out.indexOf('\u0000') != -1) {
+                       for (String s : out.split("\u0000"))
+                               checkXmlWhitespace(s);
+                       return;
+               }
+
+               int indent = -1;
+               Pattern startTag = 
Pattern.compile("^(\\s*)<[^/>]+(\\s+\\S+=['\"]\\S*['\"])*\\s*>$");
+               Pattern endTag = Pattern.compile("^(\\s*)</[^>]+>$");
+               Pattern combinedTag = 
Pattern.compile("^(\\s*)<[^>/]+(\\s+\\S+=['\"]\\S*['\"])*\\s*/>$");
+               Pattern contentOnly = Pattern.compile("^(\\s*)[^\\s\\<]+$");
+               Pattern tagWithContent = 
Pattern.compile("^(\\s*)<[^>]+>.*</[^>]+>$");
+               String[] lines = out.split("\n");
+               try {
+                       for (int i = 0; i < lines.length; i++) {
+                               String line = lines[i];
+                               Matcher m = startTag.matcher(line);
+                               if (m.matches()) {
+                                       indent++;
+                                       if (m.group(1).length() != indent)
+                                               throw new 
SerializeException("Wrong indentation detected on start tag line ''{0}''", i+1);
+                                       continue;
+                               }
+                               m = endTag.matcher(line);
+                               if (m.matches()) {
+                                       if (m.group(1).length() != indent)
+                                               throw new 
SerializeException("Wrong indentation detected on end tag line ''{0}''", i+1);
+                                       indent--;
+                                       continue;
+                               }
+                               m = combinedTag.matcher(line);
+                               if (m.matches()) {
+                                       indent++;
+                                       if (m.group(1).length() != indent)
+                                               throw new 
SerializeException("Wrong indentation detected on combined tag line ''{0}''", 
i+1);
+                                       indent--;
+                                       continue;
+                               }
+                               m = contentOnly.matcher(line);
+                               if (m.matches()) {
+                                       indent++;
+                                       if (m.group(1).length() != indent)
+                                               throw new 
SerializeException("Wrong indentation detected on content-only line ''{0}''", 
i+1);
+                                       indent--;
+                                       continue;
+                               }
+                               m = tagWithContent.matcher(line);
+                               if (m.matches()) {
+                                       indent++;
+                                       if (m.group(1).length() != indent)
+                                               throw new 
SerializeException("Wrong indentation detected on tag-with-content line 
''{0}''", i+1);
+                                       indent--;
+                                       continue;
+                               }
+                               throw new SerializeException("Unmatched 
whitespace line at line number ''{0}''", i+1);
+                       }
+                       if (indent != -1)
+                               throw new SerializeException("Possible 
unmatched tag.  indent=''{0}''", indent);
+               } catch (SerializeException e) {
+                       printLines(lines);
+                       throw e;
+               }
+       }
+
+       private static void printLines(String[] lines) {
+               for (int i = 0; i < lines.length; i++)
+                       System.err.println(String.format("%4s:" + lines[i], 
i+1)); // NOT DEBUG
+       }
+
+       /**
+        * Validates that the specified XML conforms to the specified schema.
+        */
+       private static void validateXml(String xml, String xmlSchema) throws 
Exception {
+               // parse an XML document into a DOM tree
+               DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
+               f.setNamespaceAware(true);
+               DocumentBuilder documentBuilder = f.newDocumentBuilder();
+               Document document = documentBuilder.parse(new InputSource(new 
StringReader(xml)));
+
+               // create a SchemaFactory capable of understanding WXS schemas
+               SchemaFactory factory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+               if (xmlSchema.indexOf('\u0000') != -1) {
+
+                       // Break it up into a map of namespaceURI->schema 
document
+                       final Map<String,String> schemas = new 
HashMap<String,String>();
+                       String[] ss = xmlSchema.split("\u0000");
+                       xmlSchema = ss[0];
+                       for (String s : ss) {
+                               Matcher m = pTargetNs.matcher(s);
+                               if (m.find())
+                                       schemas.put(m.group(1), s);
+                       }
+
+                       // Create a custom resolver
+                       factory.setResourceResolver(
+                               new LSResourceResolver() {
+
+                                       @Override /* LSResourceResolver */
+                                       public LSInput resolveResource(String 
type, String namespaceURI, String publicId, String systemId, String baseURI) {
+
+                                               String schema = 
schemas.get(namespaceURI);
+                                               if (schema == null)
+                                                       throw new 
FormattedRuntimeException("No schema found for namespaceURI ''{0}''", 
namespaceURI);
+
+                                               try {
+                                                       
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
+                                                       DOMImplementationLS 
domImplementationLS = (DOMImplementationLS)registry.getDOMImplementation("LS 
3.0");
+                                                       LSInput in = 
domImplementationLS.createLSInput();
+                                                       
in.setCharacterStream(new StringReader(schema));
+                                                       
in.setSystemId(systemId);
+                                                       return in;
+
+                                               } catch (Exception e) {
+                                                       throw new 
RuntimeException(e);
+                                               }
+                                       }
+                               }
+                       );
+               }
+
+               Schema schema = factory.newSchema(new StreamSource(new 
StringReader(xmlSchema)));
+
+               // create a Validator instance, which can be used to validate 
an instance document
+               Validator validator = schema.newValidator();
+
+               // validate the DOM tree
+               validator.validate(new DOMSource(document));
+       }
+
+       private static Pattern pTargetNs = 
Pattern.compile("targetNamespace=['\"]([^'\"]+)['\"]");
+
+       public static void validateXml(Object o) throws Exception {
+               validateXml(o, XmlSerializer.DEFAULT_NS_SQ);
+       }
+
+       /**
+        * Test whitespace and generated schema.
+        */
+       public static void validateXml(Object o, XmlSerializer s) throws 
Exception {
+               s = s.builder().ws().ns().addNamespaceUrisToRoot(true).build();
+               String xml = s.serialize(o);
+
+               String xmlSchema = null;
+               try {
+                       xmlSchema = s.getSchemaSerializer().serialize(o);
+                       TestUtils.checkXmlWhitespace(xml);
+                       TestUtils.checkXmlWhitespace(xmlSchema);
+                       TestUtils.validateXml(xml, xmlSchema);
+               } catch (Exception e) {
+                       System.err.println("---XML---");       // NOT DEBUG
+                       System.err.println(xml);               // NOT DEBUG
+                       System.err.println("---XMLSchema---"); // NOT DEBUG
+                       System.err.println(xmlSchema);         // NOT DEBUG
+                       throw e;
+               }
+       }
+
+       /**
+        * Reads the specified file at the specified path.
+        * Removes '\r' characters.
+        * Remove license headers.
+        */
+       public static String readFile(String path) throws Exception {
+               InputStream is = TestUtils.class.getResourceAsStream(path);
+               if (is == null) {
+                       is = new FileInputStream(path);
+               }
+               String e = read(is);
+               e = e.replaceAll("\r", "");
+               if (path.endsWith(".xml")) {
+                       e = e.replaceAll("(?s)\\<\\!\\-\\-(.*)\\-\\-\\>\\s*", 
"");
+                       e = e.replaceAll("\\<\\?.*\\?\\>\\s*", "");
+               } else if (path.endsWith(".json")) {
+                       e = e.replaceAll("\\/\\/ \\*.*\\s*", "");
+               }
+               return e;
+       }
+
+       final protected static char[] hexArray = 
"0123456789ABCDEF".toCharArray();
+       public static String toHex(byte b) {
+               char[] c = new char[2];
+               int v = b & 0xFF;
+               c[0] = hexArray[v >>> 4];
+               c[1] = hexArray[v & 0x0F];
+               return new String(c);
+       }
+
+       public static void debugOut(Object o) {
+               try {
+                       
System.err.println(decodeHex(JsonSerializer.DEFAULT_LAX.serialize(o))); // NOT 
DEBUG
+               } catch (SerializeException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Sort an XML document by element and attribute names.
+        * This method is primarily meant for debugging purposes.
+        */
+       private static final String sortXml(String xml) throws Exception {
+               xml = xml.replaceAll("\\w+\\:", "").replaceAll(">\\s+<", "><"); 
 // Strip out all namespaces and whitespace.
+
+               DocumentBuilderFactory dbf = 
DocumentBuilderFactory.newInstance();
+               DocumentBuilder db = dbf.newDocumentBuilder();
+               Document doc = db.parse(new InputSource(new StringReader(xml)));
+
+               SortedNode n = new SortedNode(doc.getDocumentElement());
+               return n.toString();
+       }
+
+       /**
+        * A sorted node in a DOM tree.
+        */
+       private static class SortedNode implements Comparable<SortedNode> {
+               public String name, text="", attrs="";
+               public List<SortedNode> children = new LinkedList<SortedNode>();
+
+               SortedNode(Element e) {
+                       this.name = e.getNodeName();
+                       NamedNodeMap attrs = e.getAttributes();
+                       if (attrs != null) {
+                               StringBuilder sb = new StringBuilder();
+                               Set<String> attrNames = new TreeSet<String>();
+                               for (int i = 0; i < attrs.getLength(); i++)
+                                       
attrNames.add(attrs.item(i).getNodeName());
+                               for (String n : attrNames) {
+                                       Node node = attrs.getNamedItem(n);
+                                       sb.append(" 
").append(n).append("='").append(node.getNodeValue()).append("'");
+                               }
+                               this.attrs = sb.toString();
+                       }
+                       NodeList nl = e.getChildNodes();
+                       for (int i = 0; i < nl.getLength(); i++) {
+                               Node n = nl.item(i);
+                               if (n instanceof Element)
+                                       children.add(new 
SortedNode((Element)nl.item(i)));
+                               if (n instanceof Text)
+                                       this.text += ((Text)n).getNodeValue();
+                       }
+                       Collections.sort(children);
+               }
+
+               @Override
+               public int compareTo(SortedNode n) {
+                       int i = name.compareTo(n.name);
+                       if (i != 0)
+                               return i;
+                       i = attrs.compareTo(n.attrs);
+                       if (i != 0)
+                               return i;
+                       i = text.compareTo(n.text);
+                       if (i != 0)
+                               return i;
+                       return 0;
+               }
+
+               @Override
+               public String toString() {
+                       return toString(0, new StringBuilder()).toString();
+               }
+
+               public StringBuilder toString(int depth ,StringBuilder sb) {
+                       indent(depth, 
sb).append("<").append(name).append(attrs);
+                       if (children.isEmpty() && text.isEmpty()) {
+                               sb.append("/>\n");
+                               return sb;
+                       }
+                       sb.append(">\n");
+                       if (! text.isEmpty())
+                               indent(depth+1, sb).append(text).append("\n");
+                       for (SortedNode c : children) {
+                               c.toString(depth+1, sb);
+                       }
+                       indent(depth, 
sb).append("</").append(name).append(">\n");
+                       return sb;
+               }
+       }
+
+       private static StringBuilder indent(int depth, StringBuilder sb) {
+               for (int i = 0; i < depth; i++)
+                       sb.append("\t");
+               return sb;
+       }
+
+       /**
+        * Compares two XML documents for equality.
+        * Namespaces are stripped from each and elements/attributes are 
ordered in alphabetical order,
+        *      then a simple string comparison is performed.
+        */
+       public static final void assertXmlEquals(String expected, String 
actual) throws Exception {
+               Assert.assertEquals(sortXml(expected), sortXml(actual));
+       }
+
+       /**
+        * Assert that the object equals the specified string after running it 
through JsonSerializer.DEFAULT_LAX.toString().
+        */
+       public static void assertObjectEquals(String s, Object o) {
+               assertObjectEquals(s, o, js2);
+       }
+
+       /**
+        * Assert that the object equals the specified string after running it 
through JsonSerializer.DEFAULT_LAX.toString()
+        * with BEAN_sortProperties set to true.
+        */
+       public static void assertSortedObjectEquals(String s, Object o) {
+               assertObjectEquals(s, o, js3);
+       }
+
+       /**
+        * Assert that the object equals the specified string after running it 
through ws.toString().
+        */
+       public static void assertObjectEquals(String s, Object o, 
WriterSerializer ws) {
+               Assert.assertEquals(s, ws.toString(o));
+       }
+
+       /**
+        * Replaces all newlines with pipes, then compares the strings.
+        */
+       public static void assertTextEquals(String s, Object o) {
+               String s2 = o.toString().replaceAll("\\r?\\n", "|");
+               Assert.assertEquals(s, s2);
+       }
+
+       public static String toReadableBytes(byte[] b) {
+               StringBuilder sb = new StringBuilder();
+               for (byte b2 : b)
+                       sb.append((b2 < ' ' || b2 > 'z') ? 
String.format("[%02X]", b2) : (char)b2 + "   ");
+               sb.append("\n");
+               for (byte b2 : b)
+                       sb.append(String.format("[%02X]", b2));
+               return sb.toString();
+       }
+
+       public static String toReadableBytes2(byte[] b) {
+               StringBuilder sb = new StringBuilder();
+               for (byte b2 : b)
+                       sb.append(String.format("%02X ", b2));
+               return sb.toString().trim();
+       }
+
+       /**
+        * Tries to turn the serialized output to a String.
+        * If it's a byte[], convert it to a UTF-8 encoded String.
+        */
+       public static String toString(Object o) {
+               if (o == null)
+                       return null;
+               if (o instanceof String)
+                       return (String)o;
+               if (o instanceof byte[])
+                       return new String((byte[])o, UTF8);
+               return o.toString();
+       }
+
+       private static ThreadLocal<TimeZone> systemTimeZone = new 
ThreadLocal<TimeZone>();
+       private static ThreadLocal<Locale> systemLocale = new 
ThreadLocal<Locale>();
+
+       /**
+        * Temporarily sets the default system timezone to the specified 
timezone ID.
+        * Use {@link #unsetTimeZone()} to unset it.
+        *
+        * @param name
+        */
+       public static void setTimeZone(String name) {
+               systemTimeZone.set(TimeZone.getDefault());
+               TimeZone.setDefault(TimeZone.getTimeZone(name));
+       }
+
+       public static void unsetTimeZone() {
+               TimeZone.setDefault(systemTimeZone.get());
+       }
+
+       /**
+        * Temporarily sets the default system locale to the specified locale.
+        * Use {@link #unsetLocale()} to unset it.
+        *
+        * @param name
+        */
+       public static void setLocale(Locale locale) {
+               systemLocale.set(Locale.getDefault());
+               Locale.setDefault(locale);
+       }
+
+       public static void unsetLocale() {
+               Locale.setDefault(systemLocale.get());
+       }
+
+       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(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(format(msg, args), 
expected, actual);
+       }
+
+       /**
+        * Same as {@link Assert#assertEquals(String,String,String) except 
takes in a MessageFormat-style message.
+        */
+       public static void assertEquals(Object expected, Object actual, String 
msg, Object...args) {
+               if ("xxx".equals(expected))
+                       System.err.println("actual=["+actual+"]");
+               if (! isEquals(expected, actual))
+                       throw new ComparisonFailure(format(msg, args), 
toString(expected), toString(actual));
+       }
+
+       /**
+        * Creates a ClassMeta for the given types.
+        */
+       public static Type getType(Type type, Type...args) {
+               return beanSession.getClassMeta(type, args);
+       }
+
+       /**
+        * Throws an AssertionError if the object isn't of the specified type.
+        */
+       public static void assertType(Class<?> type, Object o) {
+               if (type.isInstance(o))
+                       return;
+               throw new AssertionError(new StringMessage("Expected type {0} 
but was {1}", type, (o == null ? null : o.getClass())));
+       }
+
+       private static boolean isEquals(Object o1, Object o2) {
+               if (o1 == null)
+                       return o2 == null;
+               if (o2 == null)
+                       return false;
+               return o1.equals(o2);
+       }
+}

Reply via email to