diff --git a/src/org/atriasoft/exml/Exml.java b/src/org/atriasoft/exml/Exml.java index 2843a69..1684c61 100644 --- a/src/org/atriasoft/exml/Exml.java +++ b/src/org/atriasoft/exml/Exml.java @@ -16,12 +16,12 @@ import org.atriasoft.exml.builder.Builder; import org.atriasoft.exml.builder.BuilderGeneric; import org.atriasoft.exml.exception.ExmlException; import org.atriasoft.exml.exception.ExmlParserErrorMulti; +import org.atriasoft.exml.generator.GeneratorGeneric; import org.atriasoft.exml.internal.Log; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.model.XmlNode; import org.atriasoft.exml.parser.ParseXml; import org.atriasoft.exml.parser.ParsingProperty; -import org.atriasoft.exml.serializer.SerializerXml; public class Exml { /** @@ -40,9 +40,9 @@ public class Exml { */ public static void generate(final XmlNode root, final StringBuilder data) { if (!root.isElement() || (((XmlElement) root).getValue() != null && !((XmlElement) root).getValue().isEmpty())) { - SerializerXml.serialize(root, data, 0); + GeneratorGeneric.serialize(root, data, 0); } else { - SerializerXml.serializeRoot((XmlElement) root, data); + GeneratorGeneric.serializeRoot((XmlElement) root, data); } // return iGenerate(_data, 0); } diff --git a/src/org/atriasoft/exml/XmlMapper.java b/src/org/atriasoft/exml/XmlMapper.java index 59d0741..e4e8f56 100644 --- a/src/org/atriasoft/exml/XmlMapper.java +++ b/src/org/atriasoft/exml/XmlMapper.java @@ -8,10 +8,10 @@ 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.etk.Uri; import org.atriasoft.exml.builder.Builder; import org.atriasoft.exml.builder.BuilderIntrospection; +import org.atriasoft.exml.builder.IntrospectionObject; import org.atriasoft.exml.exception.ExmlBuilderException; import org.atriasoft.exml.exception.ExmlException; import org.atriasoft.exml.exception.ExmlNodeDoesNotExist; @@ -44,6 +44,22 @@ public class XmlMapper { } } + public T parse(final Path path, final Class classType) throws ExmlException, ExmlNodeDoesNotExist, AknotException { + byte[] elemData = null; + try { + elemData = Files.readAllBytes(path); + } catch (final IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (elemData == null) { + Log.error("Can not read the Stream : " + path); + return null; + } + final String dataToParse = new String(elemData); + return parse(dataToParse, classType); + } + /** * Parse a single root node that have the name of the Class Parsed: *
diff --git a/src/org/atriasoft/exml/builder/BuilderIntrospection.java b/src/org/atriasoft/exml/builder/BuilderIntrospection.java
index e1ea38a..3bab5d8 100644
--- a/src/org/atriasoft/exml/builder/BuilderIntrospection.java
+++ b/src/org/atriasoft/exml/builder/BuilderIntrospection.java
@@ -9,7 +9,6 @@ import org.atriasoft.aknot.model.InterfaceFactoryAccess;
 import org.atriasoft.aknot.model.IntrospectionModel;
 import org.atriasoft.aknot.model.ModelType;
 import org.atriasoft.aknot.pojo.CacheIntrospectionModel;
-import org.atriasoft.aknot.pojo.IntrospectionObject;
 import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
 import org.atriasoft.exml.exception.ExmlBuilderException;
 import org.atriasoft.exml.exception.ExmlException;
@@ -264,7 +263,7 @@ public class BuilderIntrospection implements Builder {
 			final IntrospectionObject tmpp = new IntrospectionObject(inferData);
 			newText(tmpp, text);
 			final Object dataLocal = tmpp.getData();
-			introspectionObject.addObject(IntrospectionObject.STUPID_TOCKEN, dataLocal);
+			introspectionObject.addObject(IntrospectionModel.STUPID_TOCKEN, dataLocal);
 			return;
 		}
 		if (model.hasTextModel()) {
diff --git a/src/org/atriasoft/exml/builder/IntrospectionObject.java b/src/org/atriasoft/exml/builder/IntrospectionObject.java
new file mode 100644
index 0000000..2cd6343
--- /dev/null
+++ b/src/org/atriasoft/exml/builder/IntrospectionObject.java
@@ -0,0 +1,168 @@
+package org.atriasoft.exml.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.atriasoft.aknot.exception.AknotException;
+import org.atriasoft.aknot.model.IntrospectionModel;
+import org.atriasoft.exml.exception.ExmlException;
+import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
+import org.atriasoft.exml.internal.Log;
+
+public class IntrospectionObject {
+	public static final String PUBLIC_TEXT_NAME = "##<< ** TEXT-ZONE ** >>##";
+	private final IntrospectionModel modelInterface;
+	private Object data = null;
+	private final Map properties = new HashMap<>();
+	private final Map> nodes = new HashMap<>();
+	
+	public IntrospectionObject(final IntrospectionModel dataInterface) {
+		this.modelInterface = dataInterface;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public void addObject(final String nodeName, final Object value) throws ExmlException {
+		if (value == null) {
+			// specific case when a List is empty  but define for a specific list ==> need no action
+			return;
+		}
+		final String beanName = this.modelInterface.getBeanName(nodeName);
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		List node = this.nodes.get(beanName);
+		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);
+			}
+			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);
+		} else {
+			node.add(value);
+		}
+	}
+	
+	public void generateTheObject() throws AknotException {
+		if (this.data != null) {
+			// nothing to do ... ==> element already created
+			return;
+		}
+		Log.warning("Create the element for the Specific node ... type = " + this.modelInterface.getClassType().getCanonicalName() + (this.modelInterface.isArray() ? "[array]" : "")
+				+ (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);
+	}
+	
+	public Object getData() {
+		return this.data;
+	}
+	
+	public IntrospectionModel getModelIntrospection() {
+		return this.modelInterface;
+	}
+	
+	public String getTreeNameOfSubNode(final String nodeName) throws AknotException, ExmlNodeDoesNotExist {
+		final String beanName = this.modelInterface.getBeanName(nodeName);
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		return this.modelInterface.getTreeNameOfSubNode(beanName);
+	}
+	
+	public Class getTypeOfProperty(final String nodeName) throws AknotException, ExmlNodeDoesNotExist {
+		final String beanName = this.modelInterface.getBeanName(nodeName);
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		return this.modelInterface.getTypeOfProperty(beanName);
+	}
+	
+	/**
+	 * Detect a subNode, and ask the type of the node at the parent Class
+	 * @param nodeName Name of the node
+	 * @return Class of the node to create
+	 */
+	public Class getTypeOfSubNode(final String nodeName) throws AknotException, ExmlNodeDoesNotExist {
+		final String beanName = this.modelInterface.getBeanNameModel(nodeName);
+		
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		return this.modelInterface.getTypeOfSubNode(beanName);
+	}
+	
+	public Class getTypeOfSubNodeSubType(final String nodeName) throws AknotException, ExmlNodeDoesNotExist {
+		final String beanName = this.modelInterface.getBeanNameModel(nodeName);
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		return this.modelInterface.getTypeOfSubNodeList(beanName);
+	}
+	
+	public Class getTypeOfSubProperty(final String nodeName) throws AknotException, ExmlNodeDoesNotExist {
+		final String beanName = this.modelInterface.getBeanName(nodeName);
+		if (beanName == null) {
+			throw new ExmlNodeDoesNotExist("The node '" + nodeName + "' Does not exist...");
+		}
+		return this.modelInterface.getTypeOfSubProperty(beanName);
+	}
+	
+	public boolean isSubNodeOrPropertyExist(final String nodeName) {
+		final String beanName = this.modelInterface.getBeanName(nodeName);
+		if (beanName == null) {
+			return false;
+		}
+		return true;
+	}
+	
+	public void putProperty(final String propertyName, final Object propertyValue) throws AknotException, ExmlException {
+		String beanName = null;
+		if (propertyName == PUBLIC_TEXT_NAME) {
+			beanName = this.modelInterface.getTextBeanName();
+		} else {
+			beanName = this.modelInterface.getBeanName(propertyName);
+		}
+		if (this.properties.containsKey(beanName)) {
+			throw new ExmlException("Property have multiple values ==> impossible case; A Node must contain only 1 attibutes");
+		}
+		this.properties.put(beanName, propertyValue);
+	}
+	
+	public void setText(final String text) throws AknotException, ExmlException {
+		if (this.data != null) {
+			throw new ExmlException("Can not set multiple text value in a single NODE ...");
+		}
+		this.data = this.modelInterface.getValueFromText(text);
+	}
+	
+}
diff --git a/src/org/atriasoft/exml/serializer/SerializerXml.java b/src/org/atriasoft/exml/generator/GeneratorGeneric.java
similarity index 80%
rename from src/org/atriasoft/exml/serializer/SerializerXml.java
rename to src/org/atriasoft/exml/generator/GeneratorGeneric.java
index 1d438c3..4cd20f2 100644
--- a/src/org/atriasoft/exml/serializer/SerializerXml.java
+++ b/src/org/atriasoft/exml/generator/GeneratorGeneric.java
@@ -1,4 +1,4 @@
-package org.atriasoft.exml.serializer;
+package org.atriasoft.exml.generator;
 
 import java.util.List;
 
@@ -13,16 +13,16 @@ import org.atriasoft.exml.model.XmlNode;
 import org.atriasoft.exml.model.XmlNodeType;
 import org.atriasoft.exml.model.XmlText;
 
-public class SerializerXml {
+public class GeneratorGeneric {
 	public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
 		if (node instanceof XmlElement) {
-			SerializerXml.serializeElement((XmlElement) node, data, indent);
+			GeneratorGeneric.serializeElement((XmlElement) node, data, indent);
 		} else if (node instanceof XmlText) {
-			SerializerXml.serializeText((XmlText) node, data, indent);
+			GeneratorGeneric.serializeText((XmlText) node, data, indent);
 		} else if (node instanceof XmlDeclaration) {
-			SerializerXml.serializeDeclaration((XmlDeclaration) node, data, indent);
+			GeneratorGeneric.serializeDeclaration((XmlDeclaration) node, data, indent);
 		} else if (node instanceof XmlComment) {
-			SerializerXml.serializeComment((XmlComment) node, data, indent);
+			GeneratorGeneric.serializeComment((XmlComment) node, data, indent);
 		} else {
 			// TODO throw an error ...
 		}
@@ -38,7 +38,7 @@ public class SerializerXml {
 	
 	private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) {
 		for (int iii = 0; iii < list.getAttributes().size(); iii++) {
-			SerializerXml.serializeAttribute(list.getAttributes().get(iii), data, indent);
+			GeneratorGeneric.serializeAttribute(list.getAttributes().get(iii), data, indent);
 		}
 	}
 	
@@ -56,7 +56,7 @@ public class SerializerXml {
 		Tools.addIndent(data, indent);
 		data.append("");
 		
 	}
@@ -66,19 +66,19 @@ public class SerializerXml {
 		Tools.addIndent(data, indent);
 		data.append("<");
 		data.append(element.getValue());
-		SerializerXml.serializeAttributeList(element, data, indent);
+		GeneratorGeneric.serializeAttributeList(element, data, indent);
 		
 		final List nodes = element.getNodes();
 		if (nodes.size() > 0) {
 			if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) {
 				data.append(">");
-				SerializerXml.serialize(nodes.get(0), data, 0);
+				GeneratorGeneric.serialize(nodes.get(0), data, 0);
 				Log.verbose(" generate : '" + data + "'");
 			} else {
 				data.append(">");
 				for (final XmlNode node : nodes) {
 					if (node != null) {
-						SerializerXml.serialize(node, data, indent + 1);
+						GeneratorGeneric.serialize(node, data, indent + 1);
 					}
 				}
 				Tools.addIndent(data, indent);
@@ -94,7 +94,7 @@ public class SerializerXml {
 	public static void serializeRoot(final XmlElement root, final StringBuilder data) {
 		for (int iii = 0; iii < root.getNodes().size(); iii++) {
 			final XmlNode node = root.getNodes().get(iii);
-			SerializerXml.serialize(node, data, 0);
+			GeneratorGeneric.serialize(node, data, 0);
 		}
 		
 	}
@@ -112,5 +112,5 @@ public class SerializerXml {
 	}
 	*/
 	
-	private SerializerXml() {}
+	private GeneratorGeneric() {}
 }
diff --git a/src/org/atriasoft/exml/model/XmlElement.java b/src/org/atriasoft/exml/model/XmlElement.java
index a35a555..5d6d98a 100644
--- a/src/org/atriasoft/exml/model/XmlElement.java
+++ b/src/org/atriasoft/exml/model/XmlElement.java
@@ -11,8 +11,8 @@ import java.util.List;
 import java.util.ListIterator;
 
 import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
+import org.atriasoft.exml.generator.GeneratorGeneric;
 import org.atriasoft.exml.internal.Log;
-import org.atriasoft.exml.serializer.SerializerXml;
 
 /** @file
  * @author Edouard DUPIN
@@ -171,12 +171,12 @@ public class XmlElement extends XmlAttributeList {
 			if (this.listSub.get(0).getType() == XmlNodeType.TEXT) {
 				res.append(this.listSub.get(0).getValue());
 			} else {
-				SerializerXml.serialize(this.listSub.get(0), res, 0);
+				GeneratorGeneric.serialize(this.listSub.get(0), res, 0);
 			}
 		} else {
 			for (int iii = 0; iii < this.listSub.size(); iii++) {
 				if (this.listSub.get(iii) != null) {
-					SerializerXml.serialize(this.listSub.get(iii), res, 0);
+					GeneratorGeneric.serialize(this.listSub.get(iii), res, 0);
 				}
 			}
 		}
diff --git a/src/org/atriasoft/exml/serializer/SerializerXmlIntrospection.java b/src/org/atriasoft/exml/serializer/SerializerXmlIntrospection.java
deleted file mode 100644
index 550b7a6..0000000
--- a/src/org/atriasoft/exml/serializer/SerializerXmlIntrospection.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.atriasoft.exml.serializer;
-
-import java.util.List;
-
-import org.atriasoft.etk.Tools;
-import org.atriasoft.exml.generator.Generator;
-import org.atriasoft.exml.internal.Log;
-import org.atriasoft.exml.model.XmlAttribute;
-import org.atriasoft.exml.model.XmlAttributeList;
-import org.atriasoft.exml.model.XmlComment;
-import org.atriasoft.exml.model.XmlDeclaration;
-import org.atriasoft.exml.model.XmlElement;
-import org.atriasoft.exml.model.XmlNode;
-import org.atriasoft.exml.model.XmlNodeType;
-import org.atriasoft.exml.model.XmlText;
-import org.atriasoft.exml.parser.ParsingProperty;
-
-public class SerializerXmlIntrospection {
-	public static void serialize(final XmlNode node, final StringBuilder data, final int indent) {
-		if (node instanceof XmlElement) {
-			SerializerXmlIntrospection.serializeElement((XmlElement) node, data, indent);
-		} else if (node instanceof XmlText) {
-			SerializerXmlIntrospection.serializeText((XmlText) node, data, indent);
-		} else if (node instanceof XmlDeclaration) {
-			SerializerXmlIntrospection.serializeDeclaration((XmlDeclaration) node, data, indent);
-		} else if (node instanceof XmlComment) {
-			SerializerXmlIntrospection.serializeComment((XmlComment) node, data, indent);
-		} else {
-			// TODO throw an error ...
-		}
-	}
-	
-	private static void serializeAttribute(final XmlAttribute attribute, final StringBuilder data, final int indent) {
-		data.append(" ");
-		data.append(attribute.getName());
-		data.append("=\"");
-		data.append(attribute.getValue());
-		data.append("\"");
-	}
-	
-	private static void serializeAttributeList(final XmlAttributeList list, final StringBuilder data, final int indent) {
-		for (int iii = 0; iii < list.getAttributes().size(); iii++) {
-			SerializerXmlIntrospection.serializeAttribute(list.getAttributes().get(iii), data, indent);
-		}
-	}
-	
-	private static void serializeComment(final XmlComment comment, final StringBuilder data, final int indent) {
-		Tools.addIndent(data, indent);
-		data.append("\n");
-	}
-	
-	private static void serializeDeclaration(final XmlDeclaration declaration, final StringBuilder data, final int indent) {
-		Tools.addIndent(data, indent);
-		data.append("\n");
-		
-	}
-	
-	private static void serializeElement(final XmlElement element, final StringBuilder data, final int indent) {
-		
-		Tools.addIndent(data, indent);
-		data.append("<");
-		data.append(element.getValue());
-		SerializerXmlIntrospection.serializeAttributeList(element, data, indent);
-		
-		final List nodes = element.getNodes();
-		if (nodes.size() > 0) {
-			if (nodes.size() == 1 && nodes.get(0) != null && nodes.get(0).getType() == XmlNodeType.TEXT && ((XmlText) nodes.get(0)).countLines() == 1) {
-				data.append(">");
-				SerializerXmlIntrospection.serialize(nodes.get(0), data, 0);
-				Log.verbose(" generate : '" + data + "'");
-			} else {
-				data.append(">\n");
-				for (final XmlNode node : nodes) {
-					if (node != null) {
-						SerializerXmlIntrospection.serialize(node, data, indent + 1);
-					}
-				}
-				Tools.addIndent(data, indent);
-			}
-			data.append("\n");
-		} else {
-			data.append("/>\n");
-		}
-	}
-	
-	public static void serializeRoot(final XmlElement root, final StringBuilder data) {
-		for (int iii = 0; iii < root.getNodes().size(); iii++) {
-			final XmlNode node = root.getNodes().get(iii);
-			SerializerXmlIntrospection.serialize(node, data, 0);
-		}
-		
-	}
-	
-	private static void serializeText(final XmlText text, final StringBuilder data, final int indent) {
-		data.append(Tools.replaceSpecialCharOut(text.getValue()));
-	}
-	
-	private final Generator generator;
-	
-	public SerializerXmlIntrospection(final Generator generator) {
-		this.generator = generator;
-	}
-	
-	public void generate(final Object root, final ParsingProperty property, final StringBuilder tmpp) {
-		//property.append(Tools.replaceSpecialCharOut(root.getValue()));
-		
-	}
-}
diff --git a/test/src/test/atriasoft/exml/ExmlLocal.java b/test/src/test/atriasoft/exml/generic/ExmlLocal.java
similarity index 95%
rename from test/src/test/atriasoft/exml/ExmlLocal.java
rename to test/src/test/atriasoft/exml/generic/ExmlLocal.java
index b0259f5..ec4043c 100644
--- a/test/src/test/atriasoft/exml/ExmlLocal.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlLocal.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.aknot.exception.AknotException;
 import org.atriasoft.exml.Exml;
@@ -11,6 +11,8 @@ import org.atriasoft.exml.exception.ExmlException;
 import org.atriasoft.exml.model.XmlNode;
 import org.junit.jupiter.api.Assertions;
 
+import test.atriasoft.exml.internal.Log;
+
 class ExmlLocal {
 	// errorPos : -1 : no error , 1 : parsing error, 2 generation error, 3 comparaison error ????
 	public static void test(final String ref, final String input, final int errorPos) {
diff --git a/test/src/test/atriasoft/exml/ExmlTestAll.java b/test/src/test/atriasoft/exml/generic/ExmlTestAll.java
similarity index 96%
rename from test/src/test/atriasoft/exml/ExmlTestAll.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestAll.java
index ef199a6..0a72838 100644
--- a/test/src/test/atriasoft/exml/ExmlTestAll.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestAll.java
@@ -3,11 +3,13 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestAll {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestAttribute.java b/test/src/test/atriasoft/exml/generic/ExmlTestAttribute.java
similarity index 98%
rename from test/src/test/atriasoft/exml/ExmlTestAttribute.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestAttribute.java
index 80a2344..cdb7c75 100644
--- a/test/src/test/atriasoft/exml/ExmlTestAttribute.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestAttribute.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.exml.Exml;
 import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestAttribute {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestCData.java b/test/src/test/atriasoft/exml/generic/ExmlTestCData.java
similarity index 91%
rename from test/src/test/atriasoft/exml/ExmlTestCData.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestCData.java
index 384edb1..afb53e5 100644
--- a/test/src/test/atriasoft/exml/ExmlTestCData.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestCData.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.exml.Exml;
 import org.atriasoft.exml.model.XmlElement;
@@ -11,6 +11,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestCData {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestComment.java b/test/src/test/atriasoft/exml/generic/ExmlTestComment.java
similarity index 94%
rename from test/src/test/atriasoft/exml/ExmlTestComment.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestComment.java
index 920eb80..f403b2b 100644
--- a/test/src/test/atriasoft/exml/ExmlTestComment.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestComment.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.exml.model.XmlComment;
 import org.atriasoft.exml.model.XmlNode;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestComment {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestDeclarationXML.java b/test/src/test/atriasoft/exml/generic/ExmlTestDeclarationXML.java
similarity index 97%
rename from test/src/test/atriasoft/exml/ExmlTestDeclarationXML.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestDeclarationXML.java
index 6147e5b..7e6eb58 100644
--- a/test/src/test/atriasoft/exml/ExmlTestDeclarationXML.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestDeclarationXML.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.exml.exception.ExmlAttributeDoesNotExist;
 import org.atriasoft.exml.model.XmlDeclaration;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestDeclarationXML {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestElement.java b/test/src/test/atriasoft/exml/generic/ExmlTestElement.java
similarity index 97%
rename from test/src/test/atriasoft/exml/ExmlTestElement.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestElement.java
index e72ad8f..517cb33 100644
--- a/test/src/test/atriasoft/exml/ExmlTestElement.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestElement.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.atriasoft.exml.Exml;
 import org.atriasoft.exml.exception.ExmlNodeDoesNotExist;
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestElement {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestParseAttribute.java b/test/src/test/atriasoft/exml/generic/ExmlTestParseAttribute.java
similarity index 96%
rename from test/src/test/atriasoft/exml/ExmlTestParseAttribute.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestParseAttribute.java
index f9d5dac..30002c7 100644
--- a/test/src/test/atriasoft/exml/ExmlTestParseAttribute.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestParseAttribute.java
@@ -3,11 +3,13 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestParseAttribute {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestParseComment.java b/test/src/test/atriasoft/exml/generic/ExmlTestParseComment.java
similarity index 94%
rename from test/src/test/atriasoft/exml/ExmlTestParseComment.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestParseComment.java
index b205dec..e204571 100644
--- a/test/src/test/atriasoft/exml/ExmlTestParseComment.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestParseComment.java
@@ -3,11 +3,13 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestParseComment {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestParseDeclaration.java b/test/src/test/atriasoft/exml/generic/ExmlTestParseDeclaration.java
similarity index 94%
rename from test/src/test/atriasoft/exml/ExmlTestParseDeclaration.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestParseDeclaration.java
index f81f906..906c741 100644
--- a/test/src/test/atriasoft/exml/ExmlTestParseDeclaration.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestParseDeclaration.java
@@ -3,11 +3,13 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestParseDeclaration {
 	@BeforeAll
 	public static void beforeClass() {
diff --git a/test/src/test/atriasoft/exml/ExmlTestParseElement.java b/test/src/test/atriasoft/exml/generic/ExmlTestParseElement.java
similarity index 95%
rename from test/src/test/atriasoft/exml/ExmlTestParseElement.java
rename to test/src/test/atriasoft/exml/generic/ExmlTestParseElement.java
index 2c90f2e..6937134 100644
--- a/test/src/test/atriasoft/exml/ExmlTestParseElement.java
+++ b/test/src/test/atriasoft/exml/generic/ExmlTestParseElement.java
@@ -3,11 +3,13 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.generic;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestParseElement {
 	static String refOutputElement = "";
 	
diff --git a/test/src/test/atriasoft/exml/Log.java b/test/src/test/atriasoft/exml/internal/Log.java
similarity index 98%
rename from test/src/test/atriasoft/exml/Log.java
rename to test/src/test/atriasoft/exml/internal/Log.java
index c282476..1e81564 100644
--- a/test/src/test/atriasoft/exml/Log.java
+++ b/test/src/test/atriasoft/exml/internal/Log.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.internal;
 
 import io.scenarium.logger.LogLevel;
 import io.scenarium.logger.Logger;
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospection.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospection.java
similarity index 97%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospection.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospection.java
index 9e44f15..9df6a79 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospection.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospection.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.Arrays;
 
@@ -14,12 +14,13 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import test.atriasoft.exml.introspection.ClassMethodEnum;
-import test.atriasoft.exml.introspection.ClassPublicMemberOnly;
-import test.atriasoft.exml.introspection.ClassPublicMethodOnly;
-import test.atriasoft.exml.introspection.ClassPublicMethodeNode;
-import test.atriasoft.exml.introspection.ClassPublicMethodeStructured;
-import test.atriasoft.exml.introspection.SimpleEnum;
+import test.atriasoft.exml.internal.Log;
+import test.atriasoft.exml.introspection.model.ClassMethodEnum;
+import test.atriasoft.exml.introspection.model.ClassPublicMemberOnly;
+import test.atriasoft.exml.introspection.model.ClassPublicMethodOnly;
+import test.atriasoft.exml.introspection.model.ClassPublicMethodeNode;
+import test.atriasoft.exml.introspection.model.ClassPublicMethodeStructured;
+import test.atriasoft.exml.introspection.model.SimpleEnum;
 
 public class ExmlTestIntrospection {
 	@BeforeAll
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionBoolean.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBoolean.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionBoolean.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBoolean.java
index e1b873f..88d9647 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionBoolean.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBoolean.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionBoolean {
 	@AknotDefaultAttribute
 	public class TestArrayBoolean {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionBooleanNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBooleanNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionBooleanNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBooleanNative.java
index 7b4f947..efafa47 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionBooleanNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionBooleanNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionBooleanNative {
 	@AknotDefaultAttribute
 	public class TestArrayBooleanFunc {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionByte.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByte.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionByte.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByte.java
index a51a2de..613ad2a 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionByte.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByte.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionByte {
 	@AknotDefaultAttribute
 	public class TestArrayByte {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionByteNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByteNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionByteNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByteNative.java
index 132fbee..1dbd60d 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionByteNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionByteNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionByteNative {
 	@AknotDefaultAttribute
 	public class TestArrayByteFunc {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorAttribute.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorAttribute.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorAttribute.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorAttribute.java
index d4a6939..f90705e 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorAttribute.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorAttribute.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotAttribute;
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDecoratorAttribute {
 	@AknotDefaultAttribute
 	public class TestNodeObject {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorCaseSensitive.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorCaseSensitive.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorCaseSensitive.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorCaseSensitive.java
index a45f148..baf83ca 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorCaseSensitive.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorCaseSensitive.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotCaseSensitive;
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
@@ -16,6 +16,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDecoratorCaseSensitive {
 	@AknotDefaultCaseSensitive
 	@AknotDefaultAttribute
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorManaged.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorManaged.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorManaged.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorManaged.java
index 5bd3376..125e063 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorManaged.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorManaged.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultManaged;
 import org.atriasoft.aknot.annotation.AknotManaged;
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDecoratorManaged {
 	@AknotDefaultManaged
 	public class TestNodeObject {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorNames.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorNames.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorNames.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorNames.java
index dc70532..68b2e39 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorNames.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorNames.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotAttribute;
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDecoratorNames {
 	public class ChangingNames {
 		private String value1RataPlouf;
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorOptionnal.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorOptionnal.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorOptionnal.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorOptionnal.java
index 2a6a596..206f259 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDecoratorOptionnal.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDecoratorOptionnal.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultOptional;
 import org.atriasoft.aknot.annotation.AknotName;
@@ -13,6 +13,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDecoratorOptionnal {
 	@AknotDefaultOptional
 	public class TestNodeObject {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDouble.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDouble.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDouble.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDouble.java
index 358e5b7..c88f9ee 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDouble.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDouble.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDouble {
 	@AknotDefaultAttribute
 	public class TestArrayDouble {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDoubleNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDoubleNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionDoubleNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDoubleNative.java
index 8ee1d3b..08d3326 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionDoubleNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionDoubleNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionDoubleNative {
 	@AknotDefaultAttribute
 	public class TestArrayDoubleFunc {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionEnum.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionEnum.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionEnum.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionEnum.java
index faad5d6..c65ed1d 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionEnum.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionEnum.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionEnum {
 	@AknotDefaultAttribute
 	public class TestArrayEnum {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionFloat.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloat.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionFloat.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloat.java
index 66b5625..a47c25c 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionFloat.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloat.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionFloat {
 	@AknotDefaultAttribute
 	public class TestArrayFloat {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionFloatNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloatNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionFloatNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloatNative.java
index fe80e22..f7723b2 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionFloatNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionFloatNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionFloatNative {
 	@AknotDefaultAttribute
 	public class TestArrayFloatFunc {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionGenerate.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionGenerate.java
similarity index 94%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionGenerate.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionGenerate.java
index ea660d5..9c2c2be 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionGenerate.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionGenerate.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.exml.XmlMapper;
 import org.atriasoft.exml.exception.ExmlException;
@@ -12,9 +12,10 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import test.atriasoft.exml.introspection.ClassPublicMemberOnly;
-import test.atriasoft.exml.introspection.ClassPublicMethodOnly;
-import test.atriasoft.exml.introspection.ClassPublicMethodeNode;
+import test.atriasoft.exml.internal.Log;
+import test.atriasoft.exml.introspection.model.ClassPublicMemberOnly;
+import test.atriasoft.exml.introspection.model.ClassPublicMethodOnly;
+import test.atriasoft.exml.introspection.model.ClassPublicMethodeNode;
 
 public class ExmlTestIntrospectionGenerate {
 	private static final String NODE_NAME = "elem";
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionInteger.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionInteger.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionInteger.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionInteger.java
index cf575c0..ee95e4a 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionInteger.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionInteger.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionInteger {
 	@AknotDefaultAttribute
 	public class TestArrayInteger {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionIntegerNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionIntegerNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionIntegerNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionIntegerNative.java
index a3189e7..4c32619 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionIntegerNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionIntegerNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionIntegerNative {
 	@AknotDefaultAttribute
 	public class TestArrayIntegerFunc {
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionObject.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObject.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionObject.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObject.java
index eddfe79..d9ca61c 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionObject.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObject.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionObject {
 	public class SimpleObject {
 		@AknotAttribute
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionObjectConstructor.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObjectConstructor.java
similarity index 97%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionObjectConstructor.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObjectConstructor.java
index 7aa4277..c7d25a9 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionObjectConstructor.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionObjectConstructor.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotAttribute;
 import org.atriasoft.aknot.annotation.AknotName;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionObjectConstructor {
 	public class TestConstructorSpecific {
 		@AknotAttribute
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionRecord.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionRecord.java
similarity index 96%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionRecord.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionRecord.java
index a5cf40f..fe64696 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionRecord.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionRecord.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotAttribute;
 import org.atriasoft.aknot.annotation.AknotName;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionRecord {
 	public record TestRecord(
 			@AknotName("valueA") Integer valueA,
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionShort.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShort.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionShort.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShort.java
index 3c4429c..01d425c 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionShort.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShort.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import java.util.List;
 
@@ -14,6 +14,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionShort {
 	public class TestArrayNodeShort {
 		public Short[] values;
diff --git a/test/src/test/atriasoft/exml/ExmlTestIntrospectionShortNative.java b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShortNative.java
similarity index 99%
rename from test/src/test/atriasoft/exml/ExmlTestIntrospectionShortNative.java
rename to test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShortNative.java
index f7c3f07..7fa42be 100644
--- a/test/src/test/atriasoft/exml/ExmlTestIntrospectionShortNative.java
+++ b/test/src/test/atriasoft/exml/introspection/ExmlTestIntrospectionShortNative.java
@@ -3,7 +3,7 @@
  * @copyright 2021, Edouard DUPIN, all right reserved
  * @license MPL v2.0 (see license file)
  */
-package test.atriasoft.exml;
+package test.atriasoft.exml.introspection;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotList;
@@ -12,6 +12,8 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
+import test.atriasoft.exml.internal.Log;
+
 public class ExmlTestIntrospectionShortNative {
 	public class TestArrayNodeShortFunc {
 		private short[] values;
diff --git a/test/src/test/atriasoft/exml/introspection/ClassInversion.java b/test/src/test/atriasoft/exml/introspection/model/ClassInversion.java
similarity index 72%
rename from test/src/test/atriasoft/exml/introspection/ClassInversion.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassInversion.java
index fe0cd28..9f0895d 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassInversion.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassInversion.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import org.atriasoft.aknot.annotation.AknotDefaultManaged;
 
diff --git a/test/src/test/atriasoft/exml/introspection/ClassMethodEnum.java b/test/src/test/atriasoft/exml/introspection/model/ClassMethodEnum.java
similarity index 84%
rename from test/src/test/atriasoft/exml/introspection/ClassMethodEnum.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassMethodEnum.java
index 5d121ec..f0c33ba 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassMethodEnum.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassMethodEnum.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import org.atriasoft.aknot.annotation.AknotName;
 
diff --git a/test/src/test/atriasoft/exml/introspection/ClassPublicMemberOnly.java b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMemberOnly.java
similarity index 95%
rename from test/src/test/atriasoft/exml/introspection/ClassPublicMemberOnly.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassPublicMemberOnly.java
index 401be30..720efc9 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassPublicMemberOnly.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMemberOnly.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotName;
diff --git a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodOnly.java b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodOnly.java
similarity index 99%
rename from test/src/test/atriasoft/exml/introspection/ClassPublicMethodOnly.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodOnly.java
index ae792ba..a790b7c 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodOnly.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodOnly.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import org.atriasoft.aknot.annotation.AknotDefaultAttribute;
 import org.atriasoft.aknot.annotation.AknotName;
diff --git a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodeNode.java b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeNode.java
similarity index 99%
rename from test/src/test/atriasoft/exml/introspection/ClassPublicMethodeNode.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeNode.java
index fd8f626..aba067a 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodeNode.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeNode.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import java.util.List;
 
diff --git a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodeStructured.java b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeStructured.java
similarity index 94%
rename from test/src/test/atriasoft/exml/introspection/ClassPublicMethodeStructured.java
rename to test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeStructured.java
index c7d2445..71162dc 100644
--- a/test/src/test/atriasoft/exml/introspection/ClassPublicMethodeStructured.java
+++ b/test/src/test/atriasoft/exml/introspection/model/ClassPublicMethodeStructured.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 import java.util.List;
 
diff --git a/test/src/test/atriasoft/exml/introspection/SimpleEnum.java b/test/src/test/atriasoft/exml/introspection/model/SimpleEnum.java
similarity index 50%
rename from test/src/test/atriasoft/exml/introspection/SimpleEnum.java
rename to test/src/test/atriasoft/exml/introspection/model/SimpleEnum.java
index fab5025..1abc713 100644
--- a/test/src/test/atriasoft/exml/introspection/SimpleEnum.java
+++ b/test/src/test/atriasoft/exml/introspection/model/SimpleEnum.java
@@ -1,4 +1,4 @@
-package test.atriasoft.exml.introspection;
+package test.atriasoft.exml.introspection.model;
 
 public enum SimpleEnum {
 	PLIF,