Commits

John Marsden committed 6122b18

Inspector Update. Marshaller Update.

  • Participants
  • Parent commits c99a700

Comments (0)

Files changed (11)

src/main/java/cc/plural/jsonij/JSONMarshaler.java

 package cc.plural.jsonij;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 import cc.plural.jsonij.marshal.JSONDocumentMarshaler;
 import cc.plural.jsonij.marshal.JSONMarshalerException;
 import cc.plural.jsonij.marshal.JavaMarshaler;
 import cc.plural.jsonij.parser.ParserException;
-import java.io.InputStream;
 
 /**
  *

src/main/java/cc/plural/jsonij/marshal/Inspector.java

  * 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
+ * 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 cc.plural.jsonij.marshal;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import cc.plural.jsonij.marshal.InspectorProperty.TYPE;
 import cc.plural.jsonij.marshal.annotation.JSONAccessor;
+import cc.plural.jsonij.marshal.annotation.JSONCollector;
 import cc.plural.jsonij.marshal.annotation.JSONIgnore;
 import cc.plural.jsonij.marshal.annotation.JSONMutator;
 import cc.plural.jsonij.marshal.annotation.JSONName;
 public class Inspector {
 
     public static final String IS_PREFIX;
+
     public static final String SET_PREFIX;
+
     public static final String GET_PREFIX;
-    Object o;
-    Class<?> c;
-    InspectorProperty[] properties;
-    InspectorFilter filter;
-    boolean innerArray;
-    boolean innerObject;
+
+    private Object o;
+
+    private Class<?> c;
+
+    private InspectorProperty[] properties;
+
+    private InspectorFilter filter;
+
+    private boolean innerArray;
+
+    private boolean innerObject;
 
     static {
         IS_PREFIX = "is";
     public boolean hasInnerObject() {
         return innerObject;
     }
-    
+
     public boolean hasProperty(String name) {
-        for(InspectorProperty property: properties) {
+        for(InspectorProperty property : properties) {
             if(property.getPropertyName().equals(name)) {
                 return true;
             }
         }
         return false;
     }
-    
+
     public InspectorProperty getProperty(String name) {
-        for(InspectorProperty property: properties) {
+        for(InspectorProperty property : properties) {
             if(property.getPropertyName().equals(name)) {
                 return property;
             }
         }
         return null;
     }
-    
 
     public void inspect() {
-        if (o == null && c == null) {
+        if(o == null && c == null) {
             return;
         }
-        if (o != null) {
+        if(o != null) {
             c = o.getClass();
         }
         Class<?> objectClass = c;
         // Inspect Properties
         InspectorProperty[] propertyList = getMethodProperties(objectClass);
-        if (propertyList != null) {
+        if(propertyList != null) {
             InspectorProperty[] fieldPropertyList = getAttributeProperties(objectClass);
-            if (fieldPropertyList != null) {
+            if(fieldPropertyList != null) {
                 HashMap<String, InspectorProperty> propertiesMap = new HashMap<String, InspectorProperty>();
-                for (InspectorProperty prop : propertyList) {
+                for(InspectorProperty prop : propertyList) {
                     propertiesMap.put(prop.getPropertyName(), prop);
                 }
-                for (InspectorProperty prop : fieldPropertyList) {
-                    if (propertiesMap.containsKey(prop.getPropertyName())) {
+                for(InspectorProperty prop : fieldPropertyList) {
+                    if(propertiesMap.containsKey(prop.getPropertyName())) {
                         InspectorProperty existingProp = propertiesMap.get(prop.getPropertyName());
-                        if (!existingProp.hasAccessor()) {
+                        if(!existingProp.hasAccessor()) {
                             existingProp.setAccessName(prop.getAccessName());
                             existingProp.setAccessPropertyType(TYPE.FIELD);
                         }
-                        if (!existingProp.hasMutator()) {
+                        if(!existingProp.hasMutator()) {
                             existingProp.setMutateName(prop.getMutateName());
                             existingProp.setMutatePropertyType(TYPE.FIELD);
                         }
+                        if(prop.getAnnotations() != null && existingProp.getAnnotations() != null) {
+                            existingProp.getAnnotations().addAll(prop.getAnnotations());
+                        } else if(prop.getAnnotations() != null && existingProp.getAnnotations() == null) {
+                            existingProp.setAnnotations(prop.getAnnotations());
+                        }
                     } else {
                         propertiesMap.put(prop.getPropertyName(), prop);
                     }
             propertyList = getAttributeProperties(objectClass);
         }
 
-        if (propertyList == null) {
+        if(propertyList == null) {
             propertyList = new InspectorProperty[0];
         }
         properties = propertyList;
 
         // Inspect inner array (List type) and Inspect inner object (Map type)
-        Class<?>[] interfaces = null;
+        Class<?>[] interfaces;
         Class<?> parent = objectClass.getSuperclass();
-        if (parent != null) {
+        if(parent != null) {
             do {
                 interfaces = parent.getInterfaces();
-                for (int i = 0; i < Array.getLength(interfaces); i++) {
-                    if (interfaces[i] == List.class) {
+                for(int i = 0; i < Array.getLength(interfaces); i++) {
+                    if(interfaces[i] == List.class) {
                         innerArray = true;
                     }
-                    if (interfaces[i] == Map.class) {
+                    if(interfaces[i] == Map.class) {
                         innerObject = true;
                     }
-                    if (innerArray && innerObject) {
+                    if(innerArray && innerObject) {
                         break;
                     }
                 }
-                if (innerArray && innerObject) {
+                if(innerArray && innerObject) {
                     break;
                 }
-            } while (( parent = parent.getSuperclass() ) != null);
+            } while((parent = parent.getSuperclass()) != null);
         }
-
     }
 
     public InspectorProperty[] getAttributeProperties(Class<?> objectClass) {
         InspectorProperty[] result = null;
         HashMap<String, InspectorProperty> attributeProperties = new HashMap<String, InspectorProperty>();
         Field[] objectFields = objectClass.getFields();
-        for (Field field : objectFields) {
-            if (isJSONIgnored(field) || filter.isFiltered(field.getDeclaringClass())) {
+        for(Field field : objectFields) {
+            if(isJSONIgnored(field) || filter.isFiltered(field.getDeclaringClass())) {
                 continue;
             }
             InspectionData fieldInspectionData = getFieldInspectionData(field);
-            if (fieldInspectionData == null || !fieldInspectionData.hasPropertyName()) {
+            if(fieldInspectionData == null || !fieldInspectionData.hasPropertyName()) {
                 continue;
             }
             String propertyName = fieldInspectionData.getPropertyName();
             InspectorProperty property = null;
-            if (!attributeProperties.containsKey(propertyName)) {
+            if(!attributeProperties.containsKey(propertyName)) {
                 property = new InspectorProperty(propertyName, TYPE.FIELD);
                 attributeProperties.put(propertyName, property);
                 property.setPropertyName(propertyName);
                 property.setMutateName(fieldInspectionData.getName());
                 property.setAccessReturnType(fieldInspectionData.getReturnType());
                 property.setMutateInputType(fieldInspectionData.getArgumentType());
+
+                if(field.getAnnotations() != null) {
+                    property.annotations = new ArrayList<Annotation>();
+                    property.annotations.addAll(Arrays.asList(field.getAnnotations()));
+                }
             }
         }
-        if (!attributeProperties.isEmpty()) {
+        if(!attributeProperties.isEmpty()) {
             result = new InspectorProperty[attributeProperties.size()];
             attributeProperties.values().toArray(result);
         }
         InspectorProperty[] result = null;
         HashMap<String, InspectorProperty> methodProperties = new HashMap<String, InspectorProperty>();
         Method[] objectMethods = objectClass.getMethods();
-        for (Method method : objectMethods) {
-            if (isJSONIgnored(method) || filter.isFiltered(method.getDeclaringClass())) {
+        for(Method method : objectMethods) {
+            if(isJSONIgnored(method) || filter.isFiltered(method.getDeclaringClass())) {
                 continue;
             }
             InspectionData methodInspectionData = getMethodInspectionData(method);
-            if (methodInspectionData == null || !methodInspectionData.hasPropertyName()) {
+            if(methodInspectionData == null || !methodInspectionData.hasPropertyName()) {
                 continue;
             }
             String propertyName = methodInspectionData.getPropertyName();
-            InspectorProperty property = null;
-            if (methodProperties.containsKey(propertyName)) {
+            InspectorProperty property;
+            if(methodProperties.containsKey(propertyName)) {
                 property = methodProperties.get(propertyName);
             } else {
                 property = new InspectorProperty(propertyName, TYPE.METHOD);
                 methodProperties.put(propertyName, property);
             }
-            if (methodInspectionData.getAccessType() == ACCESS_TYPE.ACCESS && !property.hasAccessor()) {
+            if(methodInspectionData.getAccessType() == ACCESS_TYPE.ACCESS && !property.hasAccessor()) {
                 property.setAccessName(methodInspectionData.getName());
                 property.setAccessReturnType(methodInspectionData.getReturnType());
-            } else if (methodInspectionData.getAccessType() == ACCESS_TYPE.MUTATE && !property.hasMutator()) {
+            } else if(methodInspectionData.getAccessType() == ACCESS_TYPE.MUTATE && !property.hasMutator()) {
                 property.setMutateName(methodInspectionData.getName());
                 property.setMutateInputType(methodInspectionData.getArgumentType());
             }
+
+            if(method.getAnnotations() != null && property != null) {
+                property.annotations = new ArrayList<Annotation>();
+                property.annotations.addAll(Arrays.asList(method.getAnnotations()));
+            }
         }
-        if (!methodProperties.isEmpty()) {
+        if(!methodProperties.isEmpty()) {
             result = new InspectorProperty[methodProperties.size()];
             methodProperties.values().toArray(result);
         }
         fieldInspectionData.setName(field.getName());
         fieldInspectionData.setAccessType(ACCESS_TYPE.BOTH);
         String jsonName = Inspector.getJSONName(field);
-        if (jsonName != null) {
+        if(jsonName != null) {
             fieldInspectionData.setPropertyName(jsonName);
         }
-        if (!fieldInspectionData.hasPropertyName()) {
+        if(!fieldInspectionData.hasPropertyName()) {
             fieldInspectionData.setPropertyName(fieldInspectionData.getName());
         }
         fieldInspectionData.setArgumentType(field.getType());
         InspectionData methodInspectionData = new InspectionData();
         methodInspectionData.setName(method.getName());
         String jsonName = Inspector.getJSONName(method);
-        if (jsonName != null) {
+        if(jsonName != null) {
             methodInspectionData.setPropertyName(jsonName);
         }
-        if (!methodInspectionData.hasPropertyName()) {
+        if(!methodInspectionData.hasPropertyName()) {
             String accessorName = Inspector.getJSONAccessor(method);
-            if (accessorName != null) {
+            if(accessorName != null) {
                 methodInspectionData.setPropertyName(accessorName);
                 methodInspectionData.setAccessType(ACCESS_TYPE.ACCESS);
             }
         }
-        if (!methodInspectionData.hasPropertyName()) {
+        if(!methodInspectionData.hasPropertyName()) {
             String mutatorName = Inspector.getJSONMutator(method);
-            if (mutatorName != null) {
+            if(mutatorName != null) {
                 methodInspectionData.setPropertyName(mutatorName);
                 methodInspectionData.setAccessType(ACCESS_TYPE.MUTATE);
             }
         }
         methodInspectionData.setReturnType(method.getReturnType());
-        if (!methodInspectionData.hasPropertyName()) {
+        if(!methodInspectionData.hasPropertyName()) {
             char ch;
-            String propertyName = null;
+            String propertyName;
             String methodName = methodInspectionData.getName();
             Class<?> returnType = methodInspectionData.getReturnType();
-            if (methodName.length() > IS_PREFIX.length() && methodName.startsWith(IS_PREFIX) && returnType == boolean.class && Character.isUpperCase(ch = methodName.charAt(IS_PREFIX.length()))) {
+            if(methodName.length() > IS_PREFIX.length() && methodName.startsWith(IS_PREFIX) && returnType == boolean.class && Character.isUpperCase(ch = methodName.charAt(IS_PREFIX.length()))) {
                 propertyName = Character.toLowerCase(ch) + methodName.substring(IS_PREFIX.length() + 1, methodName.length());
                 methodInspectionData.setPropertyName(propertyName);
                 methodInspectionData.setAccessType(ACCESS_TYPE.ACCESS);
-            } else if (methodName.length() > SET_PREFIX.length() && methodName.startsWith(SET_PREFIX) && Character.isUpperCase(ch = methodName.charAt(SET_PREFIX.length()))) {
+            } else if(methodName.length() > SET_PREFIX.length() && methodName.startsWith(SET_PREFIX) && Character.isUpperCase(ch = methodName.charAt(SET_PREFIX.length()))) {
                 propertyName = Character.toLowerCase(ch) + methodName.substring(SET_PREFIX.length() + 1, methodName.length());
                 methodInspectionData.setPropertyName(propertyName);
                 methodInspectionData.setAccessType(ACCESS_TYPE.MUTATE);
-            } else if (methodName.length() > GET_PREFIX.length() && methodName.startsWith(GET_PREFIX) && Character.isUpperCase(ch = methodName.charAt(GET_PREFIX.length())) && returnType != null) {
+            } else if(methodName.length() > GET_PREFIX.length() && methodName.startsWith(GET_PREFIX) && Character.isUpperCase(ch = methodName.charAt(GET_PREFIX.length())) && returnType != null) {
                 propertyName = Character.toLowerCase(ch) + methodName.substring(GET_PREFIX.length() + 1, methodName.length());
                 methodInspectionData.setPropertyName(propertyName);
                 methodInspectionData.setAccessType(ACCESS_TYPE.ACCESS);
             }
         }
-        if (methodInspectionData.getAccessType() == ACCESS_TYPE.ACCESS) {
+        if(methodInspectionData.getAccessType() == ACCESS_TYPE.ACCESS) {
             Class<?> returnType = method.getReturnType();
-            if (returnType != null) {
+            if(returnType != null) {
                 methodInspectionData.setReturnType(returnType);
             } else {
                 return null;
             }
-        } else if (methodInspectionData.getAccessType() == ACCESS_TYPE.MUTATE) {
+        } else if(methodInspectionData.getAccessType() == ACCESS_TYPE.MUTATE) {
             Class<?>[] parameterTypes = method.getParameterTypes();
-            if (Array.getLength(parameterTypes) == 1) {
+            if(Array.getLength(parameterTypes) == 1) {
                 Class<?> parameterType = parameterTypes[0];
                 methodInspectionData.setArgumentType(parameterType);
             } else {
     }
 
     public InspectorProperty[] getProperties() {
-        if (o != null && properties == null) {
+        if(o != null && properties == null) {
             inspect();
         }
         return properties;
     }
 
+    public boolean hasCollector() {
+        for(InspectorProperty prop : properties) {
+            if(prop.getAnnotations() != null) {
+                for(Annotation annotation : prop.getAnnotations()) {
+                    if(annotation instanceof JSONCollector) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    public InspectorProperty getCollector() {
+        for(InspectorProperty prop : properties) {
+            if(prop.getAnnotations() != null) {
+                for(Annotation annotation : prop.getAnnotations()) {
+                    if(annotation instanceof JSONCollector) {
+                        return prop;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     public void setProperties(InspectorProperty[] properties) {
         this.properties = properties;
     }
 
-    public boolean isJSONIgnored(AccessibleObject object) {
+    private boolean isJSONIgnored(AccessibleObject object) {
         return object.getAnnotation(JSONIgnore.class) != null;
     }
 
-    public static String getAnnotatedName(AccessibleObject object) {
+    private static String getAnnotatedName(AccessibleObject object) {
         String name = getJSONName(object);
-        if (name == null) {
+        if(name == null) {
             name = getJSONMutator(object);
         }
-        if (name == null) {
+        if(name == null) {
             name = getJSONAccessor(object);
         }
         return name;
     }
 
-    public static String getJSONName(AccessibleObject object) {
+    private static String getJSONName(AccessibleObject object) {
         String name = null;
         JSONName jsonNameAnnotation = object.getAnnotation(JSONName.class);
-        if (jsonNameAnnotation != null) {
+        if(jsonNameAnnotation != null) {
             name = jsonNameAnnotation.value();
         }
         return name;
     }
 
-    public static String getJSONMutator(AccessibleObject object) {
+    private static String getJSONMutator(AccessibleObject object) {
         String name = null;
         JSONMutator jsonMutatorAnnotation = object.getAnnotation(JSONMutator.class);
-        if (jsonMutatorAnnotation != null) {
+        if(jsonMutatorAnnotation != null) {
             name = jsonMutatorAnnotation.value();
         }
         return name;
     }
 
-    public static String getJSONAccessor(AccessibleObject object) {
+    private static String getJSONAccessor(AccessibleObject object) {
         String name = null;
         JSONAccessor jsonAccessorAnnotation = object.getAnnotation(JSONAccessor.class);
-        if (jsonAccessorAnnotation != null) {
+        if(jsonAccessorAnnotation != null) {
             name = jsonAccessorAnnotation.value();
         }
         return name;
 
     public enum ACCESS_TYPE {
 
-        ACCESS, MUTATE, BOTH
+        ACCESS,
+        MUTATE,
+        BOTH
+
     }
 
     public static class InspectionData {
 
         protected String name;
+
         protected String propertyName;
+
         protected Class<?> returnType;
+
         protected Class<?> argumentType;
+
         protected ACCESS_TYPE accessType;
 
+        protected Annotation[] annotations;
+
         public InspectionData() {
             name = null;
             propertyName = null;
             returnType = null;
+            accessType = null;
+            annotations = null;
         }
 
         public String getName() {
         public void setAccessType(ACCESS_TYPE accessType) {
             this.accessType = accessType;
         }
+
+        public Annotation[] getAnnotations() {
+            return annotations;
+        }
+
+        public void setAnnotations(Annotation[] annotations) {
+            this.annotations = annotations;
+        }
+    }
+
+    public static boolean isMapType(Class<?> c) {
+        Class<?> currentClass = c;
+        do {
+            Class<?>[] interfaces = currentClass.getInterfaces();
+            for(Class<?> i : interfaces) {
+                if(i == Map.class) {
+                    return true;
+                }
+            }
+        } while((currentClass = currentClass.getSuperclass()) != null);
+        return false;
+    }
+
+    public static boolean isListType(Class<?> c) {
+        Class<?> currentClass = c;
+        do {
+            Class<?>[] interfaces = currentClass.getInterfaces();
+            for(Class<?> i : interfaces) {
+                if(i == List.class) {
+                    return true;
+                }
+            }
+        } while((currentClass = currentClass.getSuperclass()) != null);
+        return false;
     }
 }

src/main/java/cc/plural/jsonij/marshal/InspectorFilter.java

     protected List<Class<?>> classFilter;
 
     protected static InspectorFilter defaultFilters;
-    
+
     static {
         defaultFilters = null;
     }
-    
+
     public InspectorFilter() {
         classFilter = new ArrayList<Class<?>>();
     }
     public boolean isFiltered(Class<?> clazz) {
         return classFilter.contains(clazz);
     }
-    
+
     protected static void createDefaultInstance() {
         defaultFilters = new InspectorFilter();
-	defaultFilters.classFilter.add(java.lang.Class.class);
+        defaultFilters.classFilter.add(java.lang.Class.class);
         defaultFilters.classFilter.add(java.lang.Object.class);
         defaultFilters.classFilter.add(java.util.List.class);
         defaultFilters.classFilter.add(java.util.ArrayList.class);
         defaultFilters.classFilter.add(java.util.Map.class);
-        defaultFilters.classFilter.add(java.util.HashMap.class);	
+        defaultFilters.classFilter.add(java.util.HashMap.class);
     }
-    
+
     public static InspectorFilter getDefaultFilters() {
         if(defaultFilters == null) {
             createDefaultInstance();

src/main/java/cc/plural/jsonij/marshal/InspectorProperty.java

  */
 package cc.plural.jsonij.marshal;
 
