diff --git a/src/org/atriasoft/ejson/JsonMapper.java__ b/src/org/atriasoft/ejson/JsonMapper.java similarity index 92% rename from src/org/atriasoft/ejson/JsonMapper.java__ rename to src/org/atriasoft/ejson/JsonMapper.java index 4036c01..2a5aa52 100644 --- a/src/org/atriasoft/ejson/JsonMapper.java__ +++ b/src/org/atriasoft/ejson/JsonMapper.java @@ -8,12 +8,12 @@ import java.nio.file.Path; import org.atriasoft.aknot.exception.AknotException; import org.atriasoft.aknot.model.ModelType; -import org.atriasoft.aknot.pojo.IntrospectionObject; -import org.atriasoft.ejson.builder.BuilderGeneric; +import org.atriasoft.ejson.builder.Builder; import org.atriasoft.ejson.builder.BuilderIntrospection; -import org.atriasoft.ejson.exception.EjsonBuilderException; +import org.atriasoft.ejson.builder.IntrospectionObject; import org.atriasoft.ejson.exception.EjsonException; import org.atriasoft.ejson.exception.EjsonNodeDoesNotExist; +import org.atriasoft.ejson.internal.Log; import org.atriasoft.ejson.parser.ParseJson; import org.atriasoft.ejson.parser.ParsingProperty; import org.atriasoft.etk.Uri; @@ -29,6 +29,7 @@ public class JsonMapper { } + /* public void generate(final Object root, final StringBuilder data) throws EjsonException, AknotException { GeneratorIntrospection generator; try { @@ -41,7 +42,7 @@ public class JsonMapper { e.printStackTrace(); } } - + */ /** * Parse a single root node that have the name of the Class Parsed: *
@@ -56,7 +57,7 @@ public class JsonMapper {
 	 */
 	@SuppressWarnings("unchecked")
 	public  T parse(final String data, final Class classType) throws EjsonException, EjsonNodeDoesNotExist, AknotException {
-		BuilderGeneric builder;
+		Builder builder;
 		try {
 			builder = new BuilderIntrospection(ModelType.NORMAL, classType);
 			final ParseJson parser = new ParseJson(builder);
@@ -64,9 +65,10 @@ public class JsonMapper {
 			property.setDisplayError(true);
 			
 			final IntrospectionObject introspectionObject = (IntrospectionObject) parser.parse(data, property);
-			introspectionObject.generateTheObject();
+			introspectionObject.generateTheObject(true);
 			final Object listRet = introspectionObject.getData();
-			if (listRet != null && !listRet.getClass().isArray() && listRet.getClass().componentType() == classType) {
+			Log.error("elements: {} , {}", listRet.getClass(), classType);
+			if (listRet != null && !listRet.getClass().isArray() && listRet.getClass() == classType) {
 				return (T) listRet;
 			} else if (listRet != null && listRet.getClass().isArray() && listRet.getClass().componentType() == classType) {
 				final T[] tmp = (T[]) listRet;
@@ -101,7 +103,7 @@ public class JsonMapper {
 		final String content = new String(elemData);
 		return parse(content, classType);
 	}
-	
+	/*
 	public void store(final Object root, final Path path) throws EjsonException, AknotException, IOException {
 		final StringBuilder builder = new StringBuilder();
 		generate(root, builder);
@@ -113,5 +115,5 @@ public class JsonMapper {
 		generate(root, builder);
 		Uri.writeAll(uri, builder.toString());
 	}
-	
+	*/
 }
diff --git a/src/org/atriasoft/ejson/builder/Builder.java b/src/org/atriasoft/ejson/builder/Builder.java
index 55b61d0..64199d2 100644
--- a/src/org/atriasoft/ejson/builder/Builder.java
+++ b/src/org/atriasoft/ejson/builder/Builder.java
@@ -5,7 +5,10 @@
  */
 package org.atriasoft.ejson.builder;
 
+import org.atriasoft.aknot.exception.AknotException;
 import org.atriasoft.ejson.exception.EjsonBuilderException;
+import org.atriasoft.ejson.exception.EjsonException;
+import org.atriasoft.ejson.exception.EjsonNodeDoesNotExist;
 
 public interface Builder {
 	
@@ -13,8 +16,9 @@ public interface Builder {
 	 * End of parsing element
 	 * @param parent Element representing the end of declaration
 	 * @throws EjsonBuilderException Error with this node or element.
+	 * @throws AknotException
 	 */
-	void endParsing(Object parent) throws EjsonBuilderException;
+	void endParsing(Object parent) throws EjsonBuilderException, AknotException;
 	
 	/**
 	 * New comment added on this Element (For an Array)
@@ -30,8 +34,12 @@ public interface Builder {
 	 * @param nodeName name of the element where the node is added
 	 * @return Declaration object value
 	 * @throws EjsonBuilderException Error with this node or element.
+	 * @throws AknotException
+	 * @throws EjsonNodeDoesNotExist
 	 */
-	Object newArray(Object parent, String nodeName) throws EjsonBuilderException;
+	Object newArray(Object parent, String nodeName) throws EjsonBuilderException, AknotException, EjsonNodeDoesNotExist;
+	
+	void newArrayFinished(Object parent, String string, Object obj) throws EjsonException, AknotException;
 	
 	/**
 	 * Add a property on the Element. (For an Array)
@@ -40,7 +48,7 @@ public interface Builder {
 	 * @param propertyValue Value of the property
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newBoolean(Object parent, boolean value) throws EjsonBuilderException, Exception;
+	void newBoolean(Object parent, boolean value) throws EjsonException, AknotException;
 	
 	/**
 	 * Add a property on the Element. (For an Object)
@@ -48,14 +56,14 @@ public interface Builder {
 	 * @param nodeName name of the element where the node is added
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newBoolean(Object parent, String nodeName, boolean value) throws EjsonBuilderException, Exception;
+	void newBoolean(Object parent, String nodeName, boolean value) throws EjsonException, AknotException;
 	
 	/**
 	 * New null element detected on the current node (For an Array)
 	 * @param parent Parent representing the node of the null is set
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNull(Object parent) throws EjsonBuilderException, Exception;
+	void newNull(Object parent) throws EjsonException, AknotException;
 	
 	/**
 	 * New null element detected on the current node (For an Object)
@@ -63,7 +71,7 @@ public interface Builder {
 	 * @param nodeName name of the element where the node is added
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNull(Object parent, String nodeName) throws EjsonBuilderException, Exception;
+	void newNull(Object parent, String nodeName) throws EjsonException, AknotException;
 	
 	/**
 	 * New number xxx.yyy element detected on the current node (For an Array)
@@ -71,7 +79,7 @@ public interface Builder {
 	 * @param value Double value of the number
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNumber(Object parent, double value) throws EjsonBuilderException, Exception;
+	void newNumber(Object parent, double value) throws EjsonException, AknotException;
 	
 	/**
 	 * New number xxx element detected on the current node (For an Array)
@@ -79,7 +87,7 @@ public interface Builder {
 	 * @param value Long value of the number
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNumber(Object parent, long value) throws EjsonBuilderException, Exception;
+	void newNumber(Object parent, long value) throws EjsonException, AknotException;
 	
 	/**
 	 * New number xxx.yyy element detected on the current node (For an Object)
@@ -88,7 +96,7 @@ public interface Builder {
 	 * @param value Double value of the number
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNumber(Object parent, String nodeName, double value) throws EjsonBuilderException, Exception;
+	void newNumber(Object parent, String nodeName, double value) throws EjsonException, AknotException;
 	
 	/**
 	 * New number xxx element detected on the current node (For an Object)
@@ -97,7 +105,7 @@ public interface Builder {
 	 * @param value Long value of the number
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newNumber(Object parent, String nodeName, long value) throws EjsonBuilderException, Exception;
+	void newNumber(Object parent, String nodeName, long value) throws EjsonException, AknotException;
 	
 	/**
 	 * Add a new sub-element on the current parent element (For an Array)
@@ -105,7 +113,7 @@ public interface Builder {
 	 * @return the object representing the Element.
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	Object newObject(Object parent) throws EjsonBuilderException, Exception;
+	Object newObject(Object parent) throws EjsonException, AknotException;
 	
 	/**
 	 * Add a new sub-element on the current parent element (For an Object)
@@ -114,14 +122,14 @@ public interface Builder {
 	 * @return the object representing the Element.
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	Object newObject(Object parent, String nodeName) throws EjsonBuilderException, Exception;
+	Object newObject(Object parent, String nodeName) throws EjsonException, AknotException;
 	
 	/**
 	 * Create or get the root element of the document
 	 * @return An object that id a root element.
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	Object newRoot() throws EjsonBuilderException;
+	Object newRoot() throws EjsonBuilderException, AknotException;
 	
 	/**
 	 * Add a new sub-element on the current parent element (For an Array)
@@ -130,7 +138,7 @@ public interface Builder {
 	 * @return the object representing the Element.
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newString(Object parent, String value) throws EjsonBuilderException, Exception;
+	void newString(Object parent, String value) throws EjsonException, AknotException;
 	
 	/**
 	 * Add a new sub-element on the current parent element (For an Object)
@@ -140,5 +148,5 @@ public interface Builder {
 	 * @return the object representing the Element.
 	 * @throws EjsonBuilderException Error with this node or element.
 	 */
-	void newString(Object parent, String nodeName, String value) throws EjsonBuilderException, Exception;
+	void newString(Object parent, String nodeName, String value) throws EjsonException, AknotException;
 }
diff --git a/src/org/atriasoft/ejson/builder/BuilderGeneric.java b/src/org/atriasoft/ejson/builder/BuilderGeneric.java
index c30f61d..65aaca0 100644
--- a/src/org/atriasoft/ejson/builder/BuilderGeneric.java
+++ b/src/org/atriasoft/ejson/builder/BuilderGeneric.java
@@ -5,7 +5,9 @@
  */
 package org.atriasoft.ejson.builder;
 
+import org.atriasoft.aknot.exception.AknotException;
 import org.atriasoft.ejson.exception.EjsonBuilderException;
+import org.atriasoft.ejson.exception.EjsonException;
 import org.atriasoft.ejson.model.JsonArray;
 import org.atriasoft.ejson.model.JsonBoolean;
 import org.atriasoft.ejson.model.JsonNull;
@@ -41,7 +43,13 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newBoolean(final Object parent, final boolean value) throws EjsonBuilderException, Exception {
+	public void newArrayFinished(final Object parent, final String string, final Object obj) throws EjsonException, AknotException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	public void newBoolean(final Object parent, final boolean value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonBoolean out = new JsonBoolean(value);
 			elem.add(out);
@@ -52,7 +60,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonBuilderException, Exception {
+	public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonBoolean out = new JsonBoolean(value);
 			elem.put(nodeName, out);
@@ -62,7 +70,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNull(final Object parent) throws EjsonBuilderException, Exception {
+	public void newNull(final Object parent) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonNull out = new JsonNull();
 			elem.add(out);
@@ -73,7 +81,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNull(final Object parent, final String nodeName) throws EjsonBuilderException, Exception {
+	public void newNull(final Object parent, final String nodeName) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonNull out = new JsonNull();
 			elem.put(nodeName, out);
@@ -83,7 +91,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNumber(final Object parent, final double value) throws EjsonBuilderException, Exception {
+	public void newNumber(final Object parent, final double value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonNumber out = new JsonNumber(value);
 			elem.add(out);
@@ -94,7 +102,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNumber(final Object parent, final long value) throws EjsonBuilderException, Exception {
+	public void newNumber(final Object parent, final long value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonNumber out = new JsonNumber(value);
 			elem.add(out);
@@ -105,7 +113,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonBuilderException, Exception {
+	public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonNumber out = new JsonNumber(value);
 			elem.put(nodeName, out);
@@ -115,7 +123,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonBuilderException, Exception {
+	public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonNumber out = new JsonNumber(value);
 			elem.put(nodeName, out);
@@ -125,7 +133,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public Object newObject(final Object parent) throws EjsonBuilderException, Exception {
+	public Object newObject(final Object parent) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonObject out = new JsonObject();
 			elem.add(out);
@@ -135,7 +143,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public Object newObject(final Object parent, final String nodeName) throws EjsonBuilderException, Exception {
+	public Object newObject(final Object parent, final String nodeName) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonObject out = new JsonObject();
 			elem.put(nodeName, out);
@@ -150,7 +158,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newString(final Object parent, final String value) throws EjsonBuilderException, Exception {
+	public void newString(final Object parent, final String value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonArray elem) {
 			final JsonString out = new JsonString(value);
 			elem.add(out);
@@ -161,7 +169,7 @@ public class BuilderGeneric implements Builder {
 	}
 	
 	@Override
-	public void newString(final Object parent, final String nodeName, final String value) throws EjsonBuilderException, Exception {
+	public void newString(final Object parent, final String nodeName, final String value) throws EjsonException, AknotException {
 		if (parent instanceof final JsonObject elem) {
 			final JsonString out = new JsonString(value);
 			elem.put(nodeName, out);
diff --git a/src/org/atriasoft/ejson/builder/BuilderIntrospection.java b/src/org/atriasoft/ejson/builder/BuilderIntrospection.java
index 19b9415..91ff880 100644
--- a/src/org/atriasoft/ejson/builder/BuilderIntrospection.java
+++ b/src/org/atriasoft/ejson/builder/BuilderIntrospection.java
@@ -5,18 +5,18 @@
  */
 package org.atriasoft.ejson.builder;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.atriasoft.aknot.StringSerializer;
 import org.atriasoft.aknot.exception.AknotException;
 import org.atriasoft.aknot.model.IntrospectionModel;
 import org.atriasoft.aknot.model.ModelType;
 import org.atriasoft.aknot.pojo.CacheIntrospectionModel;
 import org.atriasoft.ejson.exception.EjsonBuilderException;
 import org.atriasoft.ejson.exception.EjsonException;
-import org.atriasoft.ejson.model.JsonArray;
-import org.atriasoft.ejson.model.JsonBoolean;
-import org.atriasoft.ejson.model.JsonNull;
-import org.atriasoft.ejson.model.JsonNumber;
-import org.atriasoft.ejson.model.JsonObject;
-import org.atriasoft.ejson.model.JsonString;
+import org.atriasoft.ejson.exception.EjsonNodeDoesNotExist;
+import org.atriasoft.ejson.internal.Log;
 
 public class BuilderIntrospection implements Builder {
 	// Keep  in cach all the object alredy parsed ==> optimize CPU
@@ -32,158 +32,477 @@ public class BuilderIntrospection implements Builder {
 	}
 	
 	@Override
-	public void endParsing(final Object parent) throws EjsonBuilderException {
-		// nothing to do ... this is for revert build.
+	public void endParsing(final Object element) throws EjsonBuilderException, AknotException {
+		Log.verbose("End of Element: {}", element);
+		if (element == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) element;
+		if (introspectionObject.getModelIntrospection() == null) {
+			// property on nothing ???
+			return;
+		}
+		introspectionObject.generateTheObject(true);
 	}
 	
 	@Override
 	public Object newArray(final Object parent) throws EjsonBuilderException {
+		throw new EjsonBuilderException("Must be implemented ...");
+		/*
 		if (parent instanceof final JsonArray elem) {
 			final JsonArray out = new JsonArray();
 			elem.add(out);
 			return out;
 		}
 		throw new EjsonBuilderException("can not add Comment on something else than array");
+		*/
 	}
 	
 	@Override
-	public Object newArray(final Object parent, final String nodeName) throws EjsonBuilderException {
-		if (parent instanceof final JsonObject elem) {
-			final JsonArray out = new JsonArray();
-			elem.put(nodeName, out);
-			return out;
+	public Object newArray(final Object parent, final String nodeName) throws EjsonBuilderException, AknotException, EjsonNodeDoesNotExist {
+		if (parent == null) {
+			return null;
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
+		Log.verbose("new element on NodeName=" + nodeName);
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		Class typeClass = null;
+		String listTreeName = null;
+		if (!introspectionObject.isSubNodeOrPropertyExist(nodeName) && model.isIgnoreUnknown()) {
+			Log.debug("Ignore array: '" + nodeName + "', it does not exist.");
+			return null;
+		}
+		try {
+			typeClass = introspectionObject.getTypeOfSubNode(nodeName, true);
+		} catch (final AknotException e) {
+			throw new EjsonNodeDoesNotExist("Fait to get type of node " + nodeName + " does not exist: " + e.getMessage());
+		}
+		try {
+			listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName, true);
+		} catch (final AknotException e) {
+			throw new EjsonNodeDoesNotExist("Node does not exist: " + e.getMessage());
+		}
+		if (typeClass != null) {
+			// specific case for List ==> need to get the subType in introspection ...
+			if (typeClass.isArray()) {
+				final Class subTypeClass = typeClass.getComponentType();
+				Log.verbose("Create array new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+				IntrospectionModel inferData = null;
+				inferData = this.cacheModel.findOrCreate(ModelType.LIST, listTreeName, subTypeClass);
+				// Create the data when object is ended created...
+				return new IntrospectionObject(inferData);
+			}
+			if (List.class.isAssignableFrom(typeClass)) {
+				Class subTypeClass = null;
+				try {
+					subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName);
+				} catch (final AknotException e) {
+					throw new EjsonBuilderException("Node does not exist: " + e.getMessage());
+				}
+				Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+				IntrospectionModel inferData = null;
+				inferData = this.cacheModel.findOrCreate(ModelType.LIST, listTreeName, subTypeClass);
+				// Create the data when object is ended created...
+				return new IntrospectionObject(inferData);
+			}
+			Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+			final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, typeClass);
+			// Create the data when object is ended created...
+			return new IntrospectionObject(inferData);
+		}
+		return null;
 	}
 	
 	@Override
-	public void newBoolean(final Object parent, final boolean value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonBoolean out = new JsonBoolean(value);
-			elem.add(out);
+	public void newArrayFinished(final Object parent, String tmpName, final Object element) throws EjsonException, AknotException {
+		Log.error("New element fionished : ==> " + tmpName);
+		if (parent == null || element == null) {
 			return;
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
+		final IntrospectionObject introspectionElementObject = (IntrospectionObject) element;
+		if (introspectionElementObject.getModelIntrospection() == null) {
+			// property on nothing ???
+			return;
+		}
+		final IntrospectionObject introspectionParentObject = (IntrospectionObject) parent;
+		if (introspectionParentObject.getModelIntrospection() == null) {
+			if (tmpName.equals(this.rootNodeName)) {
+				// this is the root node ...
+				final Object tmpp = introspectionParentObject.getData();
+				if (tmpp instanceof List) {
+					@SuppressWarnings("unchecked")
+					final List elementsOut = (List) tmpp;
+					elementsOut.add(introspectionElementObject.getData());
+				}
+			}
+			return;
+		}
+		if (tmpName == null) {
+			tmpName = introspectionElementObject.getModelIntrospection().getTokenBasicList();
+		}
+		introspectionParentObject.addObject(tmpName, introspectionElementObject.getData());
+	}
+	
+	@Override
+	public void newBoolean(final Object parent, final boolean value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (!model.isArray() && !model.isList()) {
+			throw new EjsonBuilderException("Add element on other than an array: ");
+		}
+		introspectionObject.addData(value);
+	}
+	
+	@Override
+	public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Try inject number(long) in an ARRAY/List data= '" + value + "'");
+		}
+		/*
+		Class typeClass = model.getClassType();
+		if (! typeClass.isPrimitive()) {
+			throw new EjsonBuilderException("Try inject number(long) in an " + typeClass.getCanonicalName() + " data= '" + value + "'");
+		}
+		*/
+		introspectionObject.addObject(nodeName, value);
+	}
+	
+	@Override
+	public void newNull(final Object parent) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (!model.isArray() && !model.isList()) {
+			throw new EjsonBuilderException("Add element on other than an array: ");
+		}
+		introspectionObject.addData(null);
+	}
+	
+	@Override
+	public void newNull(final Object parent, final String nodeName) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Try inject number(long) in an ARRAY/List data");
+		}
+		/*
+		Class typeClass = model.getClassType();
+		if (! typeClass.isPrimitive()) {
+			throw new EjsonBuilderException("Try inject number(long) in an " + typeClass.getCanonicalName() + " data= '" + value + "'");
+		}
+		*/
+		introspectionObject.putProperty(nodeName, null);
+	}
+	
+	@Override
+	public void newNumber(final Object parent, final double value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (!model.isArray() && !model.isList()) {
+			throw new EjsonBuilderException("Add element on other than an array: ");
+		}
+		introspectionObject.addData(value);
+	}
+	
+	@Override
+	public void newNumber(final Object parent, final long value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (!model.isArray() && !model.isList()) {
+			throw new EjsonBuilderException("Add element on other than an array: ");
+		}
+		introspectionObject.addData(value);
+	}
+	
+	@Override
+	public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Try inject number(long) in an ARRAY/List data= '" + value + "'");
+		}
+		/*
+		Class typeClass = model.getClassType();
+		if (! typeClass.isPrimitive()) {
+			throw new EjsonBuilderException("Try inject number(long) in an " + typeClass.getCanonicalName() + " data= '" + value + "'");
+		}
+		*/
+		introspectionObject.putProperty(nodeName, value);
+	}
+	
+	@Override
+	public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonException, AknotException {
+		if (parent == null) {
+			return;
+		}
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Try inject number(long) in an ARRAY/List data= '" + value + "'");
+		}
+		/*
+		Class typeClass = model.getClassType();
+		if (! typeClass.isPrimitive()) {
+			throw new EjsonBuilderException("Try inject number(long) in an " + typeClass.getCanonicalName() + " data= '" + value + "'");
+		}
+		*/
+		introspectionObject.addObject(nodeName, value);
+	}
+	
+	@Override
+	public Object newObject(final Object parent) throws EjsonException, AknotException {
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (!model.isArray() && !model.isList()) {
+			throw new EjsonBuilderException("Object created inside a non list ... ==> impssible case");
+		}
+		final Class typeClass = model.getClassType();
+		Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "'");
+		final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, typeClass);
+		// Create the data when object is ended created...
+		return new IntrospectionObject(inferData);
 		
+		//throw new EjsonBuilderException("Must be implemented ...");
 	}
 	
 	@Override
-	public void newBoolean(final Object parent, final String nodeName, final boolean value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonBoolean out = new JsonBoolean(value);
-			elem.put(nodeName, out);
+	public Object newObject(final Object parent, final String nodeName) throws EjsonException, AknotException {
+		Log.verbose("new element on NodeName=" + nodeName);
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		Class typeClass = null;
+		String listTreeName = null;
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Object is not compatible with an requested array: " + nodeName);
+		} else {
+			if (!introspectionObject.isSubNodeOrPropertyExist(nodeName) && model.isIgnoreUnknown()) {
+				Log.debug("Ignore node: '" + nodeName + "' Does not exist...");
+				return null;
+			}
+			try {
+				typeClass = introspectionObject.getTypeOfSubNode(nodeName, true);
+				listTreeName = introspectionObject.getTreeNameOfSubNode(nodeName, true);
+			} catch (final AknotException e) {
+				throw new EjsonBuilderException("Node does not exist: " + e.getMessage());
+			}
+		}
+		if (typeClass != null) {
+			// specific case for List ==> need to get the subType in introspection ...
+			if (typeClass.isArray()) {
+				final Class subTypeClass = typeClass.getComponentType();
+				Log.verbose("Create array new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+				IntrospectionModel inferData = null;
+				// when we request a list elements, we need to add the element in a list, then we need the return is LIST and not ARRAY
+				inferData = this.cacheModel.findOrCreate(ModelType.LIST, listTreeName, subTypeClass);
+				
+				// Create the data when object is ended created...
+				return new IntrospectionObject(inferData);
+			}
+			if (List.class.isAssignableFrom(typeClass)) {
+				Class subTypeClass = null;
+				try {
+					subTypeClass = introspectionObject.getTypeOfSubNodeSubType(nodeName);
+				} catch (final AknotException e) {
+					throw new EjsonBuilderException("Node does not exist: " + e.getMessage());
+				}
+				Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+				IntrospectionModel inferData = null;
+				inferData = this.cacheModel.findOrCreate(ModelType.LIST, listTreeName, subTypeClass);
+				// Create the data when object is ended created...
+				return new IntrospectionObject(inferData);
+			}
+			Log.verbose("Create new class: '" + typeClass.getCanonicalName() + "' for node '" + nodeName + "'");
+			final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, listTreeName, typeClass);
+			// Create the data when object is ended created...
+			return new IntrospectionObject(inferData);
+		}
+		return null;
+	}
+	
+	@Override
+	public Object newRoot() throws EjsonBuilderException, AknotException {
+		final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, this.rootNodeName, this.rootClassType);
+		return new IntrospectionObject(inferData);
+	}
+	
+	@Override
+	public void newString(final Object parent, final String value) throws EjsonException, AknotException {
+		if (parent == null) {
 			return;
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
+		final IntrospectionObject introspectionObject = (IntrospectionObject) parent;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		/*if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Try inject string in an ARRAY/List data= '" + value + "' ==> " + model.getClassType());
+		}*/
+		if (model.hasTextModel()) {
+			final String beanName = model.getTextBeanName();
+			if (beanName == null) {
+				if (model.isIgnoreUnknown()) {
+					Log.debug("Ignore node : **TEXT**");
+					return;
+				}
+				throw new EjsonBuilderException("The node **TEXT** Does not exist...");
+			}
+			final Class typeClass = model.getTypeOfText();
+			if (typeClass != null) {
+				// specific case for List ==> need to get the subType in introspection ...
+				if (typeClass.isPrimitive()) {
+					final Object out = StringSerializer.valueOf(typeClass, value);
+					introspectionObject.putProperty(beanName, out);
+				} else if (typeClass.isArray()) {
+					Log.error("Not managed !!! ");
+					/*
+					final String[] elems = propertyValue.split(";");
+					final Class subTypeClass = typeClass.getComponentType();
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+					final List out = new ArrayList<>();
+					for (int iii = 0; iii < elems.length; iii++) {
+						final Object tmp = inferData.getValueFromText(elems[iii]);
+						out.add(tmp);
+					}
+					introspectionObject.putProperty(propertyName, out);
+					*/
+				} else if (List.class.isAssignableFrom(typeClass)) {
+					Log.error("Not managed !!! ");
+					/*
+					final String[] elems = propertyValue.split(";");
+					final Class subTypeClass = introspectionObject.getTypeOfSubProperty(propertyName);
+					Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for property '" + propertyName + "'");
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+					final List out = new ArrayList<>();
+					for (int iii = 0; iii < elems.length; iii++) {
+						final Object tmp = inferData.getValueFromText(elems[iii]);
+						out.add(tmp);
+					}
+					introspectionObject.putProperty(propertyName, out);
+					*/
+				} else {
+					//Log.error("Not managed !!! ");
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, typeClass);
+					final Object out = inferData.getValueFromText(value);
+					introspectionObject.putProperty(IntrospectionObject.PUBLIC_TEXT_NAME, out);
+				}
+			}
+		} else {
+			final Class typeClass = model.getClassType();
+			if (typeClass != null) {
+				// specific case for List ==> need to get the subType in introspection ...
+				if (typeClass.isPrimitive()) {
+					final Object out = StringSerializer.valueOf(typeClass, value);
+					introspectionObject.addObject(model.getTokenBasicList(), out);
+				} else if (typeClass.isArray()) {
+					final String[] elems = value.split(";");
+					final Class subTypeClass = typeClass.getComponentType();
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+					final List out = new ArrayList<>();
+					for (int iii = 0; iii < elems.length; iii++) {
+						final Object tmp = inferData.getValueFromText(elems[iii]);
+						out.add(tmp);
+					}
+					introspectionObject.addObject(model.getTokenBasicList(), out);
+				} else if (List.class.isAssignableFrom(typeClass)) {
+					final String[] elems = value.split(";");
+					final Class subTypeClass = introspectionObject.getTypeOfSubNode(value, true);
+					Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for property '" + value + "'");
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+					final List out = new ArrayList<>();
+					for (int iii = 0; iii < elems.length; iii++) {
+						final Object tmp = inferData.getValueFromText(elems[iii]);
+						out.add(tmp);
+					}
+					introspectionObject.addObject(model.getTokenBasicList(), out);
+				} else {
+					final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, typeClass);
+					final Object out = inferData.getValueFromText(value);
+					introspectionObject.addObject(model.getTokenBasicList(), out);
+				}
+			} else {
+				
+				introspectionObject.setText(value);
+			}
+		}
 	}
 	
 	@Override
-	public void newNull(final Object parent) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonNull out = new JsonNull();
-			elem.add(out);
+	public void newString(final Object element, final String nodeName, final String value) throws EjsonException, AknotException {
+		if (element == null) {
 			return;
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
-		
-	}
-	
-	@Override
-	public void newNull(final Object parent, final String nodeName) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonNull out = new JsonNull();
-			elem.put(nodeName, out);
-			return;
+		final IntrospectionObject introspectionObject = (IntrospectionObject) element;
+		final IntrospectionModel model = introspectionObject.getModelIntrospection();
+		if (model.isArray() || model.isList()) {
+			throw new EjsonBuilderException("Model (List/Array) can not have property with name '" + nodeName + "'");
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
-	}
-	
-	@Override
-	public void newNumber(final Object parent, final double value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonNumber out = new JsonNumber(value);
-			elem.add(out);
-			return;
+		final String beanName = model.getBeanName(nodeName);
+		if (beanName == null) {
+			if (model.isIgnoreUnknown()) {
+				Log.debug("Ignore node : '" + nodeName + "'");
+				return;
+			}
+			throw new EjsonBuilderException("The node '" + nodeName + "' Does not exist...");
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
-		
-	}
-	
-	@Override
-	public void newNumber(final Object parent, final long value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonNumber out = new JsonNumber(value);
-			elem.add(out);
-			return;
+		// T O D O: check why we do not use the been name to get the type ..... !!!!!!!!!!!
+		final Class typeClass = model.getTypeOfSubNode(nodeName, true);
+		if (typeClass != null) {
+			// specific case for List ==> need to get the subType in introspection ...
+			if (typeClass.isPrimitive()) {
+				final Object out = StringSerializer.valueOf(typeClass, value);
+				introspectionObject.addObject(nodeName, out);
+			} else if (typeClass.isArray()) {
+				final String[] elems = value.split(";");
+				final Class subTypeClass = typeClass.getComponentType();
+				final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+				final List out = new ArrayList<>();
+				for (int iii = 0; iii < elems.length; iii++) {
+					final Object tmp = inferData.getValueFromText(elems[iii]);
+					out.add(tmp);
+				}
+				introspectionObject.addObject(nodeName, out);
+			} else if (List.class.isAssignableFrom(typeClass)) {
+				final String[] elems = value.split(";");
+				final Class subTypeClass = introspectionObject.getTypeOfSubNode(value, true);
+				Log.verbose("Create List new 'SUB' class: '" + typeClass.getCanonicalName() + "' for property '" + value + "'");
+				final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, subTypeClass);
+				final List out = new ArrayList<>();
+				for (int iii = 0; iii < elems.length; iii++) {
+					final Object tmp = inferData.getValueFromText(elems[iii]);
+					out.add(tmp);
+				}
+				introspectionObject.addObject(nodeName, out);
+			} else {
+				final IntrospectionModel inferData = this.cacheModel.findOrCreate(ModelType.NORMAL, null, typeClass);
+				final Object out = inferData.getValueFromText(value);
+				introspectionObject.addObject(nodeName, out);
+			}
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
-		
-	}
-	
-	@Override
-	public void newNumber(final Object parent, final String nodeName, final double value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonNumber out = new JsonNumber(value);
-			elem.put(nodeName, out);
-			return;
+		/*
+		} else {
+			introspectionObject.addObject(nodeName, value);
 		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
-	}
-	
-	@Override
-	public void newNumber(final Object parent, final String nodeName, final long value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonNumber out = new JsonNumber(value);
-			elem.put(nodeName, out);
-			return;
-		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
-	}
-	
-	@Override
-	public Object newObject(final Object parent) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonObject out = new JsonObject();
-			elem.add(out);
-			return out;
-		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
-	}
-	
-	@Override
-	public Object newObject(final Object parent, final String nodeName) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonObject out = new JsonObject();
-			elem.put(nodeName, out);
-			return out;
-		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
-	}
-	
-	@Override
-	public Object newRoot() throws EjsonBuilderException {
-		return new JsonObject();
-	}
-	
-	@Override
-	public void newString(final Object parent, final String value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonArray elem) {
-			final JsonString out = new JsonString(value);
-			elem.add(out);
-			return;
-		}
-		throw new EjsonBuilderException("can not add Comment on something else than array");
-		
-	}
-	
-	@Override
-	public void newString(final Object parent, final String nodeName, final String value) throws EjsonBuilderException, Exception {
-		if (parent instanceof final JsonObject elem) {
-			final JsonString out = new JsonString(value);
-			elem.put(nodeName, out);
-			return;
-		}
-		throw new EjsonBuilderException("can not add Comment on something else than Object");
+		*/
 	}
 	
 }
diff --git a/src/org/atriasoft/ejson/builder/IntrospectionObject.java b/src/org/atriasoft/ejson/builder/IntrospectionObject.java
index 6da15f2..ffd23ff 100644
--- a/src/org/atriasoft/ejson/builder/IntrospectionObject.java
+++ b/src/org/atriasoft/ejson/builder/IntrospectionObject.java
@@ -22,8 +22,25 @@ public class IntrospectionObject {
 		this.modelInterface = dataInterface;
 	}
 	
+	public void addData(final Object value) throws AknotException, EjsonException {
+		Log.warning("Add Object in list {}", value);
+		final Object value2 = this.modelInterface.getValueConverted(value, this.modelInterface.getClassType());
+		
+		final String uniqueName = this.modelInterface.getTokenBasicList();
+		if (!this.nodes.containsKey(uniqueName)) {
+			final List tmp = new ArrayList<>();
+			tmp.add(value2);
+			Log.warning("    ==> new list");
+			this.nodes.put(uniqueName, tmp);
+		} else {
+			Log.warning("    ==> previous list");
+			this.nodes.get(uniqueName).add(value2);
+			Log.warning("        >> {}", this.nodes.get(uniqueName));
+		}
+	}
+	
 	@SuppressWarnings("unchecked")
-	public void addObject(final String nodeName, final Object value) throws EjsonException {
+	public void addObject(final String nodeName, Object value) throws EjsonException, AknotException {
 		if (value == null) {
 			// specific case when a List is empty  but define for a specific list ==> need no action
 			return;
@@ -33,20 +50,17 @@ public class IntrospectionObject {
 			throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
 		}
 		List node = this.nodes.get(beanName);
+		// Convert in the correct internal type if needed.
+		final Class type = this.modelInterface.getTypeOfSubNode(nodeName, true);
+		if (type == byte.class || type == Byte.class || type == float.class || type == Float.class || type == double.class || type == Double.class || type == long.class || type == Long.class
+				|| type == int.class || type == Integer.class || type == boolean.class || type == Boolean.class || type == short.class || type == Short.class) {
+			value = this.modelInterface.getValueConverted(value, type);
+		}
 		if (node == null) {
 			if (List.class.isAssignableFrom(value.getClass())) {
 				node = (List) value;
 			} else if (value.getClass().isArray()) {
 				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
-				Log.error("this is a big problem ...");
 			} else {
 				node = new ArrayList<>();
 				node.add(value);
@@ -54,15 +68,6 @@ public class IntrospectionObject {
 			this.nodes.put(beanName, node);
 		} else if (value.getClass().isArray()) {
 			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
-			Log.error("this is a big problem ...");
 		} else if (List.class.isAssignableFrom(value.getClass())) {
 			final List nodeIn = (List) value;
 			node.addAll(nodeIn);
@@ -71,7 +76,7 @@ public class IntrospectionObject {
 		}
 	}
 	
-	public void generateTheObject() throws AknotException {
+	public void generateTheObject(final boolean attributeIndependent) throws AknotException {
 		if (this.data != null) {
 			// nothing to do ... ==> element already created
 			return;
@@ -80,7 +85,7 @@ public class IntrospectionObject {
 				+ (this.modelInterface.isList() ? "[List]" : ""));
 		Log.warning("    Properties : " + this.properties.keySet());
 		Log.warning("    Nodes : " + this.nodes.keySet());
-		this.data = this.modelInterface.createObject(this.properties, this.nodes);
+		this.data = this.modelInterface.createObject(this.properties, this.nodes, attributeIndependent);
 	}
 	
 	public Object getData() {
@@ -91,12 +96,12 @@ public class IntrospectionObject {
 		return this.modelInterface;
 	}
 	
-	public String getTreeNameOfSubNode(final String nodeName) throws AknotException, EjsonNodeDoesNotExist {
+	public String getTreeNameOfSubNode(final String nodeName, final boolean attributeIndependent) throws AknotException, EjsonNodeDoesNotExist {
 		final String beanName = this.modelInterface.getBeanName(nodeName);
 		if (beanName == null) {
 			throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
 		}
-		return this.modelInterface.getTreeNameOfSubNode(beanName);
+		return this.modelInterface.getTreeNameOfSubNode(beanName, attributeIndependent);
 	}
 	
 	public Class getTypeOfProperty(final String nodeName) throws AknotException, EjsonNodeDoesNotExist {
@@ -112,13 +117,13 @@ public class IntrospectionObject {
 	 * @param nodeName Name of the node
 	 * @return Class of the node to create
 	 */
-	public Class getTypeOfSubNode(final String nodeName) throws AknotException, EjsonNodeDoesNotExist {
+	public Class getTypeOfSubNode(final String nodeName, final boolean attributeIndependent) throws AknotException, EjsonNodeDoesNotExist {
 		final String beanName = this.modelInterface.getBeanNameModel(nodeName);
 		
 		if (beanName == null) {
 			throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
 		}
-		return this.modelInterface.getTypeOfSubNode(beanName);
+		return this.modelInterface.getTypeOfSubNode(beanName, attributeIndependent);
 	}
 	
 	public Class getTypeOfSubNodeSubType(final String nodeName) throws AknotException, EjsonNodeDoesNotExist {
@@ -126,7 +131,7 @@ public class IntrospectionObject {
 		if (beanName == null) {
 			throw new EjsonNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
 		}
-		return this.modelInterface.getTypeOfSubNodeList(beanName);
+		return this.modelInterface.getTypeOfSubNodeList(beanName, true);
 	}
 	
 	public Class getTypeOfSubProperty(final String nodeName) throws AknotException, EjsonNodeDoesNotExist {
diff --git a/src/org/atriasoft/ejson/generator/GeneratorGeneric.java b/src/org/atriasoft/ejson/generator/GeneratorGeneric.java
index 11fc4de..7918440 100644
--- a/src/org/atriasoft/ejson/generator/GeneratorGeneric.java
+++ b/src/org/atriasoft/ejson/generator/GeneratorGeneric.java
@@ -73,10 +73,9 @@ public class GeneratorGeneric {
 					}
 				}
 			}
+			data.append("[");
 			if (oneLine) {
-				data.append("[ ");
-			} else {
-				data.append("[\n");
+				data.append(" ");
 			}
 			for (int iii = 0; iii < tmp.size(); iii++) {
 				if (!oneLine) {
@@ -90,8 +89,6 @@ public class GeneratorGeneric {
 				}
 				if (oneLine) {
 					data.append(" ");
-				} else {
-					data.append("\n");
 				}
 			}
 			if (!oneLine) {
@@ -167,6 +164,9 @@ public class GeneratorGeneric {
 				}
 			}
 			data.append("{");
+			if (oneLine) {
+				data.append(" ");
+			}
 			final Iterator> iterator = tmp.entrySet().iterator();
 			while (iterator.hasNext()) {
 				final Map.Entry entry = iterator.next();
@@ -180,6 +180,9 @@ public class GeneratorGeneric {
 				if (iterator.hasNext()) {
 					data.append(",");
 				}
+				if (oneLine) {
+					data.append(" ");
+				}
 			}
 			if (!oneLine) {
 				Tools.addIndent(data, indent - 1);
diff --git a/src/org/atriasoft/ejson/parser/ParseJson.java b/src/org/atriasoft/ejson/parser/ParseJson.java
index 8aa1ad5..78e4978 100644
--- a/src/org/atriasoft/ejson/parser/ParseJson.java
+++ b/src/org/atriasoft/ejson/parser/ParseJson.java
@@ -1,7 +1,9 @@
 package org.atriasoft.ejson.parser;
 
+import org.atriasoft.aknot.exception.AknotException;
 import org.atriasoft.ejson.builder.Builder;
 import org.atriasoft.ejson.exception.EjsonBuilderException;
+import org.atriasoft.ejson.exception.EjsonException;
 import org.atriasoft.ejson.exception.EjsonParserError;
 import org.atriasoft.ejson.exception.EjsonParserErrorMulti;
 import org.atriasoft.ejson.internal.Log;
@@ -16,8 +18,8 @@ public class ParseJson {
 		this.builder = builder;
 	}
 	
-	boolean iParseArray(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws Exception {
-		for (int iii = pos.value + 1; iii < data.length(); iii++) {
+	boolean iParseArray(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws EjsonException, AknotException {
+		for (int iii = pos.value; iii < data.length(); iii++) {
 			//Log.verbose("parse Array: '{}'", data.charAt(iii));
 			filePos.check(data.charAt(iii));
 			if (data.charAt(iii) == ' ' || data.charAt(iii) == '\t' || data.charAt(iii) == '\n' || data.charAt(iii) == '\r') {
@@ -31,7 +33,7 @@ public class ParseJson {
 				}
 			} else if (data.charAt(iii) == ']') {
 				// find end of value:
-				pos.value = iii; //  == > return the end element type ==> usefull to check end and check if adding element is needed
+				pos.value = iii; //  == > return the end element type ==> useful to check end and check if adding element is needed
 				if (parent != null) {
 					// continue parsing without registering object ...
 					this.builder.endParsing(parent);
@@ -42,14 +44,15 @@ public class ParseJson {
 				// find an object:
 				if (parent == null) {
 					// continue parsing without registering object ...
-					if (!iParseObject(null, data, pos, filePos, parsingProperty)) {
+					if (!subParseObject(null, data, pos, filePos, parsingProperty)) {
 						return false;
 					}
 				} else {
 					final Object obj = this.builder.newObject(parent);
-					if (!iParseObject(obj, data, pos, filePos, parsingProperty)) {
+					if (!subParseObject(obj, data, pos, filePos, parsingProperty)) {
 						return false;
 					}
+					this.builder.newArrayFinished(parent, null, obj);
 				}
 				iii = pos.value;
 			} else if (data.charAt(iii) == '"' || data.charAt(iii) == '\'') {
@@ -126,10 +129,10 @@ public class ParseJson {
 					if (dataNumber == null) {
 						return false;
 					}
-					if (dataNumber instanceof Double) {
-						this.builder.newNumber(parent, (Double) dataNumber);
-					} else if (dataNumber instanceof Long) {
-						this.builder.newNumber(parent, (Long) dataNumber);
+					if (dataNumber instanceof final Double vall) {
+						this.builder.newNumber(parent, vall);
+					} else if (dataNumber instanceof final Long vall) {
+						this.builder.newNumber(parent, vall);
 					}
 				}
 				iii = pos.value;
@@ -191,11 +194,11 @@ public class ParseJson {
 			filePos.check(data.charAt(iii));
 			if (!Tools.checkNumber(data.charAt(iii))) {
 				pos.value = iii - 1;
+				// Specific for raw Parsing when using introspection model.
 				if (isDouble) {
 					return Double.valueOf(tmpVal);
-				} else {
-					return Long.valueOf(tmpVal);
 				}
+				return Long.valueOf(tmpVal);
 			}
 			if (data.charAt(iii) == '.' || data.charAt(iii) == 'e' || data.charAt(iii) == '^') {
 				isDouble = true;
@@ -207,7 +210,59 @@ public class ParseJson {
 		return null;
 	}
 	
-	boolean iParseObject(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws Exception {
+	String iParseString(final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws EjsonBuilderException {
+		final Character end = data.charAt(pos.value);
+		boolean backslashPrevious = false;
+		final StringBuilder out = new StringBuilder();
+		for (int iii = pos.value + 1; iii < data.length(); iii++) {
+			//Log.verbose("parse String: '{}'", data.charAt(iii));
+			filePos.check(data.charAt(iii));
+			if (data.charAt(iii) == '\\') {
+				if (backslashPrevious) {
+					out.append('\\');
+					backslashPrevious = false;
+				} else {
+					backslashPrevious = true;
+				}
+			} else if (data.charAt(iii) != end) {
+				if (backslashPrevious) {
+					out.append('\\');
+					backslashPrevious = false;
+				}
+				out.append(data.charAt(iii));
+			} else if (backslashPrevious) {
+				out.append('"');
+				backslashPrevious = false;
+			} else {
+				pos.value = iii;
+				return out.toString();
+			}
+		}
+		pos.value = data.length();
+		parsingProperty.createError(new EjsonParserError(Tools.extractLine(data, pos.value), filePos, "get end of string whithout fincding end of quote"));
+		return null;
+	}
+	
+	public Object parse(final String data, final ParsingProperty property) throws EjsonException, AknotException {
+		Log.verbose("Start parsing document (type: string) size={}", data.length());
+		// came from char  == > force in utf8 ...
+		final FilePos pos = new FilePos(1, 0);
+		final PositionParsing parsePos = new PositionParsing();
+		//parsePos.value = -1;
+		
+		final Object rootNode = this.builder.newRoot();
+		subParseObject(rootNode, data, parsePos, pos, property);
+		if (property.isErrorDetected()) {
+			if (property.isThrowOnError()) {
+				throw new EjsonParserErrorMulti("Parsing error multiple error detected", property.getErrors());
+			}
+			return null;
+		}
+		this.builder.endParsing(rootNode);
+		return rootNode;
+	}
+	
+	boolean subParseObject(final Object parent, final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws EjsonException, AknotException {
 		StatusParsing mode = StatusParsing.parseName;
 		StringBuilder currentName = new StringBuilder();
 		boolean standalone = true;
@@ -230,7 +285,7 @@ public class ParseJson {
 				}
 			} else if (data.charAt(iii) == '}') {
 				// find end of value:
-				pos.value = iii; //  == > return the end element type ==> usefull to check end and check if adding element is needed
+				pos.value = iii; //  == > return the end element type ==> useful to check end and check if adding element is needed
 				if (parent != null) {
 					this.builder.endParsing(parent);
 				}
@@ -275,14 +330,15 @@ public class ParseJson {
 					// find an object:
 					if (parent == null) {
 						// continue parsing without registering object ...
-						if (!iParseObject(null, data, pos, filePos, parsingProperty)) {
+						if (!subParseObject(null, data, pos, filePos, parsingProperty)) {
 							return false;
 						}
 					} else {
 						final Object obj = this.builder.newObject(parent, currentName.toString());
-						if (!iParseObject(obj, data, pos, filePos, parsingProperty)) {
+						if (!subParseObject(obj, data, pos, filePos, parsingProperty)) {
 							return false;
 						}
+						this.builder.newArrayFinished(parent, currentName.toString(), obj);
 					}
 					iii = pos.value;
 					currentName = new StringBuilder();
@@ -315,6 +371,7 @@ public class ParseJson {
 						if (!iParseArray(obj, data, pos, filePos, parsingProperty)) {
 							return false;
 						}
+						this.builder.newArrayFinished(parent, currentName.toString(), obj);
 					}
 					iii = pos.value;
 					currentName = new StringBuilder();
@@ -363,10 +420,10 @@ public class ParseJson {
 						if (dataNumber == null) {
 							return false;
 						}
-						if (dataNumber instanceof Double) {
-							this.builder.newNumber(parent, currentName.toString(), (Double) dataNumber);
-						} else if (dataNumber instanceof Long) {
-							this.builder.newNumber(parent, currentName.toString(), (Long) dataNumber);
+						if (dataNumber instanceof final Double valll) {
+							this.builder.newNumber(parent, currentName.toString(), valll);
+						} else if (dataNumber instanceof final Long valll) {
+							this.builder.newNumber(parent, currentName.toString(), valll);
 						}
 					}
 					iii = pos.value;
@@ -388,58 +445,6 @@ public class ParseJson {
 		return !standalone;
 	}
 	
-	String iParseString(final String data, final PositionParsing pos, final FilePos filePos, final ParsingProperty parsingProperty) throws EjsonBuilderException {
-		final Character end = data.charAt(pos.value);
-		boolean backslashPrevious = false;
-		final StringBuilder out = new StringBuilder();
-		for (int iii = pos.value + 1; iii < data.length(); iii++) {
-			//Log.verbose("parse String: '{}'", data.charAt(iii));
-			filePos.check(data.charAt(iii));
-			if (data.charAt(iii) == '\\') {
-				if (backslashPrevious) {
-					out.append('\\');
-					backslashPrevious = false;
-				} else {
-					backslashPrevious = true;
-				}
-			} else if (data.charAt(iii) != end) {
-				if (backslashPrevious) {
-					out.append('\\');
-					backslashPrevious = false;
-				}
-				out.append(data.charAt(iii));
-			} else if (backslashPrevious) {
-				out.append('"');
-				backslashPrevious = false;
-			} else {
-				pos.value = iii;
-				return out.toString();
-			}
-		}
-		pos.value = data.length();
-		parsingProperty.createError(new EjsonParserError(Tools.extractLine(data, pos.value), filePos, "get end of string whithout fincding end of quote"));
-		return null;
-	}
-	
-	public Object parse(final String data, final ParsingProperty property) throws Exception, EjsonBuilderException, EjsonParserErrorMulti {
-		Log.verbose("Start parsing document (type: string) size={}", data.length());
-		// came from char  == > force in utf8 ...
-		final FilePos pos = new FilePos(1, 0);
-		final PositionParsing parsePos = new PositionParsing();
-		//parsePos.value = -1;
-		
-		final Object rootNode = this.builder.newRoot();
-		iParseObject(rootNode, data, parsePos, pos, property);
-		if (property.isErrorDetected()) {
-			if (property.isThrowOnError()) {
-				throw new EjsonParserErrorMulti("Parsing error multiple error detected", property.getErrors());
-			}
-			return null;
-		}
-		this.builder.endParsing(rootNode);
-		return rootNode;
-	}
-	
 }
 
 enum StatusParsing {
diff --git a/test/src/test/atriasoft/ejson/internal/Log.java b/test/src/test/atriasoft/ejson/internal/Log.java
new file mode 100644
index 0000000..b9a5587
--- /dev/null
+++ b/test/src/test/atriasoft/ejson/internal/Log.java
@@ -0,0 +1,82 @@
+package test.atriasoft.ejson.internal;
+
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2021, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+
+import org.atriasoft.reggol.LogLevel;
+import org.atriasoft.reggol.Logger;
+
+public class Log {
+	private static final boolean FORCE_ALL = false;
+	private static final String LIB_NAME = "ejson-test";
+	private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME);
+	private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL);
+	private static final boolean PRINT_DEBUG = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.DEBUG);
+	private static final boolean PRINT_ERROR = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.ERROR);
+	private static final boolean PRINT_INFO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.INFO);
+	private static final boolean PRINT_PRINT = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.PRINT);
+	private static final boolean PRINT_TODO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.TODO);
+	private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.VERBOSE);
+	private static final boolean PRINT_WARNING = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.WARNING);
+	
+	public static void critical(final Exception e, final String data) {
+		e.printStackTrace();
+		if (PRINT_CRITICAL || FORCE_ALL) {
+			Logger.critical(LIB_NAME_DRAW, data + " : " + e.getMessage());
+		}
+	}
+	
+	public static void critical(final String data, final Object... objects) {
+		if (PRINT_CRITICAL || FORCE_ALL) {
+			Logger.critical(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void debug(final String data, final Object... objects) {
+		if (PRINT_DEBUG || FORCE_ALL) {
+			Logger.debug(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void error(final String data, final Object... objects) {
+		if (PRINT_ERROR || FORCE_ALL) {
+			Logger.error(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void info(final String data, final Object... objects) {
+		if (PRINT_INFO || FORCE_ALL) {
+			Logger.info(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void print(final String data, final Object... objects) {
+		if (PRINT_PRINT || FORCE_ALL) {
+			Logger.print(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void todo(final String data, final Object... objects) {
+		if (PRINT_TODO || FORCE_ALL) {
+			Logger.todo(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void verbose(final String data, final Object... objects) {
+		if (PRINT_VERBOSE || FORCE_ALL) {
+			Logger.verbose(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	public static void warning(final String data, final Object... objects) {
+		if (PRINT_WARNING || FORCE_ALL) {
+			Logger.warning(LIB_NAME_DRAW, data, objects);
+		}
+	}
+	
+	private Log() {}
+	
+}
diff --git a/test/src/test/atriasoft/ejson/introspection/EjsonTestIntrospection.java b/test/src/test/atriasoft/ejson/introspection/EjsonTestIntrospection.java
new file mode 100644
index 0000000..5c616dd
--- /dev/null
+++ b/test/src/test/atriasoft/ejson/introspection/EjsonTestIntrospection.java
@@ -0,0 +1,418 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2021, Edouard DUPIN, all right reserved
+ * @license MPL v2.0 (see license file)
+ */
+package test.atriasoft.ejson.introspection;
+
+import java.util.Arrays;
+
+import org.atriasoft.aknot.exception.AknotException;
+import org.atriasoft.ejson.JsonMapper;
+import org.atriasoft.ejson.exception.EjsonBuilderException;
+import org.atriasoft.ejson.exception.EjsonException;
+import org.atriasoft.ejson.exception.EjsonParserErrorMulti;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import test.atriasoft.ejson.internal.Log;
+import test.atriasoft.ejson.introspection.model.ClassMethodEnum;
+import test.atriasoft.ejson.introspection.model.ClassPublicChild;
+import test.atriasoft.ejson.introspection.model.ClassPublicMemberOnly;
+import test.atriasoft.ejson.introspection.model.ClassPublicMethodOnly;
+import test.atriasoft.ejson.introspection.model.ClassPublicMethodeNode;
+import test.atriasoft.ejson.introspection.model.ClassPublicMethodeStructured;
+import test.atriasoft.ejson.introspection.model.SimpleEnum;
+
+public class EjsonTestIntrospection {
+	@BeforeAll
+	public static void beforeClass() {
+		Log.verbose("----------------------------------------------------------------");
+	}
+	
+	@Test
+	public void test1() throws EjsonParserErrorMulti, EjsonBuilderException {
+		
+		//@formatter:off
+		final String dataToParse = """
+		{
+			  "memberByte":12,
+			  "memberShort":1223,
+			  "memberInteger":4541542,
+			  "memberLong": 4564654654,
+			  "memberBoolean": true\s,
+			  "memberByteClass": 55\s,
+			  "memberShortClass": 1523\s,
+			  "memberIntegerClass": 4654654\s,
+			  "memberLongClass": 545645645454,
+			  "memberBooleanClass": true\s,
+			  "memberStringClass": "sdfgsdkjfglksqjéé",
+			  "memberArrayByte": [12, 15,123, 100, 2],
+			  "memberArrayByteClass":[
+		\n 12,1, 100,122],
+			  "memberArrayShort":[1245,1894, -100,-12542],
+			  "memberArrayShortClass":[-1245,-1894, 0,2542,15615],
+			  "memberArrayInteger":[123456,-654987],
+			  "memberArrayIntegerClass":[1567845,45621354,-5646544],
+			  "memberArrayLong":[1651324654,65421351685,-5],
+			  "memberArrayLongClass":[6746541351,546546546,564654654,654654654654,-45546],
+			  "memberArrayBoolean":[true, true, false],
+			  "memberArrayBooleanClass":[false, false, true, true],
+			}
+		""";
+		//@formatter:on
+		final ClassPublicMemberOnly elem = Assertions.assertDoesNotThrow(() -> {
+			final JsonMapper mapper = new JsonMapper();
+			return mapper.parse(dataToParse, ClassPublicMemberOnly.class);
+		});
+		Assertions.assertNotNull(elem);
+		Assertions.assertEquals((byte) 12, elem.memberByte);
+		Assertions.assertEquals((short) 1223, elem.memberShort);
+		Assertions.assertEquals(4541542, elem.memberInteger);
+		Assertions.assertEquals(4564654654L, elem.memberLong);
+		Assertions.assertEquals(true, elem.memberBoolean);
+		Assertions.assertEquals((byte) 55, elem.memberByteClass);
+		Assertions.assertEquals((short) 1523, elem.memberShortClass);
+		Assertions.assertEquals(4654654, elem.memberIntegerClass);
+		Assertions.assertEquals(545645645454L, elem.memberLongClass);
+		Assertions.assertEquals(true, elem.memberBooleanClass);
+		Assertions.assertEquals("sdfgsdkjfglksqjéé", elem.memberStringClass);
+		Assertions.assertEquals(5, elem.memberArrayByte.length);
+		Assertions.assertEquals((byte) 12, elem.memberArrayByte[0]);
+		Assertions.assertEquals((byte) 15, elem.memberArrayByte[1]);
+		Assertions.assertEquals((byte) 123, elem.memberArrayByte[2]);
+		Assertions.assertEquals((byte) 100, elem.memberArrayByte[3]);
+		Assertions.assertEquals(2, elem.memberArrayByte[4]);
+		Assertions.assertEquals(4, elem.memberArrayByteClass.length);
+		Assertions.assertEquals((byte) 12, elem.memberArrayByteClass[0]);
+		Assertions.assertEquals((byte) 1, elem.memberArrayByteClass[1]);
+		Assertions.assertEquals((byte) 100, elem.memberArrayByteClass[2]);
+		Assertions.assertEquals((byte) 122, elem.memberArrayByteClass[3]);
+		
+		Assertions.assertEquals(4, elem.memberArrayShort.length);
+		Assertions.assertEquals((short) 1245, elem.memberArrayShort[0]);
+		Assertions.assertEquals((short) 1894, elem.memberArrayShort[1]);
+		Assertions.assertEquals((short) -100, elem.memberArrayShort[2]);
+		Assertions.assertEquals((short) -12542, elem.memberArrayShort[3]);
+		
+		Assertions.assertEquals(5, elem.memberArrayShortClass.length);
+		Assertions.assertEquals((short) -1245, elem.memberArrayShortClass[0]);
+		Assertions.assertEquals((short) -1894, elem.memberArrayShortClass[1]);
+		Assertions.assertEquals((short) 0, elem.memberArrayShortClass[2]);
+		Assertions.assertEquals((short) 2542, elem.memberArrayShortClass[3]);
+		Assertions.assertEquals((short) 15615, elem.memberArrayShortClass[4]);
+		
+		Assertions.assertEquals(2, elem.memberArrayInteger.length);
+		//Assertions.assertArrayEquals(Arrays.asList(123456, -654987).toArray(), elem.memberArrayInteger);
+		
+		Assertions.assertEquals(3, elem.memberArrayIntegerClass.length);
+		Assertions.assertArrayEquals(Arrays.asList(1567845, 45621354, -5646544).toArray(), elem.memberArrayIntegerClass);
+		
+		Assertions.assertEquals(3, elem.memberArrayLong.length);
+		//Assertions.assertArrayEquals(Arrays.asList(1651324654L, 65421351685L, -5L).toArray(), elem.memberArrayLong);
+		Assertions.assertEquals(5, elem.memberArrayLongClass.length);
+		Assertions.assertArrayEquals(Arrays.asList(6746541351L, 546546546L, 564654654L, 654654654654L, -45546L).toArray(), elem.memberArrayLongClass);
+		Assertions.assertEquals(3, elem.memberArrayBoolean.length);
+		//Assertions.assertArrayEquals(Arrays.asList(true, true, false).toArray(), elem.memberArrayBoolean);
+		Assertions.assertEquals(4, elem.memberArrayBooleanClass.length);
+		Assertions.assertArrayEquals(Arrays.asList(false, false, true, true).toArray(), elem.memberArrayBooleanClass);
+		
+	}
+	
+	@Test
+	public void test2() {
+		//@formatter:off
+		final String dataToParse = """
+		{
+			 "memberByte": 12,
+			 "memberShort": 1223,
+			 "memberInteger": 4541542,
+			 "memberLong": 4564654654,
+			 "memberBoolean": true,
+			 "memberByteClass": 55,
+			 "memberShortClass": 1523,
+			 "memberIntegerClass": 4654654,
+			 "memberLongClass": 545645645454,
+			 "memberBooleanClass": true,
+			 "memberStringClass": "sdfgsdkjfglksqjéé",
+			 "memberArrayByte": [12, 15,123, 100, 2],
+			 "memberArrayByteClass":[
+		\n 12,1, 100,122],
+			 "memberArrayShort":[1245,1894, -100,-12542],
+			 "memberArrayShortClass":[-1245,-1894, 0,2542,15615],
+			 "memberArrayInteger":[123456,-654987],
+			 "memberArrayIntegerClass":[1567845,45621354,-5646544],
+			 "memberArrayLong":[1651324654,65421351685,-5],
+			 "memberArrayLongClass":[6746541351,546546546,564654654,654654654654,-45546],
+			 "memberArrayBoolean":[true, true, false],
+			 "memberArrayBooleanClass":[false, false, true, true],
+			}
+			""";
+		//@formatter:on
+		final ClassPublicMethodOnly elem = Assertions.assertDoesNotThrow(() -> {
+			final JsonMapper mapper = new JsonMapper();
+			return mapper.parse(dataToParse, ClassPublicMethodOnly.class);
+		});
+		Assertions.assertNotNull(elem);
+		Assertions.assertEquals((byte) 12, elem.getMemberByte());
+		Assertions.assertEquals((short) 1223, elem.getMemberShort());
+		Assertions.assertEquals(4541542, elem.getMemberInteger());
+		Assertions.assertEquals(4564654654L, elem.getMemberLong());
+		Assertions.assertEquals(true, elem.isMemberBoolean());
+		Assertions.assertEquals((byte) 55, elem.getMemberByteClass());
+		Assertions.assertEquals((short) 1523, elem.getMemberShortClass());
+		Assertions.assertEquals(4654654, elem.getMemberIntegerClass());
+		Assertions.assertEquals(545645645454L, elem.getMemberLongClass());
+		Assertions.assertEquals(true, elem.isMemberBooleanClass());
+		Assertions.assertEquals("sdfgsdkjfglksqjéé", elem.getMemberStringClass());
+		Assertions.assertEquals(5, elem.getMemberArrayByte().length);
+		Assertions.assertEquals((byte) 12, elem.getMemberArrayByte()[0]);
+		Assertions.assertEquals((byte) 15, elem.getMemberArrayByte()[1]);
+		Assertions.assertEquals((byte) 123, elem.getMemberArrayByte()[2]);
+		Assertions.assertEquals((byte) 100, elem.getMemberArrayByte()[3]);
+		Assertions.assertEquals(2, elem.getMemberArrayByte()[4]);
+		Assertions.assertEquals(4, elem.getMemberArrayByteClass().length);
+		Assertions.assertEquals((byte) 12, elem.getMemberArrayByteClass()[0]);
+		Assertions.assertEquals((byte) 1, elem.getMemberArrayByteClass()[1]);
+		Assertions.assertEquals((byte) 100, elem.getMemberArrayByteClass()[2]);
+		Assertions.assertEquals((byte) 122, elem.getMemberArrayByteClass()[3]);
+		
+		Assertions.assertEquals(4, elem.getMemberArrayShort().length);
+		Assertions.assertEquals((short) 1245, elem.getMemberArrayShort()[0]);
+		Assertions.assertEquals((short) 1894, elem.getMemberArrayShort()[1]);
+		Assertions.assertEquals((short) -100, elem.getMemberArrayShort()[2]);
+		Assertions.assertEquals((short) -12542, elem.getMemberArrayShort()[3]);
+		
+		Assertions.assertEquals(5, elem.getMemberArrayShortClass().length);
+		Assertions.assertEquals((short) -1245, elem.getMemberArrayShortClass()[0]);
+		Assertions.assertEquals((short) -1894, elem.getMemberArrayShortClass()[1]);
+		Assertions.assertEquals((short) 0, elem.getMemberArrayShortClass()[2]);
+		Assertions.assertEquals((short) 2542, elem.getMemberArrayShortClass()[3]);
+		Assertions.assertEquals((short) 15615, elem.getMemberArrayShortClass()[4]);
+		
+		Assertions.assertEquals(2, elem.getMemberArrayInteger().length);
+		//Assertions.assertArrayEquals(Arrays.asList(123456, -654987).toArray(), elem.getMemberArrayInteger());
+		
+		Assertions.assertEquals(3, elem.getMemberArrayIntegerClass().length);
+		Assertions.assertArrayEquals(Arrays.asList(1567845, 45621354, -5646544).toArray(), elem.getMemberArrayIntegerClass());
+		
+		Assertions.assertEquals(3, elem.getMemberArrayLong().length);
+		//Assertions.assertArrayEquals(Arrays.asList(1651324654L, 65421351685L, -5L).toArray(), elem.getMemberArrayLong());
+		Assertions.assertEquals(5, elem.getMemberArrayLongClass().length);
+		Assertions.assertArrayEquals(Arrays.asList(6746541351L, 546546546L, 564654654L, 654654654654L, -45546L).toArray(), elem.getMemberArrayLongClass());
+		Assertions.assertEquals(3, elem.getMemberArrayBoolean().length);
+		//Assertions.assertArrayEquals(Arrays.asList(true, true, false).toArray(), elem.getMemberArrayBoolean());
+		Assertions.assertEquals(4, elem.getMemberArrayBooleanClass().length);
+		Assertions.assertArrayEquals(Arrays.asList(false, false, true, true).toArray(), elem.getMemberArrayBooleanClass());
+		
+	}
+	
+	@Test
+	public void test3() {
+		//@formatter:off
+		final String dataToParse = """
+		{
+			 "memberByte": 12,
+			 "memberShort": 1223,
+			 "memberInteger": 4541542,
+			 "memberLong": 4564654654,
+			 "memberBoolean": true,
+			 "memberByteClass": 55,
+			 "memberShortClass": 1523,
+			 "memberIntegerClass": 4654654,
+			 "memberLongClass": 545645645454,
+			 "memberBooleanClass": true,
+			 "memberStringClass": "sdfgsdkjfglksqjéé",
+			 "memberArrayByte": [ 12 ] ,
+			 "memberArrayByte": [15],
+			 "memberArrayByte": [123],
+			 "memberArrayByte": [100],
+			 "memberArrayByte": [2],
+			 "memberArrayByteClass": [
+		\n 12],
+			 "memberArrayByteClass": [1],
+			 "memberArrayByteClass": [ 100],
+			 "memberArrayByteClass": [122],
+			 "memberArrayShort": [1245],
+			 "memberArrayShort": [1894],
+			 "memberArrayShort": [ -100],
+			 "memberArrayShort": [-12542],
+			 "memberArrayShortClass": [-1245],
+			 "memberArrayShortClass": [-1894],
+			 "memberArrayShortClass": [ 0],
+			 "memberArrayShortClass": [2542],
+			 "memberArrayShortClass": [15615],
+			 "memberArrayInteger": [123456],
+			 "memberArrayInteger": [-654987],
+			 "memberArrayIntegerClass": [1567845],
+			 "memberArrayIntegerClass": [45621354],
+			 "memberArrayIntegerClass": [-5646544],
+			 "memberArrayLong": [1651324654],
+			 "memberArrayLong": [65421351685],
+			 "memberArrayLong": [-5],
+			 "memberArrayLongClass": [6746541351],
+			 "memberArrayLongClass": [546546546],
+			 "memberArrayLongClass": [564654654],
+			 "memberArrayLongClass": [654654654654],
+			 "memberArrayLongClass": [-45546],
+			 "memberArrayBoolean": [true],
+			 "memberArrayBoolean": [ true],
+			 "memberArrayBoolean": [false],
+			 "memberArrayBooleanClass": [false],
+			 "memberArrayBooleanClass": [ false],
+			 "memberArrayBooleanClass":[ true],
+			 "memberArrayBooleanClass": [ true],
+			 "memberListByteClass": [55 ],
+			 "memberListByteClass": [  -53 ],
+			 "memberListShortClass": [ 31632],
+			 "memberListShortClass": [-32100 ],
+			 "memberListIntegerClass": [15612 ],
+			 "memberListIntegerClass": [  542 ],
+			 "memberListLongClass": [16521 ],
+			 "memberListLongClass": [  4654 ],
+			 "memberListLongClass": [9875546 ],
+			 "memberListBooleanClass": [ true],
+			 "memberListBooleanClass": [false ],
+			,
+			""";
+		//@formatter:on
+		final JsonMapper mapper2 = new JsonMapper();
+		try {
+			final ClassPublicMethodeNode elem2 = mapper2.parse(dataToParse, ClassPublicMethodeNode.class);
+		} catch (final EjsonException | AknotException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	@Test
+	public void test4() {
+		//@formatter:off
+		final String dataToParse = """
+		{
+			 "memberArrayByte": [
+			 	12,
+			 	15,
+			 	123, -100,
+			 	2,
+			 ],
+			 "memberListByte": [-112,
+			 	-115,
+			 	-13, -10,
+			 	12,
+			 ]
+		}
+			""";
+		//@formatter:on
+		final ClassPublicMethodeStructured elem = Assertions.assertDoesNotThrow(() -> {
+			final JsonMapper mapper = new JsonMapper();
+			return mapper.parse(dataToParse, ClassPublicMethodeStructured.class);
+		});
+		Assertions.assertNotNull(elem);
+		Assertions.assertEquals(5, elem.getMemberArrayByte().length);
+		Assertions.assertEquals((byte) 12, elem.getMemberArrayByte()[0]);
+		Assertions.assertEquals((byte) 15, elem.getMemberArrayByte()[1]);
+		Assertions.assertEquals((byte) 123, elem.getMemberArrayByte()[2]);
+		Assertions.assertEquals((byte) -100, elem.getMemberArrayByte()[3]);
+		Assertions.assertEquals((byte) 2, elem.getMemberArrayByte()[4]);
+		Assertions.assertEquals(5, elem.getMemberListByte().size());
+		Assertions.assertEquals((byte) -112, elem.getMemberListByte().get(0));
+		Assertions.assertEquals((byte) -115, elem.getMemberListByte().get(1));
+		Assertions.assertEquals((byte) -13, elem.getMemberListByte().get(2));
+		Assertions.assertEquals((byte) -10, elem.getMemberListByte().get(3));
+		Assertions.assertEquals((byte) 12, elem.getMemberListByte().get(4));
+		
+	}
+	
+	@Test
+	public void test5() {
+		//@formatter:off
+		final String dataToParse = """
+		{
+			 "data": "PLIF",
+			 "dataArray": [ "PLIF", "PROUT"]
+		}""";
+		//@formatter:on
+		final ClassMethodEnum elem = Assertions.assertDoesNotThrow(() -> {
+			final JsonMapper mapper = new JsonMapper();
+			return mapper.parse(dataToParse, ClassMethodEnum.class);
+		});
+		Assertions.assertNotNull(elem);
+		Assertions.assertEquals(SimpleEnum.PLIF, elem.getDataArray()[0]);
+		Assertions.assertEquals(SimpleEnum.PROUT, elem.getDataArray()[1]);
+		Assertions.assertEquals(SimpleEnum.PLIF, elem.getData());
+	}
+	
+	@Test
+	public void test6() {
+		//@formatter:off
+		final String dataToParse222 = """
+		{
+			memberData: {
+				 "memberArrayByte": [11, 12],
+				 "memberListByte": [13, 14],
+			},
+		}
+		""";
+		final String dataToParse = """
+		{
+			memberData: {
+				 "memberArrayByte": [11, 12],
+				 "memberListByte": [13, 14],
+			},
+			memberDataArray: [
+				{
+					 "memberListByte": [21, 22],
+				},
+				{
+					 "memberArrayByte": [23, 24],
+				},
+			],
+			memberDataList: [
+				{
+					 "memberListByte": [31, 32]
+				},
+				{
+					 "memberArrayByte": [33, 34],
+				},
+			],
+			value: {
+			    "data": "PLIF",
+				"dataArray": [ "PLIF", "PROUT"]
+			}
+		}""";
+		//@formatter:on
+		final ClassPublicChild elem = Assertions.assertDoesNotThrow(() -> {
+			final JsonMapper mapper = new JsonMapper();
+			return mapper.parse(dataToParse, ClassPublicChild.class);
+		});
+		Assertions.assertNotNull(elem);
+		Assertions.assertNotNull(elem.memberData);
+		Assertions.assertNotNull(elem.memberDataArray);
+		Assertions.assertNotNull(elem.memberDataList);
+		Assertions.assertNotNull(elem.value);
+		Assertions.assertEquals(2, elem.memberDataArray.length);
+		Assertions.assertEquals(2, elem.memberDataList.size());
+		
+		Assertions.assertEquals((byte) 11, elem.memberData.getMemberArrayByte()[0]);
+		Assertions.assertEquals((byte) 12, elem.memberData.getMemberArrayByte()[1]);
+		Assertions.assertEquals((byte) 13, elem.memberData.getMemberListByte().get(0));
+		Assertions.assertEquals((byte) 14, elem.memberData.getMemberListByte().get(1));
+		
+		Assertions.assertEquals((byte) 21, elem.memberDataArray[0].getMemberListByte().get(0));
+		Assertions.assertEquals((byte) 22, elem.memberDataArray[0].getMemberListByte().get(1));
+		Assertions.assertEquals((byte) 23, elem.memberDataArray[1].getMemberArrayByte()[0]);
+		Assertions.assertEquals((byte) 24, elem.memberDataArray[1].getMemberArrayByte()[1]);
+		
+		Assertions.assertEquals((byte) 31, elem.memberDataList.get(0).getMemberListByte().get(0));
+		Assertions.assertEquals((byte) 32, elem.memberDataList.get(0).getMemberListByte().get(1));
+		Assertions.assertEquals((byte) 33, elem.memberDataList.get(1).getMemberArrayByte()[0]);
+		Assertions.assertEquals((byte) 34, elem.memberDataList.get(1).getMemberArrayByte()[1]);
+		
+		Assertions.assertEquals(SimpleEnum.PLIF, elem.value.getDataArray()[0]);
+		Assertions.assertEquals(SimpleEnum.PROUT, elem.value.getDataArray()[1]);
+		Assertions.assertEquals(SimpleEnum.PLIF, elem.value.getData());
+	}
+	
+}
diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java b/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java
index 74df72d..a767ca0 100644
--- a/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java
+++ b/test/src/test/atriasoft/ejson/introspection/model/ClassMethodEnum.java
@@ -5,13 +5,22 @@ import org.atriasoft.aknot.annotation.AknotName;
 @AknotName("elem")
 public class ClassMethodEnum {
 	private SimpleEnum data;
+	private SimpleEnum[] dataArray;
 	
 	public SimpleEnum getData() {
 		return this.data;
 	}
 	
+	public SimpleEnum[] getDataArray() {
+		return this.dataArray;
+	}
+	
 	public void setData(final SimpleEnum data) {
 		this.data = data;
 	}
 	
+	public void setDataArray(final SimpleEnum[] dataArray) {
+		this.dataArray = dataArray;
+	}
+	
 }
diff --git a/test/src/test/atriasoft/ejson/introspection/model/ClassPublicChild.java b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicChild.java
new file mode 100644
index 0000000..54914c6
--- /dev/null
+++ b/test/src/test/atriasoft/ejson/introspection/model/ClassPublicChild.java
@@ -0,0 +1,11 @@
+package test.atriasoft.ejson.introspection.model;
+
+import java.util.List;
+
+public class ClassPublicChild {
+	// note: when private the decorator must be set on getter or setter, liker this you can use the internal name you want...
+	public ClassPublicMethodeStructured memberData;
+	public ClassPublicMethodeStructured[] memberDataArray;
+	public List memberDataList;
+	public ClassMethodEnum value;
+}