+import java.lang.annotation.Annotation;
+import java.util.List;
+
 /**
  *
  * @author jmarsden
 public class InspectorProperty {
 
     public enum TYPE {
-        FIELD, METHOD
+
+        FIELD,
+        METHOD
+
     }
     public String propertyName;
+
     public String accessName;
+
     public String mutateName;
+
     public TYPE accessPropertyType;
+
     public TYPE mutatePropertyType;
+
     public Class<?> accessReturnType;
+
     public Class<?> mutateInputType;
 
+    public List<Annotation> annotations;
+
     public InspectorProperty() {
         propertyName = null;
         accessPropertyType = null;
         mutatePropertyType = null;
         accessName = null;
         mutateName = null;
+        annotations = null;
     }
 
     public InspectorProperty(String name, TYPE accessType) {
     }
 
     public boolean hasAccessor() {
-        return accessPropertyType == TYPE.FIELD || ( accessName != null );
+        return accessPropertyType == TYPE.FIELD || (accessName != null);
     }
 
     public boolean hasMutator() {
-        return mutatePropertyType == TYPE.FIELD || ( mutateName != null );
+        return mutatePropertyType == TYPE.FIELD || (mutateName != null);
+    }
+
+    public List<Annotation> getAnnotations() {
+        return annotations;
+    }
+
+    public void setAnnotations(List<Annotation> annotations) {
+        this.annotations = annotations;
     }
 
     @Override

src/main/java/cc/plural/jsonij/marshal/JSONDocumentMarshaler.java

  */
 package cc.plural.jsonij.marshal;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.logging.Level;
 import cc.plural.jsonij.JSON;
 import cc.plural.jsonij.Value;
 import cc.plural.jsonij.parser.ParserException;
-import java.io.IOException;
-import java.io.InputStream;
 
 /**
  *
 public class JSONDocumentMarshaler {
 
     public static String innerArrayAttribute;
+
     public static String innerObjectAttribute;
 
     static {
-	innerArrayAttribute = "_innerArray";
-	innerObjectAttribute = "_innerObject";
+        innerArrayAttribute = "_innerArray";
+        innerObjectAttribute = "_innerObject";
     }
 
     public Object marshalJSONDocument(JSON json, Class<?> objectClass) throws JSONMarshalerException {
-	Object resultObject = null;
-	Value jsonRoot = json.getRoot();
-	if (jsonRoot.type() == Value.TYPE.OBJECT) {
-	    JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) jsonRoot;
-	    resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
-	} else if (jsonRoot.type() == Value.TYPE.ARRAY) {
-	    JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) jsonRoot;
-	    resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
-	} else {
-	    //throw new Exception();
-	}
-	return resultObject;
+        Object resultObject = null;
+        Value jsonRoot = json.getRoot();
+        if(jsonRoot.type() == Value.TYPE.OBJECT) {
+            JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) jsonRoot;
+            resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
+        } else if(jsonRoot.type() == Value.TYPE.ARRAY) {
+            JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) jsonRoot;
+            resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
+        } else {
+            //throw new Exception();
+        }
+        return resultObject;
     }
 
     public Object marshalJSONDocument(Value value, Class<?> objectClass) throws JSONMarshalerException {
-	Object resultObject = null;
-	if (value.type() == Value.TYPE.OBJECT) {
-	    JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) value;
-	    resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
-	} else if (value.type() == Value.TYPE.ARRAY) {
-	    JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) value;
-	    resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
-	} else {
-	    //throw new Exception();
-	}
-	return resultObject;
+        Object resultObject = null;
+        if(value.type() == Value.TYPE.OBJECT) {
+            JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) value;
+            resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
+        } else if(value.type() == Value.TYPE.ARRAY) {
+            JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) value;
+            resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
+        } else {
+            //throw new Exception();
+        }
+        return resultObject;
     }
 
     public Object marshalJSONDocumentObject(JSON.Object<CharSequence, Value> jsonObject, Class<?> objectClass) throws JSONMarshalerException {
-	Object resultObject = null;
-
-	Set<Entry<CharSequence, Value>> entrySet = jsonObject.entrySet();
-	Iterator<Entry<CharSequence, Value>> entrySetIterator = entrySet.iterator();
-	Entry<CharSequence, Value> entry = null;
-	Inspector inspector = new Inspector(objectClass);
-	inspector.inspect();
-
-	List<MarshalerPropertyValue> marshalPropertyValues = new ArrayList<MarshalerPropertyValue>();
-	while (entrySetIterator.hasNext()) {
-	    entry = entrySetIterator.next();
-	    if (entry.getKey().toString().equals(innerObjectAttribute) && inspector.hasInnerObject()) {
-		/**
-		 * todo: handle the inner object
-		 */
-	    }
-	    String propertyName = entry.getKey().toString();
-	    if (inspector.hasProperty(propertyName)) {
-		MarshalerPropertyValue propertyValue = new MarshalerPropertyValue(propertyName, inspector.getProperty(propertyName), entry.getValue());
-		marshalPropertyValues.add(propertyValue);
-	    }
-	}
-
-
-	try {
-	    resultObject = objectClass.newInstance();
-	    for (MarshalerPropertyValue propertyValue : marshalPropertyValues) {
-		if (propertyValue.getValue().isNull()) {
-		    // TODO: Handle Null
-		}
-		InspectorProperty property = propertyValue.getProperty();
-		if (property.getAccessPropertyType() == InspectorProperty.TYPE.METHOD) {
-		    Method method = objectClass.getMethod(property.getMutateName(), property.getMutateInputType());
-		    JavaType mutateType = JavaType.inspectObjectType(property.getMutateInputType());
-
-		    JSON.Array<Value> arrayJSON = null;
-
-		    switch (mutateType) {
-			case BOOLEAN:
-			    method.invoke(resultObject, propertyValue.getValue().getBoolean());
-			    break;
-			case BYTE:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().byteValue());
-			    break;
-			case INTEGER:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().intValue());
-			    break;
-			case SHORT:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().shortValue());
-			    break;
-			case FLOAT:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().floatValue());
-			    break;
-			case LONG:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().longValue());
-			    break;
-			case DOUBLE:
-			    method.invoke(resultObject, propertyValue.getValue().getNumber().doubleValue());
-			    break;
-			case STRING:
-			    method.invoke(resultObject, propertyValue.getValue().getString());
-			    break;
-			case ENUM:
-			    method.invoke(resultObject, propertyValue.getValue().getString());
-			    break;
-			case MAP:
-
-			    break;
-			case LIST:
-
-			    break;
-			case OBJECT:
-			    JSON.Object<CharSequence, Value> objectJSON = (JSON.Object<CharSequence, Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentObject(objectJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_BYTE:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_SHORT:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_INTEGER:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_FLOAT:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_DOUBLE:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_LONG:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_STRING:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_ENUM:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_LIST:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_MAP:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			default:
-
-			    break;
-		    }
-		} else if (property.getAccessPropertyType() == InspectorProperty.TYPE.FIELD) {
-		    Field field = objectClass.getField(propertyValue.getProperty().getMutateName());
-		    JavaType mutateType = JavaType.inspectObjectType(property.getMutateInputType());
-
-		    JSON.Array<Value> arrayJSON = null;
-
-		    switch (mutateType) {
-			case BOOLEAN:
-			    field.set(resultObject, propertyValue.getValue().getBoolean());
-			    break;
-			case BYTE:
-			    field.set(resultObject, propertyValue.getValue().getNumber().byteValue());
-			    break;
-			case INTEGER:
-			    field.set(resultObject, propertyValue.getValue().getNumber().intValue());
-			    break;
-			case SHORT:
-			    field.set(resultObject, propertyValue.getValue().getNumber().shortValue());
-			    break;
-			case FLOAT:
-			    field.set(resultObject, propertyValue.getValue().getNumber().floatValue());
-			    break;
-			case LONG:
-			    field.set(resultObject, propertyValue.getValue().getNumber().longValue());
-			    break;
-			case DOUBLE:
-			    field.set(resultObject, propertyValue.getValue().getNumber().doubleValue());
-			    break;
-			case STRING:
-			    field.set(resultObject, propertyValue.getValue().getString());
-			    break;
-			case ENUM:
-
-			    break;
-			case MAP:
-
-			    break;
-			case LIST:
-
-			    break;
-			case OBJECT:
-			    JSON.Object<CharSequence, Value> objectJSON = (JSON.Object<CharSequence, Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentObject(objectJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_BYTE:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_SHORT:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_INTEGER:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_FLOAT:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_DOUBLE:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_LONG:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_STRING:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_ENUM:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_LIST:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_MAP:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			case ARRAY_ARRAY:
-			    arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
-			    field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
-			    break;
-			default:
-
-			    break;
-		    }
-		}
-
-	    }
-
-	} catch (InstantiationException ex) {
-	    Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
-	} catch (IllegalAccessException ex) {
-	    Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
-	} catch (NoSuchFieldException ex) {
-	    Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
-	} catch (NoSuchMethodException ex) {
-	    Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
-	} catch (InvocationTargetException ex) {
-	    Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
-	}
-	return resultObject;
+        Object resultObject = null;
+
+        Set<Entry<CharSequence, Value>> entrySet = jsonObject.entrySet();
+        Iterator<Entry<CharSequence, Value>> entrySetIterator = entrySet.iterator();
+        Entry<CharSequence, Value> entry = null;
+        Inspector inspector = new Inspector(objectClass);
+        inspector.inspect();
+
+        boolean hasCollector = inspector.hasCollector();
+        Map<CharSequence, Value> collectorReference = null;
+
+        List<MarshalerPropertyValue> objectPropertyValues = new ArrayList<MarshalerPropertyValue>();
+        List<MarshalerPropertyValue> collectorPropertyValues = null;
+
+        if(hasCollector) {
+            collectorPropertyValues = new ArrayList<MarshalerPropertyValue>();
+        }
+
+        while(entrySetIterator.hasNext()) {
+            entry = entrySetIterator.next();
+            if(entry.getKey().toString().equals(innerObjectAttribute) && inspector.hasInnerObject()) {
+                /**
+                 * todo: handle the inner object
+                 */
+            }
+            String propertyName = entry.getKey().toString();
+            if(inspector.hasProperty(propertyName)) {
+                MarshalerPropertyValue propertyValue = new MarshalerPropertyValue(propertyName, inspector.getProperty(propertyName), entry.getValue());
+                objectPropertyValues.add(propertyValue);
+            } else if(hasCollector) {
+                MarshalerPropertyValue propertyValue = new MarshalerPropertyValue(propertyName, inspector.getProperty(propertyName), entry.getValue());
+                collectorPropertyValues.add(propertyValue);
+            }
+        }
+
+        try {
+            resultObject = objectClass.newInstance();
+            if(hasCollector) {
+                InspectorProperty prop = inspector.getCollector();
+                if(prop.getAccessPropertyType() == InspectorProperty.TYPE.METHOD) {
+                    Method method = objectClass.getMethod(prop.getAccessName());
+                    collectorReference = (Map<CharSequence, Value>) method.invoke(resultObject);
+                } else if(prop.getAccessPropertyType() == InspectorProperty.TYPE.FIELD) {
+                    Field field = objectClass.getField(prop.getMutateName());
+                    collectorReference = (Map<CharSequence, Value>) field.get(resultObject);
+                }
+            }
+
+            for(MarshalerPropertyValue propertyValue : objectPropertyValues) {
+                if(propertyValue.getValue().isNull()) {
+                    // TODO: Handle Null
+                }
+                InspectorProperty property = propertyValue.getProperty();
+                if(property.getAccessPropertyType() == InspectorProperty.TYPE.METHOD) {
+                    Method method = objectClass.getMethod(property.getMutateName(), property.getMutateInputType());
+                    JavaType mutateType = JavaType.inspectObjectType(property.getMutateInputType());
+
+                    JSON.Array<Value> arrayJSON = null;
+
+                    switch(mutateType) {
+                        case BOOLEAN:
+                            method.invoke(resultObject, propertyValue.getValue().getBoolean());
+                            break;
+                        case BYTE:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().byteValue());
+                            break;
+                        case INTEGER:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().intValue());
+                            break;
+                        case SHORT:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().shortValue());
+                            break;
+                        case FLOAT:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().floatValue());
+                            break;
+                        case LONG:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().longValue());
+                            break;
+                        case DOUBLE:
+                            method.invoke(resultObject, propertyValue.getValue().getNumber().doubleValue());
+                            break;
+                        case STRING:
+                            method.invoke(resultObject, propertyValue.getValue().getString());
+                            break;
+                        case ENUM:
+                            method.invoke(resultObject, propertyValue.getValue().getString());
+                            break;
+                        case MAP:
+
+                            break;
+                        case LIST:
+
+                            break;
+                        case OBJECT:
+                            JSON.Object<CharSequence, Value> objectJSON = (JSON.Object<CharSequence, Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentObject(objectJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_BYTE:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_SHORT:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_INTEGER:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_FLOAT:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_DOUBLE:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_LONG:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_STRING:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_ENUM:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_LIST:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_MAP:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            method.invoke(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        default:
+
+                            break;
+                    }
+                } else if(property.getAccessPropertyType() == InspectorProperty.TYPE.FIELD) {
+                    Field field = objectClass.getField(propertyValue.getProperty().getMutateName());
+                    JavaType mutateType = JavaType.inspectObjectType(property.getMutateInputType());
+
+                    JSON.Array<Value> arrayJSON = null;
+
+                    switch(mutateType) {
+                        case BOOLEAN:
+                            field.set(resultObject, propertyValue.getValue().getBoolean());
+                            break;
+                        case BYTE:
+                            field.set(resultObject, propertyValue.getValue().getNumber().byteValue());
+                            break;
+                        case INTEGER:
+                            field.set(resultObject, propertyValue.getValue().getNumber().intValue());
+                            break;
+                        case SHORT:
+                            field.set(resultObject, propertyValue.getValue().getNumber().shortValue());
+                            break;
+                        case FLOAT:
+                            field.set(resultObject, propertyValue.getValue().getNumber().floatValue());
+                            break;
+                        case LONG:
+                            field.set(resultObject, propertyValue.getValue().getNumber().longValue());
+                            break;
+                        case DOUBLE:
+                            field.set(resultObject, propertyValue.getValue().getNumber().doubleValue());
+                            break;
+                        case STRING:
+                            field.set(resultObject, propertyValue.getValue().getString());
+                            break;
+                        case ENUM:
+
+                            break;
+                        case MAP:
+
+                            break;
+                        case LIST:
+
+                            break;
+                        case OBJECT:
+                            JSON.Object<CharSequence, Value> objectJSON = (JSON.Object<CharSequence, Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentObject(objectJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_BYTE:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_SHORT:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_INTEGER:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_FLOAT:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_DOUBLE:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_LONG:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_STRING:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_ENUM:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_LIST:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_MAP:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        case ARRAY_ARRAY:
+                            arrayJSON = (JSON.Array<Value>) propertyValue.getValue();
+                            field.set(resultObject, marshalJSONDocumentArray(arrayJSON, property.getMutateInputType()));
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+            if(hasCollector) {
+                for(MarshalerPropertyValue propertyValue : collectorPropertyValues) {
+                    collectorReference.put(propertyValue.getName(), propertyValue.getValue());
+                }
+            }
+        } catch(InstantiationException ex) {
+            Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
+        } catch(IllegalAccessException ex) {
+            Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
+        } catch(NoSuchFieldException ex) {
+            Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
+        } catch(NoSuchMethodException ex) {
+            Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
+        } catch(InvocationTargetException ex) {
+            Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return resultObject;
     }
 
     public Object marshalJSONDocument(InputStream stream, Class<?> objectClass) throws JSONMarshalerException {
-	JSON json;
-	try {
-	    json = JSON.parse(stream);
-
-	} catch (ParserException ex) {
-	    throw new JSONMarshalerException("", ex);
-	} catch (IOException ex) {
-	    throw new JSONMarshalerException("", ex);
-	}
-	return marshalJSONDocument(json, objectClass);
+        JSON json;
+        try {
+            json = JSON.parse(stream);
+
+        } catch(ParserException ex) {
+            throw new JSONMarshalerException("", ex);
+        } catch(IOException ex) {
+            throw new JSONMarshalerException("", ex);
+        }
+        return marshalJSONDocument(json, objectClass);
     }
 
     public Object marshalJSONDocument(String jsonString, Class<?> objectClass) throws JSONMarshalerException {
-	JSON json;
-	try {
-	    json = JSON.parse(jsonString);
-
-	} catch (ParserException ex) {
-	    throw new JSONMarshalerException("", ex);
-	} catch (IOException ex) {
-	    throw new JSONMarshalerException("", ex);
-	}
-	return marshalJSONDocument(json, objectClass);
+        JSON json;
+        try {
+            json = JSON.parse(jsonString);
+
+        } catch(ParserException ex) {
+            throw new JSONMarshalerException("", ex);
+        } catch(IOException ex) {
+            throw new JSONMarshalerException("", ex);
+        }
+        return marshalJSONDocument(json, objectClass);
     }
 
     /*
      * return null; }
      */
     public Object marshalJSONDocumentArray(JSON.Array<Value> jsonArray, Class<?> objectClass) throws JSONMarshalerException {
-	int size = jsonArray.size();
-	Class<?> componentClass = objectClass.getComponentType();
-	Object array = Array.newInstance(componentClass, size);
-	for (int i = 0; i < size; i++) {
-	    Value value =  jsonArray.get(i);
-	    if(value.getValueType() == Value.TYPE.OBJECT) {
-		Array.set(array, i, marshalJSONDocumentObject((JSON.Object<CharSequence, Value>) value, componentClass));
-	    } else if(value.getValueType() == Value.TYPE.ARRAY) {
-		Array.set(array, i, marshalJSONDocumentArray((JSON.Array<Value>) value, componentClass));
-	    } else if (componentClass.equals(int.class)) {
-		Array.set(array, i, jsonArray.get(i).getNumber().intValue());
-	    } else if (componentClass.equals(float.class)) {
-		Array.set(array, i, jsonArray.get(i).getNumber().floatValue());
-	    } else if (componentClass.equals(double.class)) {
-		Array.set(array, i, jsonArray.get(i).getNumber().doubleValue());
-	    } else if (componentClass.equals(byte.class)) {
-		Array.set(array, i, jsonArray.get(i).getNumber().byteValue());
-	    } else if (componentClass.equals(boolean.class)) {
-		Array.set(array, i, jsonArray.get(i).getBoolean());
-	    } else if (componentClass.equals(String.class)) {
-		Array.set(array, i, jsonArray.get(i).getString());
-	    } else {
-		//
-	    }
-	}
-	return array;
+        int size = jsonArray.size();
+        Class<?> componentClass = objectClass.getComponentType();
+        Object array = Array.newInstance(componentClass, size);
+        for(int i = 0; i < size; i++) {
+            Value value = jsonArray.get(i);
+            if(value.getValueType() == Value.TYPE.OBJECT) {
+                Array.set(array, i, marshalJSONDocumentObject((JSON.Object<CharSequence, Value>) value, componentClass));
+            } else if(value.getValueType() == Value.TYPE.ARRAY) {
+                Array.set(array, i, marshalJSONDocumentArray((JSON.Array<Value>) value, componentClass));
+            } else if(componentClass.equals(int.class)) {
+                Array.set(array, i, jsonArray.get(i).getNumber().intValue());
+            } else if(componentClass.equals(float.class)) {
+                Array.set(array, i, jsonArray.get(i).getNumber().floatValue());
+            } else if(componentClass.equals(double.class)) {
+                Array.set(array, i, jsonArray.get(i).getNumber().doubleValue());
+            } else if(componentClass.equals(byte.class)) {
+                Array.set(array, i, jsonArray.get(i).getNumber().byteValue());
+            } else if(componentClass.equals(boolean.class)) {
+                Array.set(array, i, jsonArray.get(i).getBoolean());
+            } else if(componentClass.equals(String.class)) {
+                Array.set(array, i, jsonArray.get(i).getString());
+            } else {
+                //
+            }
+        }
+        return array;
     }
 
     /*
      */
     public static class MarshalerPropertyValue {
 
-	String name;
-	InspectorProperty property;
-	Value value;
-
-	public MarshalerPropertyValue() {
-	    this.name = null;
-	    this.property = null;
-	    this.value = null;
-	}
-
-	public MarshalerPropertyValue(String name, InspectorProperty property, Value value) {
-	    this.name = name;
-	    this.property = property;
-	    this.value = value;
-	}
-
-	public String getName() {
-	    return name;
-	}
-
-	public void setName(String name) {
-	    this.name = name;
-	}
-
-	public InspectorProperty getProperty() {
-	    return property;
-	}
-
-	public void setProperty(InspectorProperty property) {
-	    this.property = property;
-	}
-
-	public Value getValue() {
-	    return value;
-	}
-
-	public void setValue(Value value) {
-	    this.value = value;
-	}
-
-	@Override
-	public String toString() {
-	    StringBuilder resultBuilder = new StringBuilder();
-	    resultBuilder.append("MarshalerPropertyValue [Name:").append(name).append('|');
-	    resultBuilder.append("Property:").append(property);
-	    resultBuilder.append("->");
-	    resultBuilder.append("Value:").append(value).append(']');
-	    return resultBuilder.toString();
-	}
+        String name;
+
+        InspectorProperty property;
+
+        Value value;
+
+        public MarshalerPropertyValue() {
+            this.name = null;
+            this.property = null;
+            this.value = null;
+        }
+
+        public MarshalerPropertyValue(String name, InspectorProperty property, Value value) {
+            this.name = name;
+            this.property = property;
+            this.value = value;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public InspectorProperty getProperty() {
+            return property;
+        }
+
+        public void setProperty(InspectorProperty property) {
+            this.property = property;
+        }
+
+        public Value getValue() {
+            return value;
+        }
+
+        public void setValue(Value value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder resultBuilder = new StringBuilder();
+            resultBuilder.append("MarshalerPropertyValue [Name:").append(name).append('|');
+            resultBuilder.append("Property:").append(property);
+            resultBuilder.append("->");
+            resultBuilder.append("Value:").append(value).append(']');
+            return resultBuilder.toString();
+        }
     }
 }

src/main/java/cc/plural/jsonij/marshal/JSONMarshalerException.java

  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package cc.plural.jsonij.marshal;
 
 import java.util.Locale;
 public class JSONMarshalerException extends ParserException {
 
     /**
-	 * Serial UID
-	 */
-	private static final long serialVersionUID = 5425872045048502973L;
-	
-	public static final String MESSAGE_BUNDLE = "MarshalerMessageBundle";
+     * Serial UID
+     */
+    private static final long serialVersionUID = 5425872045048502973L;
+
+    public static final String MESSAGE_BUNDLE = "MarshalerMessageBundle";
 
     /**
      * Basic Constructor.
      *
-     * @param key Exception key
+     * @param key  Exception key
      * @param args Additional Arguments for Exception
      */
     public JSONMarshalerException(String key, Object... args) {
     /**
      * Constructor Including Line Number and Position Number of Exception
      *
-     * @param key Exception Key
-     * @param line Exception Line
+     * @param key      Exception Key
+     * @param line     Exception Line
      * @param position Exception Position
-     * @param args Additional Arguments for Exception
+     * @param args     Additional Arguments for Exception
      */
     public JSONMarshalerException(String key, int line, int position, Object... args) {
         super(key, line, position, null, args);
     /**
      * Constructor Including Line Number, Position Number and Locale of Exception.
      *
-     * @param key Exception Key
-     * @param line Exception Line
+     * @param key      Exception Key
+     * @param line     Exception Line
      * @param position Exception Position
-     * @param locale Valid Locale for the exception
-     * @param args Additional Arguments for Exception
+     * @param locale   Valid Locale for the exception
+     * @param args     Additional Arguments for Exception
      */
     public JSONMarshalerException(String key, int line, int position, Locale locale, Object... args) {
         super(key, line, position, locale, args);

src/main/java/cc/plural/jsonij/marshal/JavaMarshaler.java

  * @author jmarsden
  */
 public class JavaMarshaler {
-    
+
     JavaObjectMarshaler javaObjectMarshaler;
 
     public JavaMarshaler() {
 
     public Value marshalObject(boolean[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Boolean> marshaledArray = new JSON.Array<JSON.Boolean>();
-        for (int i = 0; i < size; i++) {
-            if (a[i]) {
+        for(int i = 0; i < size; i++) {
+            if(a[i]) {
                 marshaledArray.add(JSON.TRUE);
             } else {
                 marshaledArray.add(JSON.FALSE);
 
     public Value marshalObject(Boolean[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Boolean> marshaledArray = new JSON.Array<JSON.Boolean>();
-        for (int i = 0; i < size; i++) {
-            if (a[i]) {
+        for(int i = 0; i < size; i++) {
+            if(a[i]) {
                 marshaledArray.add(JSON.TRUE);
             } else {
                 marshaledArray.add(JSON.FALSE);
 
     public Value marshalObject(int[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Integer[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(char[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.String> marshaledArray = new JSON.Array<JSON.String>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.String("" + a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Character[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.String> marshaledArray = new JSON.Array<JSON.String>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.String("" + a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(double[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Double[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(float[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Float[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(short[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Short[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(long[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Long[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.Numeric> marshaledArray = new JSON.Array<JSON.Numeric>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.Numeric(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(String[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         JSON.Array<JSON.String> marshaledArray = new JSON.Array<JSON.String>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             marshaledArray.add(new JSON.String(a[i]));
         }
         return marshaledArray;
 
     public Value marshalObject(Object[] a) {
         int size = 0;
-        if (( size = Array.getLength(a) ) == 0) {
+        if((size = Array.getLength(a)) == 0) {
             return new JSON.Array<JSON.Numeric>();
         }
         CycleDetector cycleDetector = new CycleDetector();
         JSON.Array<Value> marshaledArray = new JSON.Array<Value>();
-        for (int i = 0; i < size; i++) {
+        for(int i = 0; i < size; i++) {
             Value marshaledObject = marshalJavaObject(a[i], cycleDetector);
             if(marshaledObject != null) {
                 marshaledArray.add(marshaledObject);
         Value marshaledObject = null;
         Class<?> objectClass = o.getClass();
         JavaType objectType = JavaType.inspectObjectType(objectClass);
-        switch (objectType) {
+        switch(objectType) {
             case BOOLEAN:
                 marshaledObject = marshalJavaBoolean(o);
                 break;
     protected Value marshalJavaBoolean(Object o) {
         Value value = null;
         boolean marshaledBoolean = (Boolean) o;
-        if (marshaledBoolean) {
+        if(marshaledBoolean) {
             value = JSON.TRUE;
         } else {
             value = JSON.FALSE;
         Value value = null;
         Number marshaledNumber = null;
         marshaledNumber = (Number) o;
-        if (marshaledNumber != null) {
+        if(marshaledNumber != null) {
             value = new JSON.Numeric(marshaledNumber);
         } else {
             value = JSON.NULL;
 
     protected Value marshalJavaEnum(Object o) {
         Value value = null;
-        if (o != null) {
+        if(o != null) {
             String marshaledEnumeration = o.toString();
             value = new JSON.String(marshaledEnumeration);
         } else {
     protected Value marshalJavaString(Object o) {
         Value value = null;
         String marshaledString = (String) o;
-        if (marshaledString != null) {
+        if(marshaledString != null) {
             value = new JSON.String(marshaledString);
         } else {
             value = JSON.NULL;
 
     protected Value marshalJavaArray(Object o, CycleDetector cycleDetector) {
         Value value = null;
-        if (o != null) {
+        if(o != null) {
             JSON.Array<Value> marshaledArray = new JSON.Array<Value>();
             int size = Array.getLength(o);
             Class<?> type = o.getClass();
             Class<?> componentType = type.getComponentType();
-            if (componentType == int.class || componentType == Integer.class) {
-                for (int i = 0; i < size; i++) {
+            if(componentType == int.class || componentType == Integer.class) {
+                for(int i = 0; i < size; i++) {
                     marshaledArray.add(new JSON.Numeric(Array.getInt(o, i)));
                 }
-            } else if (componentType == double.class || componentType == Double.class) {
-                for (int i = 0; i < size; i++) {