[DIRECTMEMORY-102] Lightning Serializer Contribution
Submitted by Christoph Engelbert.
Patch submitted as provided. some changes later :-)



git-svn-id: https://svn.apache.org/repos/asf/directmemory/lightning/trunk@1392595 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lightning-api/pom.xml b/lightning-api/pom.xml
new file mode 100644
index 0000000..58134d7
--- /dev/null
+++ b/lightning-api/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-api</artifactId>
+  <name>Lightning: API</name>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.carrotsearch</groupId>
+      <artifactId>hppc</artifactId>
+      <version>0.4.1</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/ClassComparisonStrategy.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/ClassComparisonStrategy.java
new file mode 100644
index 0000000..1268095
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/ClassComparisonStrategy.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+/**
+ * Defines the comparison strategy of classes between different serializers. The standard strategy of Java is
+ * SerialVersionUID but Lightning has some lighter algorithm which only takes properties into account.
+ */
+public enum ClassComparisonStrategy
+{
+
+    /**
+     * Default Java Serialization like SerialVersionUID
+     */
+    SerialVersionUID,
+
+    /**
+     * Lightning checksum calculation
+     */
+    LightningChecksum,
+
+    /**
+     * Instructs Lightning to skip all kinds of comparison between the different ClassDefinitionContainers. This is not
+     * recommended but is required for possible schema evolution features.
+     */
+    SkipComparison
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/Marshaller.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/Marshaller.java
new file mode 100644
index 0000000..03a56e8
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/Marshaller.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public interface Marshaller
+{
+
+    boolean acceptType( Class<?> type );
+
+    void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                   SerializationContext serializationContext )
+        throws IOException;
+
+    <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                      SerializationContext serializationContext )
+        throws IOException;
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerContext.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerContext.java
new file mode 100644
index 0000000..39944dc
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerContext.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.lang.reflect.Type;
+
+public interface MarshallerContext
+{
+
+    Marshaller getMarshaller( Type type );
+
+    void bindMarshaller( Type type, Marshaller marshaller );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerStrategy.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerStrategy.java
new file mode 100644
index 0000000..79dfd75
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/MarshallerStrategy.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.lang.reflect.Type;
+
+public interface MarshallerStrategy
+{
+
+    Marshaller getMarshaller( Type type, MarshallerContext marshallerContext );
+
+    Marshaller getMarshaller( Type type, MarshallerContext marshallerContext, boolean baseMarshallersOnly );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationContext.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationContext.java
new file mode 100644
index 0000000..8a83e26
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationContext.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.lang.reflect.Type;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+public interface SerializationContext
+{
+
+    ClassDefinitionContainer getClassDefinitionContainer();
+
+    SerializationStrategy getSerializationStrategy();
+
+    ObjectInstantiatorFactory getObjectInstantiatorFactory();
+
+    Marshaller findMarshaller( Type type );
+
+    ValueNullableEvaluator getValueNullableEvaluator();
+
+    long findReferenceIdByObject( Object instance );
+
+    Object findObjectByReferenceId( long referenceId );
+
+    boolean containsReferenceId( long referenceId );
+
+    long putMarshalledInstance( Object instance );
+
+    long putUnmarshalledInstance( long refrenceId, Object instance );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationStrategy.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationStrategy.java
new file mode 100644
index 0000000..6fc9b20
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/SerializationStrategy.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+public enum SerializationStrategy
+{
+
+    /**
+     * This strategy does not force same instances to become same instances on deserialization since only values are
+     * written to the stream.<br>
+     * To be clear, deserialized instances of same objects are non identity-equal!
+     */
+    SpeedOptimized,
+
+    /**
+     * This strategy forces same instances to become same instances on deserialization. This needs to collect instances
+     * by hashCode on both sides while serialization and deserialization, which in case needs time.<br>
+     * To be clear, deserialized instances of same objects are identity-equal!
+     */
+    SizeOptimized
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/Serializer.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/Serializer.java
new file mode 100644
index 0000000..0826c3d
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/Serializer.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+
+public interface Serializer
+{
+
+    ClassDefinitionContainer getClassDefinitionContainer();
+
+    void setClassDefinitionContainer( ClassDefinitionContainer classDefinitionContainer );
+
+    <V> void serialize( V value, DataOutput dataOutput );
+
+    <V> void serialize( V value, OutputStream outputStream );
+
+    <V> void serialize( V value, Writer writer );
+
+    <V> void serialize( V value, ByteBuffer buffer );
+
+    <V> V deserialize( DataInput dataInput );
+
+    <V> V deserialize( InputStream inputStream );
+
+    <V> V deserialize( Reader reader );
+
+    <V> V deserialize( ByteBuffer buffer );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/Streamed.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/Streamed.java
new file mode 100644
index 0000000..18ce20f
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/Streamed.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public interface Streamed
+{
+
+    void writeTo( DataOutput dataOutput )
+        throws IOException;
+
+    void readFrom( DataInput dataInput )
+        throws IOException;
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/TypeBindableMarshaller.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/TypeBindableMarshaller.java
new file mode 100644
index 0000000..31a730d
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/TypeBindableMarshaller.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.lang.reflect.Type;
+
+public interface TypeBindableMarshaller
+{
+
+    Marshaller bindType( Type... bindingTypes );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/SerializerDefinition.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/SerializerDefinition.java
new file mode 100644
index 0000000..2e840f5
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/SerializerDefinition.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.configuration;
+
+import org.apache.directmemory.lightning.generator.DefinitionBuildingContext;
+import org.apache.directmemory.lightning.generator.DefinitionVisitor;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+
+public interface SerializerDefinition
+{
+
+    void configure( DefinitionBuildingContext definitionBuildingContext, ObjectInstantiatorFactory instantiator );
+
+    void acceptVisitor( DefinitionVisitor visitor );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/TypeIntrospector.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/TypeIntrospector.java
new file mode 100644
index 0000000..389964d
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/configuration/TypeIntrospector.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.configuration;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public interface TypeIntrospector
+{
+
+    List<PropertyDescriptor> introspect( Type type, MarshallerStrategy marshallerStrategy,
+                                         MarshallerContext marshallerContext,
+                                         PropertyDescriptorFactory propertyDescriptorFactory );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/ClassDefinitionInconsistentException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/ClassDefinitionInconsistentException.java
new file mode 100644
index 0000000..f9a7970
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/ClassDefinitionInconsistentException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class ClassDefinitionInconsistentException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -1585228404035281265L;
+
+    public ClassDefinitionInconsistentException()
+    {
+        super();
+    }
+
+    public ClassDefinitionInconsistentException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public ClassDefinitionInconsistentException( String message )
+    {
+        super( message );
+    }
+
+    public ClassDefinitionInconsistentException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalAccessorException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalAccessorException.java
new file mode 100644
index 0000000..b1202d4
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalAccessorException.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class IllegalAccessorException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = 4787626329337667393L;
+
+    public IllegalAccessorException()
+    {
+        super();
+    }
+
+    public IllegalAccessorException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public IllegalAccessorException( String message )
+    {
+        super( message );
+    }
+
+    public IllegalAccessorException( Throwable cause )
+    {
+        super( cause );
+    }
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalPropertyAccessException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalPropertyAccessException.java
new file mode 100644
index 0000000..2590bec
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/IllegalPropertyAccessException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class IllegalPropertyAccessException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = 967346776852344538L;
+
+    public IllegalPropertyAccessException()
+    {
+        super();
+    }
+
+    public IllegalPropertyAccessException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public IllegalPropertyAccessException( String message )
+    {
+        super( message );
+    }
+
+    public IllegalPropertyAccessException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerDefinitionException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerDefinitionException.java
new file mode 100644
index 0000000..1c057f3
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerDefinitionException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class SerializerDefinitionException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -5334852575035142159L;
+
+    public SerializerDefinitionException()
+    {
+        super();
+    }
+
+    public SerializerDefinitionException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public SerializerDefinitionException( String message )
+    {
+        super( message );
+    }
+
+    public SerializerDefinitionException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerExecutionException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerExecutionException.java
new file mode 100644
index 0000000..4988cdf
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerExecutionException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class SerializerExecutionException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = 6304044942065057900L;
+
+    public SerializerExecutionException()
+    {
+        super();
+    }
+
+    public SerializerExecutionException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public SerializerExecutionException( String message )
+    {
+        super( message );
+    }
+
+    public SerializerExecutionException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerMarshallerGeneratorException.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerMarshallerGeneratorException.java
new file mode 100644
index 0000000..e95c42e
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/exceptions/SerializerMarshallerGeneratorException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.exceptions;
+
+public class SerializerMarshallerGeneratorException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = 3794029259705664064L;
+
+    public SerializerMarshallerGeneratorException()
+    {
+        super();
+    }
+
+    public SerializerMarshallerGeneratorException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public SerializerMarshallerGeneratorException( String message )
+    {
+        super( message );
+    }
+
+    public SerializerMarshallerGeneratorException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionBuildingContext.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionBuildingContext.java
new file mode 100644
index 0000000..52f049f
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionBuildingContext.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.generator;
+
+import org.apache.directmemory.lightning.MarshallerStrategy;
+
+public interface DefinitionBuildingContext
+{
+
+    PropertyDescriptorFactory getPropertyDescriptorFactory();
+
+    MarshallerStrategy getMarshallerStrategy();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionVisitor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionVisitor.java
new file mode 100644
index 0000000..55ffcb4
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/DefinitionVisitor.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.generator;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public interface DefinitionVisitor
+{
+
+    void visitSerializerDefinition( SerializerDefinition serializerDefinition );
+
+    void visitAttributeAnnotation( Class<? extends Annotation> attributeAnnotation );
+
+    void visitClassDefine( Type type, Marshaller marshaller );
+
+    void visitAnnotatedAttribute( PropertyDescriptor propertyDescriptor, Marshaller marshaller );
+
+    void visitPropertyDescriptor( PropertyDescriptor propertyDescriptor, Marshaller marshaller );
+
+    void visitFinalizeSerializerDefinition( SerializerDefinition serializerDefinition );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/PropertyDescriptorFactory.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/PropertyDescriptorFactory.java
new file mode 100644
index 0000000..335b574
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/generator/PropertyDescriptorFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.generator;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public interface PropertyDescriptorFactory
+{
+
+    PropertyDescriptor byMethod( Method method, Marshaller marshaller, Class<?> definedClass );
+
+    PropertyDescriptor byField( Field field, Marshaller marshaller, Class<?> definedClass );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiator.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiator.java
new file mode 100644
index 0000000..a922ba3
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiator.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.instantiator;
+
+/**
+ * Instantiates a new object.
+ * 
+ * @author Leonardo Mesquita
+ */
+public interface ObjectInstantiator
+{
+
+    /**
+     * Returns a new instance of an object. The returned object's class is defined by the implementation.
+     * 
+     * @return A new instance of an object.
+     */
+    Object newInstance();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiatorFactory.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiatorFactory.java
new file mode 100644
index 0000000..3f64694
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/instantiator/ObjectInstantiatorFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.instantiator;
+
+/**
+ * Common interface to all kind of Objenesis objects
+ * 
+ * @author Henri Tremblay
+ */
+public interface ObjectInstantiatorFactory
+{
+
+    /**
+     * Will create a new object without any constructor being called
+     * 
+     * @param clazz Class to instantiate
+     * @return New instance of clazz
+     */
+    Object newInstance( Class<?> clazz );
+
+    /**
+     * Will pick the best instantiator for the provided class. If you need to create a lot of instances from the same
+     * class, it is way more efficient to create them from the same ObjectInstantiator than calling
+     * {@link #newInstance(Class)}.
+     * 
+     * @param clazz Class to instantiate
+     * @return Instantiator dedicated to the class
+     */
+    ObjectInstantiator getInstantiatorOf( Class<?> clazz );
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerInputStream.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerInputStream.java
new file mode 100644
index 0000000..35e0133
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerInputStream.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.io;
+
+import java.io.DataInput;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInput;
+import java.io.PushbackInputStream;
+import java.io.UTFDataFormatException;
+
+import org.apache.directmemory.lightning.Serializer;
+
+/**
+ * Parts of this class taken from Hazelcast project
+ */
+public class SerializerInputStream
+    extends FilterInputStream
+    implements ObjectInput
+{
+
+    private final Serializer serializer;
+
+    private final byte[] longReadBuffer = new byte[8];
+
+    private char lineBuffer[];
+
+    public SerializerInputStream( InputStream in, Serializer serializer )
+    {
+        super( in );
+        this.serializer = serializer;
+    }
+
+    @Override
+    public Object readObject()
+    {
+        return serializer.deserialize( (DataInput) this );
+    }
+
+    @Override
+    public void readFully( byte[] b )
+        throws IOException
+    {
+        in.read( b );
+    }
+
+    @Override
+    public void readFully( byte[] b, int off, int len )
+        throws IOException
+    {
+        in.read( b, off, len );
+    }
+
+    @Override
+    public int skipBytes( int n )
+        throws IOException
+    {
+        return (int) in.skip( n );
+    }
+
+    @Override
+    public boolean readBoolean()
+        throws IOException
+    {
+        return in.read() == 1;
+    }
+
+    @Override
+    public byte readByte()
+        throws IOException
+    {
+        return (byte) in.read();
+    }
+
+    @Override
+    public int readUnsignedByte()
+        throws IOException
+    {
+        return in.read();
+    }
+
+    @Override
+    public short readShort()
+        throws IOException
+    {
+        int byte1 = read();
+        int byte2 = read();
+        return (short) ( ( byte1 << 8 ) + ( byte2 << 0 ) );
+    }
+
+    @Override
+    public int readUnsignedShort()
+        throws IOException
+    {
+        int byte1 = read();
+        int byte2 = read();
+        return (short) ( ( byte1 << 8 ) + ( byte2 << 0 ) );
+    }
+
+    @Override
+    public char readChar()
+        throws IOException
+    {
+        return (char) readUnsignedShort();
+    }
+
+    @Override
+    public int readInt()
+        throws IOException
+    {
+        final int byte1 = read();
+        final int byte2 = read();
+        final int byte3 = read();
+        final int byte4 = read();
+        return ( ( byte1 << 24 ) + ( byte2 << 16 ) + ( byte3 << 8 ) + ( byte4 << 0 ) );
+    }
+
+    @Override
+    public long readLong()
+        throws IOException
+    {
+        in.read( longReadBuffer );
+        return ( ( (long) longReadBuffer[0] << 56 ) + ( (long) ( longReadBuffer[1] & 255 ) << 48 )
+            + ( (long) ( longReadBuffer[2] & 255 ) << 40 ) + ( (long) ( longReadBuffer[3] & 255 ) << 32 )
+            + ( (long) ( longReadBuffer[4] & 255 ) << 24 ) + ( ( longReadBuffer[5] & 255 ) << 16 )
+            + ( ( longReadBuffer[6] & 255 ) << 8 ) + ( ( longReadBuffer[7] & 255 ) << 0 ) );
+    }
+
+    @Override
+    public float readFloat()
+        throws IOException
+    {
+        return Float.intBitsToFloat( readInt() );
+    }
+
+    @Override
+    public double readDouble()
+        throws IOException
+    {
+        return Double.longBitsToDouble( readLong() );
+    }
+
+    @Override
+    public String readLine()
+        throws IOException
+    {
+        char buf[] = lineBuffer;
+        if ( buf == null )
+        {
+            buf = lineBuffer = new char[128];
+        }
+        int room = buf.length;
+        int offset = 0;
+        int c;
+        loop: while ( true )
+        {
+            switch ( c = read() )
+            {
+                case -1:
+                case '\n':
+                    break loop;
+                case '\r':
+                    final int c2 = read();
+                    if ( ( c2 != '\n' ) && ( c2 != -1 ) )
+                    {
+                        new PushbackInputStream( this ).unread( c2 );
+                    }
+                    break loop;
+                default:
+                    if ( --room < 0 )
+                    {
+                        buf = new char[offset + 128];
+                        room = buf.length - offset - 1;
+                        System.arraycopy( lineBuffer, 0, buf, 0, offset );
+                        lineBuffer = buf;
+                    }
+                    buf[offset++] = (char) c;
+                    break;
+            }
+        }
+        if ( ( c == -1 ) && ( offset == 0 ) )
+        {
+            return null;
+        }
+        return String.copyValueOf( buf, 0, offset );
+
+    }
+
+    @Override
+    public String readUTF()
+        throws IOException
+    {
+        boolean isNull = readBoolean();
+        if ( isNull )
+            return null;
+        int length = readInt();
+        StringBuilder result = new StringBuilder( length );
+        int chunkSize = length / SerializerOutputStream.STRING_CHUNK_SIZE + 1;
+        while ( chunkSize > 0 )
+        {
+            result.append( readShortUTF() );
+            chunkSize--;
+        }
+        return result.toString();
+    }
+
+    private final String readShortUTF()
+        throws IOException
+    {
+        final int utflen = readShort();
+        byte[] bytearr = null;
+        char[] chararr = null;
+        bytearr = new byte[utflen];
+        chararr = new char[utflen];
+        int c, char2, char3;
+        int count = 0;
+        int chararr_count = 0;
+        readFully( bytearr, 0, utflen );
+        while ( count < utflen )
+        {
+            c = bytearr[count] & 0xff;
+            if ( c > 127 )
+                break;
+            count++;
+            chararr[chararr_count++] = (char) c;
+        }
+        while ( count < utflen )
+        {
+            c = bytearr[count] & 0xff;
+            switch ( c >> 4 )
+            {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                case 5:
+                case 6:
+                case 7:
+                    /* 0xxxxxxx */
+                    count++;
+                    chararr[chararr_count++] = (char) c;
+                    break;
+                case 12:
+                case 13:
+                    /* 110x xxxx 10xx xxxx */
+                    count += 2;
+                    if ( count > utflen )
+                        throw new UTFDataFormatException( "malformed input: partial character at end" );
+                    char2 = bytearr[count - 1];
+                    if ( ( char2 & 0xC0 ) != 0x80 )
+                        throw new UTFDataFormatException( "malformed input around byte " + count );
+                    chararr[chararr_count++] = (char) ( ( ( c & 0x1F ) << 6 ) | ( char2 & 0x3F ) );
+                    break;
+                case 14:
+                    /* 1110 xxxx 10xx xxxx 10xx xxxx */
+                    count += 3;
+                    if ( count > utflen )
+                        throw new UTFDataFormatException( "malformed input: partial character at end" );
+                    char2 = bytearr[count - 2];
+                    char3 = bytearr[count - 1];
+                    if ( ( ( char2 & 0xC0 ) != 0x80 ) || ( ( char3 & 0xC0 ) != 0x80 ) )
+                        throw new UTFDataFormatException( "malformed input around byte " + ( count - 1 ) );
+                    chararr[chararr_count++] =
+                        (char) ( ( ( c & 0x0F ) << 12 ) | ( ( char2 & 0x3F ) << 6 ) | ( ( char3 & 0x3F ) << 0 ) );
+                    break;
+                default:
+                    /* 10xx xxxx, 1111 xxxx */
+                    throw new UTFDataFormatException( "malformed input around byte " + count );
+            }
+        }
+        // The number of chars produced may be less than utflen
+        return new String( chararr, 0, chararr_count );
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerOutputStream.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerOutputStream.java
new file mode 100644
index 0000000..14eabc1
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/io/SerializerOutputStream.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.io;
+
+import java.io.DataOutput;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+
+import org.apache.directmemory.lightning.Serializer;
+
+/**
+ * Parts of this class taken from Hazelcast project
+ */
+public class SerializerOutputStream
+    extends FilterOutputStream
+    implements ObjectOutput
+{
+
+    static final int STRING_CHUNK_SIZE = 16 * 1024;
+
+    private final Serializer serializer;
+
+    private int written = 0;
+
+    public SerializerOutputStream( OutputStream out, Serializer serializer )
+    {
+        super( out );
+        this.serializer = serializer;
+    }
+
+    @Override
+    public void writeObject( Object object )
+    {
+        serializer.serialize( object, (DataOutput) this );
+    }
+
+    @Override
+    public synchronized void write( int b )
+        throws IOException
+    {
+        out.write( b );
+        increaseWritten( 1 );
+    }
+
+    @Override
+    public synchronized void write( byte[] b, int off, int len )
+        throws IOException
+    {
+        out.write( b, off, len );
+        increaseWritten( len );
+    }
+
+    @Override
+    public void writeBoolean( boolean v )
+        throws IOException
+    {
+        out.write( v ? 1 : 0 );
+    }
+
+    @Override
+    public void writeByte( int v )
+        throws IOException
+    {
+        out.write( v );
+        increaseWritten( 1 );
+    }
+
+    @Override
+    public void writeShort( int v )
+        throws IOException
+    {
+        out.write( ( v >>> 8 ) & 0xFF );
+        out.write( ( v >>> 0 ) & 0xFF );
+        increaseWritten( 2 );
+    }
+
+    @Override
+    public void writeChar( int v )
+        throws IOException
+    {
+        out.write( ( v >>> 8 ) & 0xFF );
+        out.write( ( v >>> 0 ) & 0xFF );
+        increaseWritten( 2 );
+    }
+
+    @Override
+    public void writeInt( int v )
+        throws IOException
+    {
+        out.write( ( v >>> 24 ) & 0xFF );
+        out.write( ( v >>> 16 ) & 0xFF );
+        out.write( ( v >>> 8 ) & 0xFF );
+        out.write( ( v >>> 0 ) & 0xFF );
+        increaseWritten( 4 );
+    }
+
+    @Override
+    public void writeLong( long v )
+        throws IOException
+    {
+        byte[] buffer = new byte[8];
+        buffer[0] = (byte) ( v >>> 56 );
+        buffer[1] = (byte) ( v >>> 48 );
+        buffer[2] = (byte) ( v >>> 40 );
+        buffer[3] = (byte) ( v >>> 32 );
+        buffer[4] = (byte) ( v >>> 24 );
+        buffer[5] = (byte) ( v >>> 16 );
+        buffer[6] = (byte) ( v >>> 8 );
+        buffer[7] = (byte) ( v >>> 0 );
+        out.write( buffer, 0, 8 );
+        increaseWritten( 8 );
+    }
+
+    @Override
+    public void writeFloat( float v )
+        throws IOException
+    {
+        writeInt( Float.floatToIntBits( v ) );
+    }
+
+    @Override
+    public void writeDouble( double v )
+        throws IOException
+    {
+        writeLong( Double.doubleToLongBits( v ) );
+    }
+
+    @Override
+    public void writeBytes( String s )
+        throws IOException
+    {
+        int len = s.length();
+        for ( int i = 0; i < len; i++ )
+        {
+            out.write( (byte) s.charAt( i ) );
+        }
+        increaseWritten( len );
+    }
+
+    @Override
+    public void writeChars( String s )
+        throws IOException
+    {
+        int len = s.length();
+        for ( int i = 0; i < len; i++ )
+        {
+            int v = s.charAt( i );
+            out.write( ( v >>> 8 ) & 0xFF );
+            out.write( ( v >>> 0 ) & 0xFF );
+        }
+        increaseWritten( len * 2 );
+    }
+
+    @Override
+    public void writeUTF( String s )
+        throws IOException
+    {
+        boolean isNull = ( s == null );
+        writeBoolean( isNull );
+        if ( isNull )
+            return;
+        int length = s.length();
+        writeInt( length );
+        int chunkSize = length / STRING_CHUNK_SIZE + 1;
+        for ( int i = 0; i < chunkSize; i++ )
+        {
+            int beginIndex = Math.max( 0, i * STRING_CHUNK_SIZE - 1 );
+            int endIndex = Math.min( ( i + 1 ) * STRING_CHUNK_SIZE - 1, length );
+            writeShortUTF( s.substring( beginIndex, endIndex ) );
+        }
+    }
+
+    private final void writeShortUTF( final String str )
+        throws IOException
+    {
+        final int strlen = str.length();
+        int utflen = 0;
+        int c, count = 0;
+        /* use charAt instead of copying String to char array */
+        for ( int i = 0; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( ( c >= 0x0001 ) && ( c <= 0x007F ) )
+            {
+                utflen++;
+            }
+            else if ( c > 0x07FF )
+            {
+                utflen += 3;
+            }
+            else
+            {
+                utflen += 2;
+            }
+        }
+        // if (utflen > 65535)
+        // throw new UTFDataFormatException("encoded string too long: " + utflen
+        // + " bytes");
+        final byte[] bytearr = new byte[utflen + 2];
+        bytearr[count++] = (byte) ( ( utflen >>> 8 ) & 0xFF );
+        bytearr[count++] = (byte) ( ( utflen ) & 0xFF );
+        int i;
+        for ( i = 0; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( !( ( c >= 0x0001 ) && ( c <= 0x007F ) ) )
+                break;
+            bytearr[count++] = (byte) c;
+        }
+        for ( ; i < strlen; i++ )
+        {
+            c = str.charAt( i );
+            if ( ( c >= 0x0001 ) && ( c <= 0x007F ) )
+            {
+                bytearr[count++] = (byte) c;
+            }
+            else if ( c > 0x07FF )
+            {
+                bytearr[count++] = (byte) ( 0xE0 | ( ( c >> 12 ) & 0x0F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c >> 6 ) & 0x3F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c ) & 0x3F ) );
+            }
+            else
+            {
+                bytearr[count++] = (byte) ( 0xC0 | ( ( c >> 6 ) & 0x1F ) );
+                bytearr[count++] = (byte) ( 0x80 | ( ( c ) & 0x3F ) );
+            }
+        }
+        write( bytearr, 0, utflen + 2 );
+    }
+
+    public int size()
+    {
+        return written;
+    }
+
+    private void increaseWritten( int count )
+    {
+        int temp = written + count;
+        if ( temp < 0 )
+        {
+            temp = Integer.MAX_VALUE;
+        }
+        written = temp;
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LogLevel.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LogLevel.java
new file mode 100644
index 0000000..bb8cc45
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LogLevel.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.logging;
+
+public enum LogLevel
+{
+
+    Trace, Debug, Info, Warn, Error, Fatal
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/Logger.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/Logger.java
new file mode 100644
index 0000000..9524ca1
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/Logger.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.logging;
+
+public interface Logger
+{
+
+    Logger getChildLogger( Class<?> clazz );
+
+    Logger getChildLogger( String name );
+
+    String getName();
+
+    boolean isLogLevelEnabled( LogLevel logLevel );
+
+    boolean isTraceEnabled();
+
+    boolean isDebugEnabled();
+
+    boolean isInfoEnabled();
+
+    boolean isWarnEnabled();
+
+    boolean isErrorEnabled();
+
+    boolean isFatalEnabled();
+
+    void trace( String message );
+
+    void trace( String message, Throwable throwable );
+
+    void debug( String message );
+
+    void debug( String message, Throwable throwable );
+
+    void info( String message );
+
+    void info( String message, Throwable throwable );
+
+    void warn( String message );
+
+    void warn( String message, Throwable throwable );
+
+    void error( String message );
+
+    void error( String message, Throwable throwable );
+
+    void fatal( String message );
+
+    void fatal( String message, Throwable throwable );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LoggerAdapter.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LoggerAdapter.java
new file mode 100644
index 0000000..fb58d78
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/logging/LoggerAdapter.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.logging;
+
+public class LoggerAdapter
+    implements Logger
+{
+
+    private final String name;
+
+    public LoggerAdapter()
+    {
+        this( "Default" );
+    }
+
+    public LoggerAdapter( Class<?> clazz )
+    {
+        this( clazz.getCanonicalName() );
+    }
+
+    public LoggerAdapter( String name )
+    {
+        this.name = name;
+    }
+
+    @Override
+    public Logger getChildLogger( Class<?> clazz )
+    {
+        return getChildLogger( clazz.getCanonicalName() );
+    }
+
+    @Override
+    public Logger getChildLogger( final String name )
+    {
+        final Logger that = this;
+        return new Logger()
+        {
+
+            @Override
+            public void warn( String message, Throwable throwable )
+            {
+                that.warn( message, throwable );
+            }
+
+            @Override
+            public void warn( String message )
+            {
+                that.warn( message );
+            }
+
+            @Override
+            public void trace( String message, Throwable throwable )
+            {
+                that.trace( message, throwable );
+            }
+
+            @Override
+            public void trace( String message )
+            {
+                that.trace( message );
+            }
+
+            @Override
+            public boolean isWarnEnabled()
+            {
+                return that.isWarnEnabled();
+            }
+
+            @Override
+            public boolean isTraceEnabled()
+            {
+                return that.isTraceEnabled();
+            }
+
+            @Override
+            public boolean isLogLevelEnabled( LogLevel logLevel )
+            {
+                return that.isLogLevelEnabled( logLevel );
+            }
+
+            @Override
+            public boolean isInfoEnabled()
+            {
+                return that.isInfoEnabled();
+            }
+
+            @Override
+            public boolean isFatalEnabled()
+            {
+                return that.isFatalEnabled();
+            }
+
+            @Override
+            public boolean isErrorEnabled()
+            {
+                return that.isErrorEnabled();
+            }
+
+            @Override
+            public boolean isDebugEnabled()
+            {
+                return that.isDebugEnabled();
+            }
+
+            @Override
+            public void info( String message, Throwable throwable )
+            {
+                that.info( message, throwable );
+            }
+
+            @Override
+            public void info( String message )
+            {
+                that.info( message );
+            }
+
+            @Override
+            public String getName()
+            {
+                return name;
+            }
+
+            @Override
+            public Logger getChildLogger( String name )
+            {
+                return that.getChildLogger( name );
+            }
+
+            @Override
+            public Logger getChildLogger( Class<?> clazz )
+            {
+                return getChildLogger( clazz.getCanonicalName() );
+            }
+
+            @Override
+            public void fatal( String message, Throwable throwable )
+            {
+                that.fatal( message, throwable );
+            }
+
+            @Override
+            public void fatal( String message )
+            {
+                that.fatal( message );
+            }
+
+            @Override
+            public void error( String message, Throwable throwable )
+            {
+                that.error( message, throwable );
+            }
+
+            @Override
+            public void error( String message )
+            {
+                that.error( message );
+            }
+
+            @Override
+            public void debug( String message, Throwable throwable )
+            {
+                that.debug( message, throwable );
+            }
+
+            @Override
+            public void debug( String message )
+            {
+                that.debug( message );
+            }
+        };
+    }
+
+    @Override
+    public String getName()
+    {
+        return name;
+    }
+
+    @Override
+    public boolean isLogLevelEnabled( LogLevel logLevel )
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isTraceEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isDebugEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isInfoEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isWarnEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isErrorEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public boolean isFatalEnabled()
+    {
+        return false;
+    }
+
+    @Override
+    public void trace( String message )
+    {
+    }
+
+    @Override
+    public void trace( String message, Throwable throwable )
+    {
+    }
+
+    @Override
+    public void debug( String message )
+    {
+    }
+
+    @Override
+    public void debug( String message, Throwable throwable )
+    {
+    }
+
+    @Override
+    public void info( String message )
+    {
+    }
+
+    @Override
+    public void info( String message, Throwable throwable )
+    {
+    }
+
+    @Override
+    public void warn( String message )
+    {
+    }
+
+    @Override
+    public void warn( String message, Throwable throwable )
+    {
+    }
+
+    @Override
+    public void error( String message )
+    {
+    }
+
+    @Override
+    public void error( String message, Throwable throwable )
+    {
+    }
+
+    @Override
+    public void fatal( String message )
+    {
+    }
+
+    @Override
+    public void fatal( String message, Throwable throwable )
+    {
+    }
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/AccessorType.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/AccessorType.java
new file mode 100644
index 0000000..0f77548
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/AccessorType.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public enum AccessorType
+{
+    Field, Method
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ArrayPropertyAccessor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ArrayPropertyAccessor.java
new file mode 100644
index 0000000..ba458fa
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ArrayPropertyAccessor.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public interface ArrayPropertyAccessor
+    extends ValuePropertyAccessor
+{
+
+    <T> void writeObject( Object instance, int index, T value );
+
+    <T> T readObject( Object instance, int index );
+
+    void writeBoolean( Object instance, int index, boolean value );
+
+    boolean readBoolean( Object instance, int index );
+
+    void writeByte( Object instance, int index, byte value );
+
+    byte readByte( Object instance, int index );
+
+    void writeChar( Object instance, int index, char value );
+
+    char readChar( Object instance, int index );
+
+    void writeShort( Object instance, int index, short value );
+
+    short readShort( Object instance, int index );
+
+    void writeInt( Object instance, int index, int value );
+
+    int readInt( Object instance, int index );
+
+    void writeLong( Object instance, int index, long value );
+
+    long readLong( Object instance, int index );
+
+    void writeFloat( Object instance, int index, float value );
+
+    float readFloat( Object instance, int index );
+
+    void writeDouble( Object instance, int index, double value );
+
+    double readDouble( Object instance, int index );
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/Attribute.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/Attribute.java
new file mode 100644
index 0000000..93b6d62
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/Attribute.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Defines a property (annotated field or method) as an attribute to be serialized by Lightning.<br>
+ * 
+ * <pre>
+ * 
+ * public class MyEntity
+ * {
+ * 
+ *     private long id;
+ * 
+ *     &#064;Attribute
+ *     private String name;
+ * 
+ *     &#064;Attribute
+ *     public long getId()
+ *     {
+ *         return id;
+ *     }
+ * 
+ *     public void setId( long id )
+ *     {
+ *         this.id = id;
+ *     }
+ * 
+ *     public String getName()
+ *     {
+ *         return name;
+ *     }
+ * 
+ *     public void setName( String name )
+ *     {
+ *         this.name = name;
+ *     }
+ * }
+ * </pre>
+ */
+@Documented
+@Inherited
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.FIELD, ElementType.METHOD } )
+public @interface Attribute
+{
+
+    public static final String NULL = "~~NULL~~";
+
+    /**
+     * If a method is annotated this value defines a property name differs from property name extracted from methodname.<br>
+     * Means if method is "getFoo" property name defaults to "foo", but if the method is annotated by @Attribute("bar")
+     * the property name will be explicitly "bar".
+     * 
+     * @return the defined property name
+     */
+    String property() default NULL;
+
+    boolean nullable() default false;
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinition.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinition.java
new file mode 100644
index 0000000..e8b986d
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinition.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public interface ClassDefinition
+{
+
+    String getCanonicalName();
+
+    Class<?> getType();
+
+    byte[] getChecksum();
+
+    long getId();
+
+    long getSerialVersionUID();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinitionContainer.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinitionContainer.java
new file mode 100644
index 0000000..1f0e960
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDefinitionContainer.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+import java.util.Collection;
+
+public interface ClassDefinitionContainer
+{
+
+    Collection<ClassDefinition> getClassDefinitions();
+
+    Class<?> getTypeById( long id );
+
+    ClassDefinition getClassDefinitionByCanonicalName( String canonicalName );
+
+    ClassDefinition getClassDefinitionById( long id );
+
+    ClassDefinition getClassDefinitionByType( Class<?> type );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDescriptor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDescriptor.java
new file mode 100644
index 0000000..fb49377
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ClassDescriptor.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+import java.util.List;
+
+import org.apache.directmemory.lightning.Marshaller;
+
+public interface ClassDescriptor
+{
+
+    ClassDefinition getClassDefinition();
+
+    Class<?> getType();
+
+    List<PropertyDescriptor> getPropertyDescriptors();
+
+    Marshaller getMarshaller();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyAccessor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyAccessor.java
new file mode 100644
index 0000000..0528024
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyAccessor.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public interface PropertyAccessor
+{
+
+    Class<?> getDeclaringClass();
+
+    Class<?> getDefinedClass();
+
+    AccessorType getAccessorType();
+
+    Class<?> getType();
+
+    boolean isArrayType();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyDescriptor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyDescriptor.java
new file mode 100644
index 0000000..29e30b6
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/PropertyDescriptor.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.directmemory.lightning.Marshaller;
+
+public interface PropertyDescriptor
+    extends Comparable<PropertyDescriptor>
+{
+
+    Annotation[] getAnnotations();
+
+    Class<?> getDefinedClass();
+
+    Class<?> getDeclaringClass();
+
+    PropertyAccessor getPropertyAccessor();
+
+    String getName();
+
+    String getPropertyName();
+
+    Class<?> getType();
+
+    String getInternalSignature();
+
+    Marshaller getMarshaller();
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValueNullableEvaluator.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValueNullableEvaluator.java
new file mode 100644
index 0000000..a9a73fc
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValueNullableEvaluator.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public interface ValueNullableEvaluator
+{
+
+    boolean isValueNullable( PropertyDescriptor propertyDescriptor );
+
+}
diff --git a/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValuePropertyAccessor.java b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValuePropertyAccessor.java
new file mode 100644
index 0000000..9f013b8
--- /dev/null
+++ b/lightning-api/src/main/java/org/apache/directmemory/lightning/metadata/ValuePropertyAccessor.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.metadata;
+
+public interface ValuePropertyAccessor
+    extends PropertyAccessor
+{
+
+    <T> void writeObject( Object instance, T value );
+
+    <T> T readObject( Object instance );
+
+    void writeBoolean( Object instance, boolean value );
+
+    boolean readBoolean( Object instance );
+
+    void writeByte( Object instance, byte value );
+
+    byte readByte( Object instance );
+
+    void writeChar( Object instance, char value );
+
+    char readChar( Object instance );
+
+    void writeShort( Object instance, short value );
+
+    short readShort( Object instance );
+
+    void writeInt( Object instance, int value );
+
+    int readInt( Object instance );
+
+    void writeLong( Object instance, long value );
+
+    long readLong( Object instance );
+
+    void writeFloat( Object instance, float value );
+
+    float readFloat( Object instance );
+
+    void writeDouble( Object instance, double value );
+
+    double readDouble( Object instance );
+
+}
diff --git a/lightning-core/pom.xml b/lightning-core/pom.xml
new file mode 100644
index 0000000..2895264
--- /dev/null
+++ b/lightning-core/pom.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-core</artifactId>
+  <name>Lightning: Core</name>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-api</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode</groupId>
+      <artifactId>reflectasm</artifactId>
+      <scope>provided</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>asm</groupId>
+          <artifactId>asm</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>jarjar</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <property>
+          <name>jarjar</name>
+          <value>true</value>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.sonatype.plugins</groupId>
+            <artifactId>jarjar-maven-plugin</artifactId>
+            <version>1.4</version>
+            <configuration>
+              <includes>
+                <include>com.carrotsearch:hppc</include>
+                <include>${project.groupId}:lightning-api</include>
+                <include>asm:asm</include>
+                <include>com.googlecode:reflectasm</include>
+              </includes>
+              <rules>
+                <rule>
+                  <pattern>com.carrotsearch.**</pattern>
+                  <result>org.apache.directmemory.lightning.internal.bundle.@1</result>
+                </rule>
+                <rule>
+                  <pattern>org.objectweb.**</pattern>
+                  <result>org.apache.directmemory.lightning.internal.bundle.@1</result>
+                </rule>
+                <rule>
+                  <pattern>com.esotericsoftware.**</pattern>
+                  <result>org.apache.directmemory.lightning.internal.bundle.@1</result>
+                </rule>
+              </rules>
+            </configuration>
+            <executions>
+              <execution>
+                <id>jarjar-classes</id>
+                <phase>process-test-classes</phase>
+                <goals>
+                  <goal>jarjar</goal>
+                </goals>
+                <configuration>
+                  <input>{classes}</input>
+                </configuration>
+              </execution>
+              <execution>
+                <id>jarjar-test-classes</id>
+                <phase>process-test-classes</phase>
+                <goals>
+                  <goal>jarjar</goal>
+                </goals>
+                <configuration>
+                  <input>{test-classes}</input>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
\ No newline at end of file
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/Lightning.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/Lightning.java
new file mode 100644
index 0000000..34c39aa
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/Lightning.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.ClassComparisonStrategy;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.DefaultValueNullableEvaluator;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.internal.InternalSerializerCreator;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.logging.LoggerAdapter;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+public final class Lightning
+{
+
+    private Lightning()
+    {
+    }
+
+    public static final Builder newBuilder()
+    {
+        return new Builder();
+    }
+
+    public static final Serializer createSerializer( SerializerDefinition... serializerDefinitions )
+    {
+        return createSerializer( Arrays.asList( serializerDefinitions ) );
+    }
+
+    public static final Serializer createSerializer( Iterable<? extends SerializerDefinition> serializerDefinitions )
+    {
+        return new Builder().serializerDefinitions( serializerDefinitions ).build();
+    }
+
+    public static class Builder
+    {
+
+        private Set<SerializerDefinition> serializerDefinitions = new HashSet<SerializerDefinition>();
+
+        private SerializationStrategy serializationStrategy = SerializationStrategy.SpeedOptimized;
+
+        private Class<? extends Annotation> attributeAnnotation = null;
+
+        private ClassComparisonStrategy classComparisonStrategy = ClassComparisonStrategy.LightningChecksum;
+
+        private ValueNullableEvaluator valueNullableEvaluator = new DefaultValueNullableEvaluator();
+
+        private File debugCacheDirectory = null;
+
+        private Logger logger = new LoggerAdapter();
+
+        private Builder()
+        {
+        }
+
+        public Builder describesAttributs( Class<? extends Annotation> attributeAnnotation )
+        {
+            this.attributeAnnotation = attributeAnnotation;
+            return this;
+        }
+
+        public Builder debugCacheDirectory( File debugCacheDirectory )
+        {
+            this.debugCacheDirectory = debugCacheDirectory;
+            return this;
+        }
+
+        public Builder serializationStrategy( SerializationStrategy serializationStrategy )
+        {
+            this.serializationStrategy = serializationStrategy;
+            return this;
+        }
+
+        public Builder classComparisonStrategy( ClassComparisonStrategy classComparisonStrategy )
+        {
+            this.classComparisonStrategy = classComparisonStrategy;
+            return this;
+        }
+
+        public Builder serializerDefinitions( SerializerDefinition... serializerDefinitions )
+        {
+            return serializerDefinitions( Arrays.asList( serializerDefinitions ) );
+        }
+
+        public Builder serializerDefinitions( Iterable<? extends SerializerDefinition> serializerDefinitions )
+        {
+            for ( SerializerDefinition serializerDefinition : serializerDefinitions )
+            {
+                this.serializerDefinitions.add( serializerDefinition );
+            }
+            return this;
+        }
+
+        public Builder setValueNullableEvaluator( ValueNullableEvaluator valueNullableEvaluator )
+        {
+            this.valueNullableEvaluator = valueNullableEvaluator;
+            return this;
+        }
+
+        public Builder logger( Logger logger )
+        {
+            this.logger = logger;
+            return this;
+        }
+
+        public Serializer build()
+        {
+            return new InternalSerializerCreator().setLogger( logger ).setSerializationStrategy( serializationStrategy ).setClassComparisonStrategy( classComparisonStrategy ).setAttributeAnnotation( attributeAnnotation ).setDebugCacheDirectory( debugCacheDirectory ).setValueNullableEvaluator( valueNullableEvaluator ).addSerializerDefinitions( serializerDefinitions ).build();
+        }
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractMarshaller.java
new file mode 100644
index 0000000..7e91f86
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractMarshaller.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.base;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public abstract class AbstractMarshaller
+    implements Marshaller
+{
+
+    @Override
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        return null;
+    }
+
+    protected boolean writePossibleNull( Object value, DataOutput dataOutput )
+        throws IOException
+    {
+        dataOutput.writeByte( value == null ? 1 : 0 );
+        return value != null;
+    }
+
+    protected boolean isNull( DataInput dataInput )
+        throws IOException
+    {
+        byte isNull = dataInput.readByte();
+        return isNull == 1 ? true : false;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractObjectMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractObjectMarshaller.java
new file mode 100644
index 0000000..1344edf
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractObjectMarshaller.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.base;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public abstract class AbstractObjectMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public final <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                   SerializationContext serializationContext )
+        throws IOException
+    {
+        Object value =
+            serializationContext.getObjectInstantiatorFactory().getInstantiatorOf( propertyDescriptor.getType() );
+        return unmarshall( (V) value, propertyDescriptor, dataInput, serializationContext );
+    }
+
+    public abstract <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                      SerializationContext serializationContext )
+        throws IOException;
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractSerializerDefinition.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractSerializerDefinition.java
new file mode 100644
index 0000000..81435e6
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/AbstractSerializerDefinition.java
@@ -0,0 +1,445 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.base;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.bindings.AnnotatedBinder;
+import org.apache.directmemory.lightning.bindings.AttributeBinder;
+import org.apache.directmemory.lightning.bindings.ClassBinder;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.configuration.TypeIntrospector;
+import org.apache.directmemory.lightning.exceptions.SerializerDefinitionException;
+import org.apache.directmemory.lightning.generator.DefinitionBuildingContext;
+import org.apache.directmemory.lightning.generator.DefinitionVisitor;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.InternalMarshallerContext;
+import org.apache.directmemory.lightning.internal.beans.introspection.AnnotatedTypeIntrospector;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
+
+public abstract class AbstractSerializerDefinition
+    implements SerializerDefinition
+{
+
+    private final InternalMarshallerContext marshallerContext = new InternalMarshallerContext();
+
+    private final Set<SerializerDefinition> children = new HashSet<SerializerDefinition>();
+
+    private final Map<PropertyDescriptor, Marshaller> propertyMarshallers =
+        new HashMap<PropertyDescriptor, Marshaller>();
+
+    private final Map<AnnotatedBinder, AnnotationBinderDefinition<?>> annotationBinders =
+        new HashMap<AnnotatedBinder, AnnotationBinderDefinition<?>>();
+
+    private DefinitionBuildingContext definitionBuildingContext;
+
+    private ObjectInstantiatorFactory objectInstantiatorFactory = null;
+
+    private Class<? extends Annotation> attributeAnnotation = null;
+
+    private AbstractSerializerDefinition parent = null;
+
+    @Override
+    public final void configure( DefinitionBuildingContext definitionBuildingContext,
+                                 ObjectInstantiatorFactory objectInstantiatorFactory )
+    {
+        // Save PropertyDescriptorFactory for later use in configure()
+        this.definitionBuildingContext = definitionBuildingContext;
+
+        // Save ObjectInstantiatorFactory for later use in configure()
+        this.objectInstantiatorFactory = objectInstantiatorFactory;
+
+        // Read the configuration
+        configure();
+    }
+
+    @Override
+    public final void acceptVisitor( DefinitionVisitor visitor )
+    {
+        // Start visiting
+        visitor.visitSerializerDefinition( this );
+
+        // Visit the attribute annotation if set
+        Class<? extends Annotation> attributeAnnotation = findAttributeAnnotation( this );
+        if ( attributeAnnotation != null )
+        {
+            visitor.visitAttributeAnnotation( attributeAnnotation );
+        }
+
+        // Visit all direct marshallers
+        Iterator<ObjectObjectCursor<Type, Marshaller>> iterator = marshallerContext.getInternalMap().iterator();
+        while ( iterator.hasNext() )
+        {
+            ObjectObjectCursor<Type, Marshaller> entry = iterator.next();
+            visitor.visitClassDefine( entry.key, entry.value );
+        }
+
+        // Visit annotated properties
+        Iterator<AnnotationBinderDefinition<?>> annotationIterator = annotationBinders.values().iterator();
+        while ( annotationIterator.hasNext() )
+        {
+            AnnotationBinderDefinition<?> annotationBinderDefinition = annotationIterator.next();
+            annotationBinderDefinition.acceptVisitor( visitor );
+        }
+
+        // Visit all property definitions
+        for ( Entry<PropertyDescriptor, Marshaller> entry : propertyMarshallers.entrySet() )
+        {
+            visitor.visitPropertyDescriptor( entry.getKey(), entry.getValue() );
+
+            Class<?> type = entry.getKey().getType();
+            if ( type.isPrimitive() || type.isArray() && type.getComponentType().isPrimitive() )
+            {
+                continue;
+            }
+
+            visitor.visitClassDefine( type, entry.getValue() );
+        }
+
+        // Visit all children
+        for ( SerializerDefinition child : children )
+        {
+            child.configure( definitionBuildingContext, objectInstantiatorFactory );
+            child.acceptVisitor( visitor );
+        }
+
+        // Finalize visit
+        visitor.visitFinalizeSerializerDefinition( this );
+    }
+
+    protected abstract void configure();
+
+    protected <T> ClassBinder<T> serialize( final Class<T> clazz )
+    {
+        return buildClassBinder( clazz );
+    }
+
+    protected void install( SerializerDefinition childSerializer )
+    {
+        children.add( childSerializer );
+        if ( childSerializer instanceof AbstractSerializerDefinition )
+        {
+            ( (AbstractSerializerDefinition) childSerializer ).parent = this;
+        }
+    }
+
+    protected void describesAttributes( Class<? extends Annotation> attributeAnnotation )
+    {
+        this.attributeAnnotation = attributeAnnotation;
+    }
+
+    protected <V> AttributeBinder<V> attribute( final String attribute )
+    {
+        return new DefinedAttributeBinder<V>()
+        {
+
+            @Override
+            protected void setDeclaringClass( Class<?> declaringClass )
+            {
+                super.setDeclaringClass( declaringClass );
+                try
+                {
+                    Field reflectiveField = declaringClass.getDeclaredField( attribute );
+                    reflectiveField.setAccessible( true );
+                    property = reflectiveField;
+                }
+                catch ( Exception e )
+                {
+                    throw new SerializerDefinitionException( "Property " + property + " could not be found for type "
+                        + declaringClass.getCanonicalName(), e );
+                }
+            }
+        };
+    }
+
+    protected <V> AttributeBinder<V> attribute( final Field attribute )
+    {
+        return new DefinedAttributeBinder<V>()
+        {
+
+            {
+                property = attribute;
+                declaringClass = attribute.getDeclaringClass();
+            }
+        };
+    }
+
+    private <T> ClassBinder<T> buildClassBinder( final Class<T> clazz )
+    {
+        return new ClassBinder<T>()
+        {
+
+            @Override
+            public AnnotatedBinder attributes()
+            {
+                return buildAnnotatedBinder( this, attributeAnnotation );
+            }
+
+            @Override
+            public AnnotatedBinder attributes( Class<? extends Annotation> annotation )
+            {
+                return buildAnnotatedBinder( this, annotation );
+            }
+
+            @Override
+            public Class<T> getType()
+            {
+                return clazz;
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public void using( Class<?> clazz )
+            {
+                if ( Marshaller.class.isAssignableFrom( clazz ) )
+                {
+                    try
+                    {
+                        using( ( (Class<Marshaller>) clazz ).newInstance() );
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new SerializerDefinitionException( "Marshaller class " + clazz.getCanonicalName()
+                            + " could not be instantiated. Is there a standard (public) constructor?", e );
+                    }
+                }
+
+            }
+
+            @Override
+            public void using( Marshaller marshaller )
+            {
+                if ( marshaller instanceof AbstractObjectMarshaller )
+                {
+                    marshallerContext.bindMarshaller( clazz,
+                                                      new ObjenesisDelegatingMarshaller(
+                                                                                         (AbstractObjectMarshaller) marshaller,
+                                                                                         objectInstantiatorFactory ) );
+                }
+                else
+                {
+                    marshallerContext.bindMarshaller( clazz, marshaller );
+                }
+            }
+
+            @Override
+            public void using( TypeIntrospector typeIntrospector )
+            {
+                // TODO Auto-generated method stub
+
+            }
+
+            @Override
+            public void attributes( AttributeBinder<?>... attributes )
+            {
+                for ( AttributeBinder<?> attribute : attributes )
+                {
+                    if ( attribute instanceof DefinedAttributeBinder )
+                    {
+                        DefinedAttributeBinder<?> binder = (DefinedAttributeBinder<?>) attribute;
+                        binder.setDeclaringClass( getType() );
+                        binder.build();
+                    }
+                }
+            }
+        };
+    }
+
+    private <T> AnnotatedBinder buildAnnotatedBinder( final ClassBinder<T> classBinder,
+                                                      final Class<? extends Annotation> annotation )
+    {
+
+        return new AnnotatedBinder()
+        {
+
+            private final AnnotationBinderDefinition<T> binder = new AnnotationBinderDefinition<T>( classBinder );
+
+            {
+                annotationBinders.put( this, binder );
+            }
+
+            @Override
+            public AnnotatedBinder exclude( String property )
+            {
+                binder.addExclude( property );
+                return this;
+            }
+
+            @Override
+            public AnnotatedBinder excludes( String... properties )
+            {
+                for ( String property : properties )
+                {
+                    binder.addExclude( property );
+                }
+                return this;
+            }
+        };
+    }
+
+    private Class<? extends Annotation> findAttributeAnnotation( AbstractSerializerDefinition abstractSerializerDefinition )
+    {
+        if ( attributeAnnotation != null )
+        {
+            return attributeAnnotation;
+        }
+
+        if ( parent != null )
+        {
+            return abstractSerializerDefinition.findAttributeAnnotation( parent );
+        }
+
+        return Attribute.class;
+    }
+
+    private class AnnotationBinderDefinition<T>
+    {
+
+        private final AnnotatedTypeIntrospector typeIntrospector;
+
+        private final ClassBinder<T> classBinder;
+
+        private final List<String> excludes = new ArrayList<String>();
+
+        private AnnotationBinderDefinition( ClassBinder<T> classBinder )
+        {
+            this.typeIntrospector =
+                new AnnotatedTypeIntrospector( findAttributeAnnotation( AbstractSerializerDefinition.this ), excludes );
+            this.classBinder = classBinder;
+        }
+
+        public void addExclude( String exclude )
+        {
+            excludes.add( exclude );
+        }
+
+        public void acceptVisitor( DefinitionVisitor visitor )
+        {
+            MarshallerContext marshallers = combineMarshallers( AbstractSerializerDefinition.this );
+            List<PropertyDescriptor> propertyDescriptors =
+                typeIntrospector.introspect( classBinder.getType(), definitionBuildingContext.getMarshallerStrategy(),
+                                             marshallers, definitionBuildingContext.getPropertyDescriptorFactory() );
+
+            for ( PropertyDescriptor propertyDescriptor : propertyDescriptors )
+            {
+                Class<?> fieldType = propertyDescriptor.getType();
+                Marshaller marshaller = propertyDescriptor.getMarshaller();
+                visitor.visitAnnotatedAttribute( propertyDescriptor, marshaller );
+
+                if ( fieldType.isPrimitive() || fieldType.isArray() && fieldType.getComponentType().isPrimitive() )
+                {
+                    continue;
+                }
+
+                visitor.visitClassDefine( !fieldType.isArray() ? fieldType : fieldType.getComponentType(), marshaller );
+                if ( marshaller == null )
+                {
+                    visitFieldTypeAnnotatedProperties( !fieldType.isArray() ? fieldType : fieldType.getComponentType(),
+                                                       visitor );
+                }
+            }
+        }
+
+        @SuppressWarnings( "unchecked" )
+        private <F> void visitFieldTypeAnnotatedProperties( Class<?> type, DefinitionVisitor visitor )
+        {
+            ClassBinder<F> classBinder = (ClassBinder<F>) buildClassBinder( type );
+            new AnnotationBinderDefinition<F>( classBinder ).acceptVisitor( visitor );
+        }
+
+        private MarshallerContext combineMarshallers( AbstractSerializerDefinition abstractSerializerDefinition )
+        {
+            return new InternalMarshallerContext( abstractSerializerDefinition.marshallerContext );
+        }
+    }
+
+    private abstract class DefinedAttributeBinder<V>
+        implements AttributeBinder<V>
+    {
+
+        protected Marshaller marshaller;
+
+        protected Field property;
+
+        protected Class<?> declaringClass;
+
+        protected void setDeclaringClass( Class<?> declaringClass )
+        {
+            this.declaringClass = declaringClass;
+        }
+
+        @Override
+        public AttributeBinder<V> using( Class<? extends Marshaller> marshaller )
+        {
+            try
+            {
+                using( marshaller.newInstance() );
+                return this;
+            }
+            catch ( Exception e )
+            {
+                throw new SerializerDefinitionException( "Marshaller class " + marshaller.getCanonicalName()
+                    + " could not be instantiated. Is there a standard (public) constructor?", e );
+            }
+        }
+
+        @Override
+        public AttributeBinder<V> using( Marshaller marshaller )
+        {
+            if ( marshaller instanceof TypeBindableMarshaller )
+            {
+                Type[] typeArguments = TypeUtil.getTypeArgument( property.getGenericType() );
+                this.marshaller = ( (TypeBindableMarshaller) marshaller ).bindType( typeArguments );
+            }
+
+            return this;
+        }
+
+        private void build()
+        {
+            if ( marshaller == null )
+            {
+                marshaller =
+                    definitionBuildingContext.getMarshallerStrategy().getMarshaller( property.getType(),
+                                                                                     marshallerContext, true );
+            }
+            propertyMarshallers.put( definitionBuildingContext.getPropertyDescriptorFactory().byField( property,
+                                                                                                       marshaller,
+                                                                                                       declaringClass ),
+                                     marshaller );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/base/DefaultValueNullableEvaluator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/DefaultValueNullableEvaluator.java
new file mode 100644
index 0000000..e93aed1
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/DefaultValueNullableEvaluator.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.base;
+
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+public class DefaultValueNullableEvaluator
+    implements ValueNullableEvaluator
+{
+
+    @Override
+    public boolean isValueNullable( PropertyDescriptor propertyDescriptor )
+    {
+        return !propertyDescriptor.getType().isPrimitive();
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/base/ObjenesisDelegatingMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/ObjenesisDelegatingMarshaller.java
new file mode 100644
index 0000000..f3596a9
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/base/ObjenesisDelegatingMarshaller.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.base;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+class ObjenesisDelegatingMarshaller
+    implements Marshaller
+{
+
+    private final ObjectInstantiatorFactory objectInstantiatorFactory;
+
+    private final AbstractObjectMarshaller delegatedMarshaller;
+
+    ObjenesisDelegatingMarshaller( AbstractObjectMarshaller delegatedMarshaller,
+                                   ObjectInstantiatorFactory objectInstantiatorFactory )
+    {
+        this.delegatedMarshaller = delegatedMarshaller;
+        this.objectInstantiatorFactory = objectInstantiatorFactory;
+    }
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return delegatedMarshaller.acceptType( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        delegatedMarshaller.marshall( value, propertyDescriptor, dataOutput, serializationContext );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        V value = (V) objectInstantiatorFactory.newInstance( propertyDescriptor.getType() );
+        return delegatedMarshaller.unmarshall( value, propertyDescriptor, dataInput, serializationContext );
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AnnotatedBinder.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AnnotatedBinder.java
new file mode 100644
index 0000000..40d20c6
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AnnotatedBinder.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.bindings;
+
+public interface AnnotatedBinder
+{
+
+    AnnotatedBinder exclude( String property );
+
+    AnnotatedBinder excludes( String... properties );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AttributeBinder.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AttributeBinder.java
new file mode 100644
index 0000000..d86edd9
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/AttributeBinder.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.bindings;
+
+import org.apache.directmemory.lightning.Marshaller;
+
+public interface AttributeBinder<V>
+{
+
+    AttributeBinder<V> using( Class<? extends Marshaller> marshaller );
+
+    AttributeBinder<V> using( Marshaller marshaller );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/ClassBinder.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/ClassBinder.java
new file mode 100644
index 0000000..76539e7
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/ClassBinder.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.bindings;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.configuration.TypeIntrospector;
+
+public interface ClassBinder<T>
+{
+
+    AnnotatedBinder attributes();
+
+    AnnotatedBinder attributes( Class<? extends Annotation> annotation );
+
+    void attributes( AttributeBinder<?>... attributes );
+
+    void using( Class<?> clazz );
+
+    void using( Marshaller marshaller );
+
+    void using( TypeIntrospector typeIntrospector );
+
+    Class<T> getType();
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/MarshallerBinder.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/MarshallerBinder.java
new file mode 100644
index 0000000..fc9ea7b
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/bindings/MarshallerBinder.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.bindings;
+
+import org.apache.directmemory.lightning.Marshaller;
+
+public interface MarshallerBinder
+{
+
+    void using( Class<? extends Marshaller> marshaller );
+
+    void using( Marshaller marshaller );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/CheatPropertyDescriptor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/CheatPropertyDescriptor.java
new file mode 100644
index 0000000..3f9002d
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/CheatPropertyDescriptor.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.metadata.AccessorType;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class CheatPropertyDescriptor
+    implements PropertyDescriptor
+{
+
+    private final String name;
+
+    private final String propertyName;
+
+    private final String internalSignature;
+
+    private final String declaringCanonicalClassname;
+
+    private final PropertyAccessor propertyAccessor;
+
+    private final Marshaller marshaller;
+
+    public CheatPropertyDescriptor( String propertyName, final Class<?> type, Marshaller marshaller )
+    {
+        this.name = propertyName;
+        this.propertyName = propertyName;
+        this.marshaller = marshaller;
+        this.propertyAccessor = new PropertyAccessor()
+        {
+
+            @Override
+            public boolean isArrayType()
+            {
+                return type.isArray();
+            }
+
+            @Override
+            public Class<?> getType()
+            {
+                return type;
+            }
+
+            @Override
+            public Class<?> getDefinedClass()
+            {
+                return type;
+            }
+
+            @Override
+            public Class<?> getDeclaringClass()
+            {
+                return type;
+            }
+
+            @Override
+            public AccessorType getAccessorType()
+            {
+                return AccessorType.Field;
+            }
+        };
+
+        this.declaringCanonicalClassname = null;
+        this.internalSignature = null;
+    }
+
+    @Override
+    public int compareTo( PropertyDescriptor o )
+    {
+        return propertyName.compareTo( o.getPropertyName() );
+    }
+
+    @Override
+    public Annotation[] getAnnotations()
+    {
+        return new Annotation[0];
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return propertyAccessor.getDefinedClass();
+    }
+
+    @Override
+    public Class<?> getDeclaringClass()
+    {
+        return propertyAccessor.getDeclaringClass();
+    }
+
+    @Override
+    public PropertyAccessor getPropertyAccessor()
+    {
+        return propertyAccessor;
+    }
+
+    @Override
+    public String getName()
+    {
+        return name;
+    }
+
+    @Override
+    public String getPropertyName()
+    {
+        return propertyName;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return propertyAccessor.getType();
+    }
+
+    @Override
+    public String getInternalSignature()
+    {
+        return internalSignature;
+    }
+
+    @Override
+    public Marshaller getMarshaller()
+    {
+        return marshaller;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result =
+            prime * result + ( ( declaringCanonicalClassname == null ) ? 0 : declaringCanonicalClassname.hashCode() );
+        result = prime * result + ( ( internalSignature == null ) ? 0 : internalSignature.hashCode() );
+        result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
+        result = prime * result + ( ( propertyName == null ) ? 0 : propertyName.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+            return true;
+        if ( obj == null )
+            return false;
+        if ( getClass() != obj.getClass() )
+            return false;
+        CheatPropertyDescriptor other = (CheatPropertyDescriptor) obj;
+        if ( declaringCanonicalClassname == null )
+        {
+            if ( other.declaringCanonicalClassname != null )
+                return false;
+        }
+        else if ( !declaringCanonicalClassname.equals( other.declaringCanonicalClassname ) )
+            return false;
+        if ( internalSignature == null )
+        {
+            if ( other.internalSignature != null )
+                return false;
+        }
+        else if ( !internalSignature.equals( other.internalSignature ) )
+            return false;
+        if ( name == null )
+        {
+            if ( other.name != null )
+                return false;
+        }
+        else if ( !name.equals( other.name ) )
+            return false;
+        if ( propertyName == null )
+        {
+            if ( other.propertyName != null )
+                return false;
+        }
+        else if ( !propertyName.equals( other.propertyName ) )
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "CheatingPropertyDescriptor [name=" + name + ", propertyName=" + propertyName + ", internalSignature="
+            + internalSignature + ", declaringCanonicalClassname=" + declaringCanonicalClassname
+            + ", propertyAccessor=" + propertyAccessor + ", marshaller=" + marshaller + "]";
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/ClassDescriptorAwareSerializer.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/ClassDescriptorAwareSerializer.java
new file mode 100644
index 0000000..83f5873
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/ClassDescriptorAwareSerializer.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+
+public interface ClassDescriptorAwareSerializer
+    extends Serializer
+{
+
+    ClassDescriptor findClassDescriptor( Class<?> type );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinition.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinition.java
new file mode 100644
index 0000000..cb078bc
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinition.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.internal.util.Crc64Util;
+import org.apache.directmemory.lightning.internal.util.InternalUtil;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.objectweb.asm.Type;
+
+class InternalClassDefinition
+    implements ClassDefinition, Comparable<ClassDefinition>
+{
+
+    private final String canonicalName;
+
+    private final Class<?> type;
+
+    private final byte[] checksum;
+
+    private final long serialVersionUID;
+
+    private long id;
+
+    InternalClassDefinition( Class<?> type, List<PropertyDescriptor> propertyDescriptors, Logger logger )
+    {
+        this.canonicalName = Type.getInternalName( type ).replace( "/", "." );
+        this.type = type;
+
+        byte[] classData = ClassUtil.getClassBytes( !type.isArray() ? type : type.getComponentType() );
+        this.checksum = InternalUtil.getChecksum( propertyDescriptors, logger );
+        this.id = Crc64Util.checksum( classData );
+        this.serialVersionUID = ClassUtil.calculateSerialVersionUID( type );
+    }
+
+    InternalClassDefinition( long id, Class<?> type, byte[] checksum, long serialVersionUID )
+    {
+        this.canonicalName = Type.getInternalName( type ).replace( "/", "." );
+        this.type = type;
+        this.id = id;
+        this.checksum = checksum;
+        this.serialVersionUID = serialVersionUID;
+    }
+
+    @Override
+    public String getCanonicalName()
+    {
+        return canonicalName;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return type;
+    }
+
+    @Override
+    public byte[] getChecksum()
+    {
+        return Arrays.copyOf( checksum, checksum.length );
+    }
+
+    @Override
+    public long getId()
+    {
+        return id;
+    }
+
+    @Override
+    public long getSerialVersionUID()
+    {
+        return serialVersionUID;
+    }
+
+    @Override
+    public int compareTo( ClassDefinition o )
+    {
+        return canonicalName.compareTo( o.getCanonicalName() );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( canonicalName == null ) ? 0 : canonicalName.hashCode() );
+        result = prime * result + Arrays.hashCode( checksum );
+        result = prime * result + (int) ( id ^ ( id >>> 32 ) );
+        result = prime * result + (int) ( serialVersionUID ^ ( serialVersionUID >>> 32 ) );
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+            return true;
+        if ( obj == null )
+            return false;
+        if ( getClass() != obj.getClass() )
+            return false;
+        InternalClassDefinition other = (InternalClassDefinition) obj;
+        if ( canonicalName == null )
+        {
+            if ( other.canonicalName != null )
+                return false;
+        }
+        else if ( !canonicalName.equals( other.canonicalName ) )
+            return false;
+        if ( !Arrays.equals( checksum, other.checksum ) )
+            return false;
+        if ( id != other.id )
+            return false;
+        if ( serialVersionUID != other.serialVersionUID )
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "InternalClassDefinition [canonicalName=" + canonicalName + ", type=" + type + ", checksum="
+            + Arrays.toString( checksum ) + ", serialVersionUID=" + serialVersionUID + ", id=" + id + "]";
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinitionContainer.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinitionContainer.java
new file mode 100644
index 0000000..70549c7
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDefinitionContainer.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+
+import com.carrotsearch.hppc.LongObjectMap;
+import com.carrotsearch.hppc.LongObjectOpenHashMap;
+
+class InternalClassDefinitionContainer
+    implements ClassDefinitionContainer, Serializable
+{
+
+    private static final long serialVersionUID = -8496850178968208567L;
+
+    private final ClassDefinition[] classDefinitions;
+
+    private final LongObjectMap<ClassDefinition> classDefinitionsMappings;
+
+    // Serialization
+    private InternalClassDefinitionContainer( ClassDefinition[] classDefinitions )
+    {
+        this.classDefinitions = classDefinitions;
+        this.classDefinitionsMappings = new LongObjectOpenHashMap<ClassDefinition>();
+    }
+
+    InternalClassDefinitionContainer( Set<ClassDefinition> classDefinitions )
+    {
+        this.classDefinitions = classDefinitions.toArray( new ClassDefinition[classDefinitions.size()] );
+        this.classDefinitionsMappings = new LongObjectOpenHashMap<ClassDefinition>( classDefinitions.size() );
+        initMappings( this.classDefinitions );
+    }
+
+    @Override
+    public Collection<ClassDefinition> getClassDefinitions()
+    {
+        return Arrays.asList( Arrays.copyOf( classDefinitions, classDefinitions.length ) );
+    }
+
+    @Override
+    public Class<?> getTypeById( long id )
+    {
+        ClassDefinition classDefinition = classDefinitionsMappings.get( id );
+        return classDefinition != null ? classDefinition.getType() : null;
+    }
+
+    @Override
+    public ClassDefinition getClassDefinitionByCanonicalName( String canonicalName )
+    {
+        for ( ClassDefinition classDefinition : classDefinitions )
+        {
+            if ( classDefinition.getCanonicalName().equals( canonicalName ) )
+            {
+                return classDefinition;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public ClassDefinition getClassDefinitionById( long id )
+    {
+        ClassDefinition classDefinition = classDefinitionsMappings.get( id );
+        return classDefinition != null ? classDefinition : null;
+    }
+
+    @Override
+    public ClassDefinition getClassDefinitionByType( Class<?> type )
+    {
+        if ( List.class.isAssignableFrom( type ) )
+        {
+            type = List.class;
+        }
+        else if ( Set.class.isAssignableFrom( type ) )
+        {
+            type = Set.class;
+        }
+        else if ( Map.class.isAssignableFrom( type ) )
+        {
+            type = Map.class;
+        }
+
+        for ( ClassDefinition classDefinition : classDefinitions )
+        {
+            if ( classDefinition.getType() == type )
+            {
+                return classDefinition;
+            }
+        }
+        return null;
+    }
+
+    private void initMappings( ClassDefinition[] classDefinitions )
+    {
+        for ( ClassDefinition classDefinition : classDefinitions )
+        {
+            classDefinitionsMappings.put( classDefinition.getId(), classDefinition );
+        }
+    }
+
+    Object writeReplace()
+    {
+        return new InternalClassDefinitionProxy( this );
+    }
+
+    /**
+     * SerializationProxy
+     */
+    private static class InternalClassDefinitionProxy
+        implements Externalizable
+    {
+
+        private static final long serialVersionUID = 3127589236225504001L;
+
+        private final InternalClassDefinitionContainer classDefinitionContainer;
+
+        private ClassDefinition[] classDefinitions;
+
+        @SuppressWarnings( "unused" )
+        public InternalClassDefinitionProxy()
+        {
+            this.classDefinitionContainer = null;
+        }
+
+        private InternalClassDefinitionProxy( InternalClassDefinitionContainer classDefinitionContainer )
+        {
+            this.classDefinitionContainer = classDefinitionContainer;
+        }
+
+        @Override
+        public void writeExternal( ObjectOutput out )
+            throws IOException
+        {
+            List<ClassDefinition> selectedClassDefinitions = new ArrayList<ClassDefinition>();
+            for ( ClassDefinition classDefinition : classDefinitionContainer.classDefinitions )
+            {
+                if ( classDefinition.getId() < 1000 )
+                {
+                    continue;
+                }
+
+                selectedClassDefinitions.add( classDefinition );
+            }
+
+            out.writeInt( selectedClassDefinitions.size() );
+            for ( ClassDefinition classDefinition : selectedClassDefinitions )
+            {
+                final long id = classDefinition.getId();
+                final byte[] checksum = classDefinition.getChecksum();
+                final String canonicalName = classDefinition.getCanonicalName();
+                final long serialVersionUID = classDefinition.getSerialVersionUID();
+
+                out.writeLong( id );
+                out.writeUTF( canonicalName );
+                out.write( checksum );
+                out.writeLong( serialVersionUID );
+            }
+        }
+
+        @Override
+        public void readExternal( ObjectInput in )
+            throws IOException, ClassNotFoundException
+        {
+            int size = in.readInt();
+
+            classDefinitions = new ClassDefinition[size + ClassUtil.CLASS_DESCRIPTORS.length];
+            for ( int i = 0; i < ClassUtil.CLASS_DESCRIPTORS.length; i++ )
+            {
+                classDefinitions[i] = ClassUtil.CLASS_DESCRIPTORS[i];
+            }
+
+            for ( int i = 0; i < size; i++ )
+            {
+                final long id = in.readLong();
+                final String canonicalName = in.readUTF();
+                final byte[] checksum = new byte[20];
+                in.readFully( checksum );
+                final long serialVersionUID = in.readLong();
+
+                try
+                {
+                    Class<?> type = ClassUtil.loadClass( canonicalName );
+                    classDefinitions[i + ClassUtil.CLASS_DESCRIPTORS.length] =
+                        new InternalClassDefinition( id, type, checksum, serialVersionUID );
+                }
+                catch ( ClassNotFoundException e )
+                {
+                    throw new IOException( "Class " + canonicalName + " could not be loaded", e );
+                }
+            }
+        }
+
+        private Object readResolve()
+        {
+            InternalClassDefinitionContainer classDefinitionContainer =
+                new InternalClassDefinitionContainer( classDefinitions );
+            classDefinitionContainer.initMappings( classDefinitions );
+            return classDefinitionContainer;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDescriptor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDescriptor.java
new file mode 100644
index 0000000..e9cfd17
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalClassDescriptor.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class InternalClassDescriptor
+    implements ClassDescriptor
+{
+
+    private final Set<PropertyDescriptor> propertyDescriptors = new HashSet<PropertyDescriptor>();
+
+    private final Logger logger;
+
+    private final Class<?> type;
+
+    private ClassDefinition classDefinition;
+
+    private Marshaller marshaller;
+
+    public InternalClassDescriptor( Class<?> type, Logger logger )
+    {
+        this.type = type;
+        this.logger = logger;
+    }
+
+    @Override
+    public ClassDefinition getClassDefinition()
+    {
+        return classDefinition;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return type;
+    }
+
+    @Override
+    public List<PropertyDescriptor> getPropertyDescriptors()
+    {
+        return new ArrayList<PropertyDescriptor>( propertyDescriptors );
+    }
+
+    @Override
+    public Marshaller getMarshaller()
+    {
+        return marshaller;
+    }
+
+    public boolean push( PropertyDescriptor propertyDescriptor )
+    {
+        return propertyDescriptors.add( propertyDescriptor );
+    }
+
+    public void setMarshaller( Marshaller marshaller )
+    {
+        this.marshaller = marshaller;
+    }
+
+    public ClassDescriptor build( ClassDefinition[] classDefinitions )
+    {
+        for ( ClassDefinition classDefinition : classDefinitions )
+        {
+            if ( classDefinition.getType() == type )
+            {
+                this.classDefinition = classDefinition;
+                return this;
+            }
+        }
+
+        classDefinition = new InternalClassDefinition( getType(), getPropertyDescriptors(), logger );
+        return this;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( type == null ) ? 0 : type.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+            return true;
+        if ( obj == null )
+            return false;
+        if ( getClass() != obj.getClass() )
+            return false;
+        InternalClassDescriptor other = (InternalClassDescriptor) obj;
+        if ( type == null )
+        {
+            if ( other.type != null )
+                return false;
+        }
+        else if ( !type.equals( other.type ) )
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "InternalClassDescriptor [propertyDescriptors=" + propertyDescriptors + ", type=" + type
+            + ", classDefinition=" + classDefinition + ", marshaller=" + marshaller + "]";
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalDefinitionBuildingContext.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalDefinitionBuildingContext.java
new file mode 100644
index 0000000..3a654cc
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalDefinitionBuildingContext.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.generator.DefinitionBuildingContext;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+
+public class InternalDefinitionBuildingContext
+    implements DefinitionBuildingContext
+{
+
+    private final PropertyDescriptorFactory propertyDescriptorFactory;
+
+    private final MarshallerStrategy marshallerStrategy;
+
+    public InternalDefinitionBuildingContext( MarshallerStrategy marshallerStrategy,
+                                              PropertyDescriptorFactory propertyDescriptorFactory )
+    {
+        this.marshallerStrategy = marshallerStrategy;
+        this.propertyDescriptorFactory = propertyDescriptorFactory;
+    }
+
+    @Override
+    public PropertyDescriptorFactory getPropertyDescriptorFactory()
+    {
+        return propertyDescriptorFactory;
+    }
+
+    @Override
+    public MarshallerStrategy getMarshallerStrategy()
+    {
+        return marshallerStrategy;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerContext.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerContext.java
new file mode 100644
index 0000000..c729890
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerContext.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.lang.reflect.Type;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+
+import com.carrotsearch.hppc.ObjectObjectMap;
+import com.carrotsearch.hppc.ObjectObjectOpenHashMap;
+
+public class InternalMarshallerContext
+    implements MarshallerContext
+{
+
+    private final MarshallerContext parentMarshallerContext;
+
+    private final ObjectObjectMap<Type, Marshaller> marshallers = new ObjectObjectOpenHashMap<Type, Marshaller>();
+
+    public InternalMarshallerContext()
+    {
+        this( null );
+    }
+
+    public InternalMarshallerContext( MarshallerContext parentMarshallerContext )
+    {
+        this.parentMarshallerContext = parentMarshallerContext;
+    }
+
+    @Override
+    public Marshaller getMarshaller( Type type )
+    {
+        Marshaller marshaller = marshallers.get( type );
+        if ( marshaller != null )
+        {
+            return marshaller;
+        }
+
+        if ( parentMarshallerContext != null )
+        {
+            return parentMarshallerContext.getMarshaller( type );
+        }
+
+        return null;
+    }
+
+    @Override
+    public void bindMarshaller( Type type, Marshaller marshaller )
+    {
+        marshallers.put( type, marshaller );
+    }
+
+    public ObjectObjectMap<Type, Marshaller> getInternalMap()
+    {
+        return marshallers;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerStrategy.java
new file mode 100644
index 0000000..7750f84
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalMarshallerStrategy.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.io.Externalizable;
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.Streamed;
+import org.apache.directmemory.lightning.internal.marshaller.BigDecimalMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.BigIntegerMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.BooleanArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.BooleanMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ByteArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ByteMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.CharacterArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.CharacterMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.DoubleArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.DoubleMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.EnumMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ExternalizableMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.FloatArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.FloatMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.IntegerArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.IntegerMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ListMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.LongArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.LongMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.MapMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.SerializableMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.SetMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ShortArrayMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.ShortMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.StreamedMarshaller;
+import org.apache.directmemory.lightning.internal.marshaller.StringMarshaller;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+
+public class InternalMarshallerStrategy
+    implements MarshallerStrategy
+{
+
+    public static final List<Marshaller> baseMarshaller;
+
+    static
+    {
+        List<Marshaller> marshallers = new ArrayList<Marshaller>();
+        marshallers.add( new StreamedMarshaller() );
+        marshallers.add( new ExternalizableMarshaller() );
+        marshallers.add( new BooleanMarshaller() );
+        marshallers.add( new ByteMarshaller() );
+        marshallers.add( new CharacterMarshaller() );
+        marshallers.add( new ShortMarshaller() );
+        marshallers.add( new IntegerMarshaller() );
+        marshallers.add( new LongMarshaller() );
+        marshallers.add( new FloatMarshaller() );
+        marshallers.add( new DoubleMarshaller() );
+        marshallers.add( new StringMarshaller() );
+        marshallers.add( new EnumMarshaller() );
+        marshallers.add( new ListMarshaller() );
+        marshallers.add( new SetMarshaller() );
+        marshallers.add( new MapMarshaller() );
+        marshallers.add( new BigIntegerMarshaller() );
+        marshallers.add( new BigDecimalMarshaller() );
+        marshallers.add( new BooleanArrayMarshaller() );
+        marshallers.add( new ByteArrayMarshaller() );
+        marshallers.add( new CharacterArrayMarshaller() );
+        marshallers.add( new ShortArrayMarshaller() );
+        marshallers.add( new IntegerArrayMarshaller() );
+        marshallers.add( new LongArrayMarshaller() );
+        marshallers.add( new FloatArrayMarshaller() );
+        marshallers.add( new DoubleArrayMarshaller() );
+
+        baseMarshaller = Collections.unmodifiableList( marshallers );
+    }
+
+    private final Marshaller externalizableMarshaller = new ExternalizableMarshaller();
+
+    private final Marshaller serializableMarshaller = new SerializableMarshaller();
+
+    private final Marshaller streamedMarshaller = new StreamedMarshaller();
+
+    @Override
+    public Marshaller getMarshaller( Type type, MarshallerContext marshallerContext )
+    {
+        return getMarshaller( type, marshallerContext, false );
+    }
+
+    @Override
+    public Marshaller getMarshaller( Type type, MarshallerContext marshallerContext, boolean baseMarshallersOnly )
+    {
+        Class<?> rawType = TypeUtil.getBaseType( type );
+        if ( Streamed.class.isAssignableFrom( rawType ) )
+        {
+            return streamedMarshaller;
+        }
+
+        if ( !baseMarshallersOnly && Externalizable.class.isAssignableFrom( rawType ) )
+        {
+            return externalizableMarshaller;
+        }
+
+        if ( marshallerContext != null )
+        {
+            Marshaller marshaller = marshallerContext.getMarshaller( type );
+            if ( marshaller != null )
+            {
+                return marshaller;
+            }
+        }
+
+        for ( Marshaller temp : baseMarshaller )
+        {
+            if ( temp.acceptType( rawType ) )
+            {
+                return temp;
+            }
+        }
+
+        if ( !baseMarshallersOnly && Serializable.class.isAssignableFrom( rawType ) && !rawType.isArray() )
+        {
+            return serializableMarshaller;
+        }
+
+        return null;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializationContext.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializationContext.java
new file mode 100644
index 0000000..b005214
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializationContext.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.lang.reflect.Type;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+import com.carrotsearch.hppc.LongObjectMap;
+import com.carrotsearch.hppc.LongObjectOpenHashMap;
+
+public class InternalSerializationContext
+    implements SerializationContext
+{
+
+    private final Map<Object, Long> referencesMarshall;
+
+    private final LongObjectMap<Object> referencesUnmarshall;
+
+    private final MarshallerContext marshallerContext = new InternalMarshallerContext();
+
+    private final ClassDefinitionContainer classDefinitionContainer;
+
+    private final SerializationStrategy serializationStrategy;
+
+    private final MarshallerStrategy marshallerStrategy;
+
+    private final ObjectInstantiatorFactory objectInstantiatorFactory;
+
+    private final ValueNullableEvaluator valueNullableEvaluator;
+
+    private long nextReferenceIdMarshall = 10000;
+
+    public InternalSerializationContext( ClassDefinitionContainer classDefinitionContainer,
+                                         SerializationStrategy serializationStrategy,
+                                         MarshallerStrategy marshallerStrategy,
+                                         ObjectInstantiatorFactory objectInstantiatorFactory,
+                                         ValueNullableEvaluator valueNullableEvaluator,
+                                         Map<Class<?>, Marshaller> definedMarshallers )
+    {
+
+        this.classDefinitionContainer = classDefinitionContainer;
+        this.serializationStrategy = serializationStrategy;
+        this.marshallerStrategy = marshallerStrategy;
+        this.objectInstantiatorFactory = objectInstantiatorFactory;
+        this.valueNullableEvaluator = valueNullableEvaluator;
+
+        for ( Entry<Class<?>, Marshaller> entry : definedMarshallers.entrySet() )
+        {
+            this.marshallerContext.bindMarshaller( entry.getKey(), entry.getValue() );
+        }
+
+        if ( serializationStrategy == SerializationStrategy.SizeOptimized )
+        {
+            this.referencesMarshall = new IdentityHashMap<Object, Long>();
+            this.referencesUnmarshall = new LongObjectOpenHashMap<Object>();
+        }
+        else
+        {
+            this.referencesMarshall = null;
+            this.referencesUnmarshall = null;
+        }
+    }
+
+    @Override
+    public ClassDefinitionContainer getClassDefinitionContainer()
+    {
+        return classDefinitionContainer;
+    }
+
+    @Override
+    public SerializationStrategy getSerializationStrategy()
+    {
+        return serializationStrategy;
+    }
+
+    @Override
+    public ObjectInstantiatorFactory getObjectInstantiatorFactory()
+    {
+        return objectInstantiatorFactory;
+    }
+
+    @Override
+    public long findReferenceIdByObject( Object instance )
+    {
+        Long referenceId = referencesMarshall.get( instance );
+        if ( referenceId == null )
+        {
+            return -1;
+        }
+        return referenceId;
+    }
+
+    @Override
+    public long putMarshalledInstance( Object instance )
+    {
+        long newId = getNextReferenceIdMarshall();
+        referencesMarshall.put( instance, newId );
+        return newId;
+    }
+
+    @Override
+    public Object findObjectByReferenceId( long referenceId )
+    {
+        return referencesUnmarshall.get( referenceId );
+    }
+
+    @Override
+    public boolean containsReferenceId( long referenceId )
+    {
+        return referencesUnmarshall.containsKey( referenceId );
+    }
+
+    @Override
+    public long putUnmarshalledInstance( long refrenceId, Object instance )
+    {
+        referencesUnmarshall.put( refrenceId, instance );
+        return refrenceId;
+    }
+
+    @Override
+    public Marshaller findMarshaller( Type type )
+    {
+        Class<?> rawType = TypeUtil.getBaseType( type );
+        Marshaller marshaller = marshallerStrategy.getMarshaller( rawType, marshallerContext, false );
+
+        if ( marshaller instanceof TypeBindableMarshaller )
+        {
+            Type[] typeArguments = TypeUtil.getTypeArgument( type );
+            marshaller = ( (TypeBindableMarshaller) marshaller ).bindType( typeArguments );
+        }
+
+        return marshaller;
+    }
+
+    public Map<Object, Long> getReferencesMarshall()
+    {
+        return referencesMarshall;
+    }
+
+    public LongObjectMap<Object> getReferencesUnmarshall()
+    {
+        return referencesUnmarshall;
+    }
+
+    public long getNextReferenceIdMarshall()
+    {
+        long newId = nextReferenceIdMarshall++;
+        return newId;
+    }
+
+    @Override
+    public ValueNullableEvaluator getValueNullableEvaluator()
+    {
+        return valueNullableEvaluator;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializer.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializer.java
new file mode 100644
index 0000000..c3811b8
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializer.java
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.directmemory.lightning.ClassComparisonStrategy;
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.exceptions.ClassDefinitionInconsistentException;
+import org.apache.directmemory.lightning.exceptions.SerializerExecutionException;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.generator.BytecodeMarshallerGenerator;
+import org.apache.directmemory.lightning.internal.generator.MarshallerGenerator;
+import org.apache.directmemory.lightning.internal.io.BufferInputStream;
+import org.apache.directmemory.lightning.internal.io.BufferOutputStream;
+import org.apache.directmemory.lightning.internal.io.ReaderInputStream;
+import org.apache.directmemory.lightning.internal.io.WriterOutputStream;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+class InternalSerializer
+    implements ClassDescriptorAwareSerializer
+{
+
+    private final AtomicReference<ClassDefinitionContainer> classDefinitionContainer =
+        new AtomicReference<ClassDefinitionContainer>();
+
+    private final MarshallerGenerator marshallerGenerator = new BytecodeMarshallerGenerator();
+
+    private final ObjectInstantiatorFactory objectInstantiatorFactory;
+
+    private final ClassComparisonStrategy classComparisonStrategy;
+
+    private final Map<Class<?>, ClassDescriptor> classDescriptors;
+
+    private final SerializationStrategy serializationStrategy;
+
+    private final Map<Class<?>, Marshaller> definedMarshallers;
+
+    private final MarshallerStrategy marshallerStrategy;
+
+    private final ValueNullableEvaluator valueNullableEvaluator;
+
+    InternalSerializer( ClassDefinitionContainer classDefinitionContainer, SerializationStrategy serializationStrategy,
+                        ClassComparisonStrategy classComparisonStrategy,
+                        Map<Class<?>, ClassDescriptor> classDescriptors, Map<Class<?>, Marshaller> marshallers,
+                        ObjectInstantiatorFactory objectInstantiatorFactory, Logger logger,
+                        MarshallerStrategy marshallerStrategy, File debugCacheDirectory,
+                        ValueNullableEvaluator valueNullableEvaluator )
+    {
+
+        this.classDefinitionContainer.set( classDefinitionContainer );
+        this.classComparisonStrategy = classComparisonStrategy;
+        this.classDescriptors = Collections.unmodifiableMap( classDescriptors );
+        this.serializationStrategy = serializationStrategy;
+        this.valueNullableEvaluator = valueNullableEvaluator;
+
+        for ( ClassDescriptor classDescriptor : classDescriptors.values() )
+        {
+            if ( classDescriptor instanceof InternalClassDescriptor && classDescriptor.getMarshaller() == null )
+            {
+                Marshaller marshaller =
+                    marshallerGenerator.generateMarshaller( classDescriptor.getType(),
+                                                            classDescriptor.getPropertyDescriptors(), marshallers,
+                                                            this, serializationStrategy, objectInstantiatorFactory,
+                                                            debugCacheDirectory );
+
+                ( (InternalClassDescriptor) classDescriptor ).setMarshaller( marshaller );
+                marshallers.put( classDescriptor.getType(), marshaller );
+            }
+        }
+
+        this.definedMarshallers = marshallers;
+        this.marshallerStrategy = marshallerStrategy;
+        this.objectInstantiatorFactory = objectInstantiatorFactory;
+    }
+
+    @Override
+    public ClassDefinitionContainer getClassDefinitionContainer()
+    {
+        return classDefinitionContainer.get();
+    }
+
+    @Override
+    public void setClassDefinitionContainer( ClassDefinitionContainer classDefinitionContainer )
+    {
+        // Pre-check if checksums of remote classes passing
+        ClassDefinitionContainer oldClassDefinitionContainer = getClassDefinitionContainer();
+        consistencyCheckClassChecksums( oldClassDefinitionContainer, classDefinitionContainer );
+
+        // Set new ClassDefinitionContainer if checking succeed
+        this.classDefinitionContainer.set( classDefinitionContainer );
+    }
+
+    @Override
+    public <V> void serialize( V value, DataOutput dataOutput )
+    {
+        try
+        {
+            SerializationContext serializationContext =
+                new InternalSerializationContext( classDefinitionContainer.get(), serializationStrategy,
+                                                  marshallerStrategy, objectInstantiatorFactory,
+                                                  valueNullableEvaluator, definedMarshallers );
+
+            Class<?> type = value.getClass();
+            ClassDescriptor classDescriptor = findClassDescriptor( type );
+            Marshaller marshaller = classDescriptor.getMarshaller();
+            PropertyDescriptor pd = new CheatPropertyDescriptor( "serialize", classDescriptor.getType(), marshaller );
+
+            dataOutput.writeLong( classDescriptor.getClassDefinition().getId() );
+            marshaller.marshall( value, pd, dataOutput, serializationContext );
+        }
+        catch ( IOException e )
+        {
+            throw new SerializerExecutionException( "Error while serializing value", e );
+        }
+    }
+
+    @Override
+    public <V> void serialize( V value, OutputStream outputStream )
+    {
+        if ( outputStream instanceof DataOutput )
+            serialize( value, (DataOutput) outputStream );
+        else
+            serialize( value, (DataOutput) new DataOutputStream( outputStream ) );
+    }
+
+    @Override
+    public <V> void serialize( V value, Writer writer )
+    {
+        serialize( value, (DataOutput) new DataOutputStream( new WriterOutputStream( writer, "UTF-8" ) ) );
+    }
+
+    @Override
+    public <V> void serialize( V value, ByteBuffer buffer )
+    {
+        serialize( value, (DataOutput) new DataOutputStream( new BufferOutputStream( buffer ) ) );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V deserialize( DataInput dataInput )
+    {
+        try
+        {
+            SerializationContext serializationContext =
+                new InternalSerializationContext( classDefinitionContainer.get(), serializationStrategy,
+                                                  marshallerStrategy, objectInstantiatorFactory,
+                                                  valueNullableEvaluator, definedMarshallers );
+
+            long typeId = dataInput.readLong();
+            Class<?> clazz = classDefinitionContainer.get().getTypeById( typeId );
+            ClassDescriptor classDescriptor = findClassDescriptor( clazz );
+            Marshaller marshaller = classDescriptor.getMarshaller();
+            PropertyDescriptor pd = new CheatPropertyDescriptor( "serialize", classDescriptor.getType(), marshaller );
+
+            return (V) marshaller.unmarshall( pd, dataInput, serializationContext );
+        }
+        catch ( IOException e )
+        {
+            throw new SerializerExecutionException( "Error while deserializing value", e );
+        }
+    }
+
+    @Override
+    public <V> V deserialize( InputStream inputStream )
+    {
+        if ( inputStream instanceof DataInput )
+        {
+            return deserialize( (DataInput) inputStream );
+        }
+
+        return deserialize( (DataInput) new DataInputStream( inputStream ) );
+    }
+
+    @Override
+    public <V> V deserialize( Reader reader )
+    {
+        return deserialize( (DataInput) new DataInputStream( new ReaderInputStream( reader, "UTF-8" ) ) );
+    }
+
+    @Override
+    public <V> V deserialize( ByteBuffer buffer )
+    {
+        return deserialize( (DataInput) new DataInputStream( new BufferInputStream( buffer ) ) );
+    }
+
+    @Override
+    public ClassDescriptor findClassDescriptor( Class<?> type )
+    {
+        return classDescriptors.get( type );
+    }
+
+    private void consistencyCheckClassChecksums( ClassDefinitionContainer oldClassDefinitionContainer,
+                                                 ClassDefinitionContainer classDefinitionContainer )
+    {
+        for ( ClassDefinition classDefinition : classDefinitionContainer.getClassDefinitions() )
+        {
+            ClassDefinition oldClassDefinition =
+                oldClassDefinitionContainer.getClassDefinitionByCanonicalName( classDefinition.getCanonicalName() );
+            if ( oldClassDefinition == null )
+            {
+                throw new ClassDefinitionInconsistentException( "No ClassDefinition for type "
+                    + classDefinition.getCanonicalName() + " was found" );
+            }
+
+            if ( classComparisonStrategy != ClassComparisonStrategy.SkipComparison )
+            {
+                if ( classComparisonStrategy == ClassComparisonStrategy.SerialVersionUID )
+                {
+                    long serialVersionUID = classDefinition.getSerialVersionUID();
+                    long oldSerialVersionUID = oldClassDefinition.getSerialVersionUID();
+                    if ( serialVersionUID != oldSerialVersionUID )
+                    {
+                        throw new ClassDefinitionInconsistentException( "SerialVersionUID of type "
+                            + classDefinition.getCanonicalName() + " is not constistent" );
+                    }
+                }
+                else
+                {
+                    byte[] checksum = classDefinition.getChecksum();
+                    byte[] oldChecksum = oldClassDefinition.getChecksum();
+                    if ( !Arrays.equals( checksum, oldChecksum ) )
+                    {
+                        throw new ClassDefinitionInconsistentException( "Signature checksum of type "
+                            + classDefinition.getCanonicalName() + " is not constistent" );
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializerCreator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializerCreator.java
new file mode 100644
index 0000000..a186123
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/InternalSerializerCreator.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.directmemory.lightning.ClassComparisonStrategy;
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.generator.DefinitionBuildingContext;
+import org.apache.directmemory.lightning.generator.DefinitionVisitor;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.beans.InternalPropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisSerializer;
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.logging.LoggerAdapter;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.apache.directmemory.lightning.metadata.ValueNullableEvaluator;
+
+public final class InternalSerializerCreator
+{
+
+    private final Map<Class<?>, InternalClassDescriptor> classDescriptors =
+        new HashMap<Class<?>, InternalClassDescriptor>();
+
+    private final List<SerializerDefinition> serializerDefinitions = new ArrayList<SerializerDefinition>();
+
+    private final Map<Class<?>, Marshaller> marshallers = new HashMap<Class<?>, Marshaller>();
+
+    private final ObjectInstantiatorFactory objectInstantiatorFactory = new ObjenesisSerializer( true );
+
+    private ValueNullableEvaluator valueNullableEvaluator;
+
+    private SerializationStrategy serializationStrategy = SerializationStrategy.SpeedOptimized;
+
+    private Class<? extends Annotation> attributeAnnotation = Attribute.class;
+
+    private ClassComparisonStrategy classComparisonStrategy = ClassComparisonStrategy.LightningChecksum;
+
+    private File debugCacheDirectory = null;
+
+    private Logger logger = new LoggerAdapter();
+
+    public InternalSerializerCreator()
+    {
+    }
+
+    public InternalSerializerCreator addSerializerDefinitions( Iterable<? extends SerializerDefinition> serializerDefinitions )
+    {
+        for ( SerializerDefinition serializerDefinition : serializerDefinitions )
+        {
+            this.serializerDefinitions.add( serializerDefinition );
+        }
+
+        return this;
+    }
+
+    public InternalSerializerCreator setDebugCacheDirectory( File debugCacheDirectory )
+    {
+        this.debugCacheDirectory = debugCacheDirectory;
+        return this;
+    }
+
+    public InternalSerializerCreator setLogger( Logger logger )
+    {
+        this.logger = logger;
+        return this;
+    }
+
+    public InternalSerializerCreator setAttributeAnnotation( Class<? extends Annotation> attributeAnnotation )
+    {
+        this.attributeAnnotation = attributeAnnotation;
+        return this;
+    }
+
+    public InternalSerializerCreator setSerializationStrategy( SerializationStrategy serializationStrategy )
+    {
+        this.serializationStrategy = serializationStrategy;
+        return this;
+    }
+
+    public InternalSerializerCreator setClassComparisonStrategy( ClassComparisonStrategy classComparisonStrategy )
+    {
+        this.classComparisonStrategy = classComparisonStrategy;
+        return this;
+    }
+
+    public InternalSerializerCreator setValueNullableEvaluator( ValueNullableEvaluator valueNullableEvaluator )
+    {
+        this.valueNullableEvaluator = valueNullableEvaluator;
+        return this;
+    }
+
+    public Serializer build()
+    {
+        PropertyDescriptorFactory propertyDescriptorFactory = new InternalPropertyDescriptorFactory( logger );
+        MarshallerStrategy marshallerStrategy = new InternalMarshallerStrategy();
+        DefinitionBuildingContext definitionBuildingContext =
+            new InternalDefinitionBuildingContext( marshallerStrategy, propertyDescriptorFactory );
+
+        DefinitionVisitor definitionVisitor = new InternalDefinitionVisitor();
+        for ( SerializerDefinition serializerDefinition : serializerDefinitions )
+        {
+            serializerDefinition.configure( definitionBuildingContext, objectInstantiatorFactory );
+            serializerDefinition.acceptVisitor( definitionVisitor );
+        }
+
+        Set<ClassDefinition> classDefinitions =
+            new HashSet<ClassDefinition>( Arrays.asList( ClassUtil.CLASS_DESCRIPTORS ) );
+        for ( InternalClassDescriptor classDescriptor : classDescriptors.values() )
+        {
+            classDefinitions.add( classDescriptor.build( ClassUtil.CLASS_DESCRIPTORS ).getClassDefinition() );
+        }
+
+        Map<Class<?>, ClassDescriptor> cleanedClassDescriptors =
+            new HashMap<Class<?>, ClassDescriptor>( classDescriptors.size() );
+        for ( Entry<Class<?>, InternalClassDescriptor> entry : classDescriptors.entrySet() )
+        {
+            cleanedClassDescriptors.put( entry.getKey(), entry.getValue() );
+        }
+
+        return new InternalSerializer( new InternalClassDefinitionContainer( classDefinitions ), serializationStrategy,
+                                       classComparisonStrategy, cleanedClassDescriptors, marshallers,
+                                       objectInstantiatorFactory, logger, marshallerStrategy, debugCacheDirectory,
+                                       valueNullableEvaluator );
+    }
+
+    private InternalClassDescriptor findClassDescriptor( Class<?> type )
+    {
+        InternalClassDescriptor classDescriptor = classDescriptors.get( type );
+        if ( classDescriptor == null )
+        {
+            classDescriptor = new InternalClassDescriptor( type, logger );
+            classDescriptors.put( type, classDescriptor );
+        }
+
+        return classDescriptor;
+    }
+
+    private class InternalDefinitionVisitor
+        implements DefinitionVisitor
+    {
+
+        private final Stack<Class<? extends Annotation>> attributeAnnotation = new Stack<Class<? extends Annotation>>();
+
+        @Override
+        public void visitSerializerDefinition( SerializerDefinition serializerDefinition )
+        {
+            // If at top level definition just add the base annotation
+            if ( attributeAnnotation.size() == 0 )
+            {
+                if ( InternalSerializerCreator.this.attributeAnnotation == null )
+                {
+                    attributeAnnotation.push( Attribute.class );
+                }
+                else
+                {
+                    attributeAnnotation.push( InternalSerializerCreator.this.attributeAnnotation );
+                }
+            }
+            else
+            {
+                Class<? extends Annotation> annotation = attributeAnnotation.peek();
+                attributeAnnotation.push( annotation );
+            }
+        }
+
+        @Override
+        public void visitAttributeAnnotation( Class<? extends Annotation> attributeAnnotation )
+        {
+            // Remove last element and replace it with the real annotation to
+            // use right from that moment
+            this.attributeAnnotation.pop();
+            this.attributeAnnotation.push( attributeAnnotation );
+        }
+
+        @Override
+        public void visitClassDefine( Type type, Marshaller marshaller )
+        {
+            Class<?> rawType = TypeUtil.getBaseType( type );
+            InternalClassDescriptor classDescriptor = findClassDescriptor( rawType );
+            classDescriptor.setMarshaller( marshaller );
+
+            marshallers.put( rawType, marshaller );
+        }
+
+        @Override
+        public void visitAnnotatedAttribute( PropertyDescriptor propertyDescriptor, Marshaller marshaller )
+        {
+            InternalClassDescriptor classDescriptor = findClassDescriptor( propertyDescriptor.getDefinedClass() );
+
+            if ( logger.isTraceEnabled() )
+            {
+                logger.trace( "Found property " + propertyDescriptor.getName() + " ("
+                    + propertyDescriptor.getInternalSignature() + ") on type "
+                    + propertyDescriptor.getDefinedClass().getCanonicalName() );
+            }
+
+            classDescriptor.push( propertyDescriptor );
+        }
+
+        @Override
+        public void visitPropertyDescriptor( PropertyDescriptor propertyDescriptor, Marshaller marshaller )
+        {
+            InternalClassDescriptor classDescriptor = findClassDescriptor( propertyDescriptor.getDefinedClass() );
+
+            if ( logger.isTraceEnabled() )
+            {
+                logger.trace( "Found property " + propertyDescriptor.getName() + " ("
+                    + propertyDescriptor.getInternalSignature() + ") on type "
+                    + propertyDescriptor.getDefinedClass().getCanonicalName() );
+            }
+
+            classDescriptor.push( propertyDescriptor );
+        }
+
+        @Override
+        public void visitFinalizeSerializerDefinition( SerializerDefinition serializerDefinition )
+        {
+            // Clean this level up
+            this.attributeAnnotation.pop();
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractPropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractPropertyAccessor.java
new file mode 100644
index 0000000..4860e3b
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractPropertyAccessor.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+abstract class AbstractPropertyAccessor
+    implements PropertyAccessor
+{
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractValuePropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractValuePropertyAccessor.java
new file mode 100644
index 0000000..7dbe2ea
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/AbstractValuePropertyAccessor.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import org.apache.directmemory.lightning.metadata.ValuePropertyAccessor;
+
+public abstract class AbstractValuePropertyAccessor
+    extends AbstractPropertyAccessor
+    implements ValuePropertyAccessor
+{
+
+    @Override
+    public boolean isArrayType()
+    {
+        return false;
+    }
+
+    @Override
+    public void writeShort( Object instance, short value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeLong( Object instance, long value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeInt( Object instance, int value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeFloat( Object instance, float value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeDouble( Object instance, double value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeChar( Object instance, char value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeByte( Object instance, byte value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public void writeBoolean( Object instance, boolean value )
+    {
+        writeObject( instance, value );
+    }
+
+    @Override
+    public short readShort( Object instance )
+    {
+        return (Short) readObject( instance );
+    }
+
+    @Override
+    public long readLong( Object instance )
+    {
+        return (Long) readObject( instance );
+    }
+
+    @Override
+    public int readInt( Object instance )
+    {
+        return (Integer) readObject( instance );
+    }
+
+    @Override
+    public float readFloat( Object instance )
+    {
+        return (Float) readObject( instance );
+    }
+
+    @Override
+    public double readDouble( Object instance )
+    {
+        return (Double) readObject( instance );
+    }
+
+    @Override
+    public char readChar( Object instance )
+    {
+        return (Character) readObject( instance );
+    }
+
+    @Override
+    public byte readByte( Object instance )
+    {
+        return (Byte) readObject( instance );
+    }
+
+    @Override
+    public boolean readBoolean( Object instance )
+    {
+        return (Boolean) readObject( instance );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldArrayPropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldArrayPropertyAccessor.java
new file mode 100644
index 0000000..6740168
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldArrayPropertyAccessor.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+
+import org.apache.directmemory.lightning.metadata.AccessorType;
+import org.apache.directmemory.lightning.metadata.ArrayPropertyAccessor;
+
+public abstract class FieldArrayPropertyAccessor
+    extends FieldValuePropertyAccessor
+    implements ArrayPropertyAccessor
+{
+
+    private final Field field;
+
+    private final Class<?> definedClass;
+
+    protected FieldArrayPropertyAccessor( Field field, Class<?> definedClass )
+    {
+        super( field, definedClass );
+        this.field = field;
+        this.definedClass = definedClass;
+    }
+
+    @Override
+    public boolean isArrayType()
+    {
+        return true;
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return definedClass;
+    }
+
+    @Override
+    public AccessorType getAccessorType()
+    {
+        return AccessorType.Field;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return field.getType();
+    }
+
+    @Override
+    protected Field getField()
+    {
+        return field;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldValuePropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldValuePropertyAccessor.java
new file mode 100644
index 0000000..4e50831
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/FieldValuePropertyAccessor.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+
+import org.apache.directmemory.lightning.metadata.AccessorType;
+
+public abstract class FieldValuePropertyAccessor
+    extends AbstractValuePropertyAccessor
+{
+
+    private final Field field;
+
+    private final Class<?> definedClass;
+
+    protected FieldValuePropertyAccessor( Field field, Class<?> definedClass )
+    {
+        this.field = field;
+        this.definedClass = definedClass;
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return definedClass;
+    }
+
+    @Override
+    public Class<?> getDeclaringClass()
+    {
+        return field.getDeclaringClass();
+    }
+
+    @Override
+    public AccessorType getAccessorType()
+    {
+        return AccessorType.Field;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return field.getType();
+    }
+
+    protected Field getField()
+    {
+        return field;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptor.java
new file mode 100644
index 0000000..83e0ceb
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptor.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.apache.directmemory.lightning.internal.util.StringUtil;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+class InternalPropertyDescriptor
+    implements PropertyDescriptor
+{
+
+    private final String name;
+
+    private final String propertyName;
+
+    private final String internalSignature;
+
+    private final String declaringCanonicalClassname;
+
+    private final Class<?> definedClass;
+
+    private final Class<?> declaringClass;
+
+    private final PropertyAccessor propertyAccessor;
+
+    private final Annotation[] annotations;
+
+    private final Marshaller marshaller;
+
+    InternalPropertyDescriptor( String propertyName, Marshaller marshaller, Annotation[] annotations,
+                                PropertyAccessor propertyAccessor )
+    {
+        this.name = StringUtil.toUpperCamelCase( propertyName );
+        this.propertyName = propertyName;
+        this.propertyAccessor = propertyAccessor;
+        this.marshaller = marshaller;
+        this.declaringCanonicalClassname = propertyAccessor.getType().getCanonicalName();
+        this.internalSignature = BeanUtil.buildInternalSignature( propertyName, propertyAccessor );
+        this.annotations = Arrays.copyOf( annotations, annotations.length );
+        this.definedClass = propertyAccessor.getDefinedClass();
+        this.declaringClass = propertyAccessor.getDeclaringClass();
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return definedClass;
+    }
+
+    @Override
+    public Class<?> getDeclaringClass()
+    {
+        return declaringClass;
+    }
+
+    @Override
+    public PropertyAccessor getPropertyAccessor()
+    {
+        return propertyAccessor;
+    }
+
+    @Override
+    public Annotation[] getAnnotations()
+    {
+        return Arrays.copyOf( annotations, annotations.length );
+    }
+
+    @Override
+    public String getName()
+    {
+        return name;
+    }
+
+    @Override
+    public String getPropertyName()
+    {
+        return propertyName;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return propertyAccessor.getType();
+    }
+
+    @Override
+    public String getInternalSignature()
+    {
+        return internalSignature;
+    }
+
+    @Override
+    public Marshaller getMarshaller()
+    {
+        return marshaller;
+    }
+
+    @Override
+    public int compareTo( PropertyDescriptor o )
+    {
+        return propertyName.compareTo( o.getPropertyName() );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Arrays.hashCode( annotations );
+        result =
+            prime * result + ( ( declaringCanonicalClassname == null ) ? 0 : declaringCanonicalClassname.hashCode() );
+        result = prime * result + ( ( declaringClass == null ) ? 0 : declaringClass.hashCode() );
+        result = prime * result + ( ( definedClass == null ) ? 0 : definedClass.hashCode() );
+        result = prime * result + ( ( internalSignature == null ) ? 0 : internalSignature.hashCode() );
+        result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
+        result = prime * result + ( ( propertyName == null ) ? 0 : propertyName.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        if ( this == obj )
+            return true;
+        if ( obj == null )
+            return false;
+        if ( getClass() != obj.getClass() )
+            return false;
+        InternalPropertyDescriptor other = (InternalPropertyDescriptor) obj;
+        if ( !Arrays.equals( annotations, other.annotations ) )
+            return false;
+        if ( declaringCanonicalClassname == null )
+        {
+            if ( other.declaringCanonicalClassname != null )
+                return false;
+        }
+        else if ( !declaringCanonicalClassname.equals( other.declaringCanonicalClassname ) )
+            return false;
+        if ( declaringClass == null )
+        {
+            if ( other.declaringClass != null )
+                return false;
+        }
+        else if ( !declaringClass.equals( other.declaringClass ) )
+            return false;
+        if ( definedClass == null )
+        {
+            if ( other.definedClass != null )
+                return false;
+        }
+        else if ( !definedClass.equals( other.definedClass ) )
+            return false;
+        if ( internalSignature == null )
+        {
+            if ( other.internalSignature != null )
+                return false;
+        }
+        else if ( !internalSignature.equals( other.internalSignature ) )
+            return false;
+        if ( name == null )
+        {
+            if ( other.name != null )
+                return false;
+        }
+        else if ( !name.equals( other.name ) )
+            return false;
+        if ( propertyName == null )
+        {
+            if ( other.propertyName != null )
+                return false;
+        }
+        else if ( !propertyName.equals( other.propertyName ) )
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "InternalPropertyDescriptor [name=" + name + ", propertyName=" + propertyName + ", internalSignature="
+            + internalSignature + ", declaringCanonicalClassname=" + declaringCanonicalClassname + ", definedClass="
+            + definedClass + ", declaringClass=" + declaringClass + ", propertyAccessor=" + propertyAccessor
+            + ", annotations=" + Arrays.toString( annotations ) + ", marshaller=" + marshaller + "]";
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptorFactory.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptorFactory.java
new file mode 100644
index 0000000..f206ca9
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/InternalPropertyDescriptorFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class InternalPropertyDescriptorFactory
+    implements PropertyDescriptorFactory
+{
+
+    private final PropertyAccessorStrategy propertyAccessorStrategy;
+
+    public InternalPropertyDescriptorFactory( Logger logger )
+    {
+        propertyAccessorStrategy = new PropertyAccessorStrategy( logger );
+    }
+
+    @Override
+    public PropertyDescriptor byMethod( Method method, Marshaller marshaller, Class<?> definedClass )
+    {
+        PropertyAccessor propertyAccessor = propertyAccessorStrategy.byMethod( method, definedClass );
+        String propertyName = BeanUtil.buildPropertyName( method );
+        return new InternalPropertyDescriptor( propertyName, marshaller, method.getAnnotations(), propertyAccessor );
+    }
+
+    @Override
+    public PropertyDescriptor byField( Field field, Marshaller marshaller, Class<?> definedClass )
+    {
+        PropertyAccessor propertyAccessor = propertyAccessorStrategy.byField( field, definedClass );
+        return new InternalPropertyDescriptor( field.getName(), marshaller, field.getAnnotations(), propertyAccessor );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodArrayPropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodArrayPropertyAccessor.java
new file mode 100644
index 0000000..7ebe96e
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodArrayPropertyAccessor.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.metadata.AccessorType;
+import org.apache.directmemory.lightning.metadata.ArrayPropertyAccessor;
+
+public abstract class MethodArrayPropertyAccessor
+    extends AbstractValuePropertyAccessor
+    implements ArrayPropertyAccessor
+{
+
+    private final Method setter;
+
+    private final Method getter;
+
+    private final Class<?> definedClass;
+
+    protected MethodArrayPropertyAccessor( Method setter, Method getter, Class<?> definedClass )
+    {
+        this.setter = setter;
+        this.getter = getter;
+        this.definedClass = definedClass;
+    }
+
+    @Override
+    public boolean isArrayType()
+    {
+        return true;
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return definedClass;
+    }
+
+    @Override
+    public Class<?> getDeclaringClass()
+    {
+        return getter.getDeclaringClass();
+    }
+
+    @Override
+    public AccessorType getAccessorType()
+    {
+        return AccessorType.Method;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return getter.getReturnType();
+    }
+
+    protected Method getGetterMethod()
+    {
+        return getter;
+    }
+
+    protected Method getSetterMethod()
+    {
+        return setter;
+    }
+
+    @Override
+    public void writeBoolean( Object instance, int index, boolean value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public boolean readBoolean( Object instance, int index )
+    {
+        return (Boolean) readObject( instance, index );
+    }
+
+    @Override
+    public void writeByte( Object instance, int index, byte value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public byte readByte( Object instance, int index )
+    {
+        return (Byte) readObject( instance, index );
+    }
+
+    @Override
+    public void writeChar( Object instance, int index, char value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public char readChar( Object instance, int index )
+    {
+        return (Character) readObject( instance, index );
+    }
+
+    @Override
+    public void writeShort( Object instance, int index, short value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public short readShort( Object instance, int index )
+    {
+        return (Short) readObject( instance, index );
+    }
+
+    @Override
+    public void writeInt( Object instance, int index, int value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public int readInt( Object instance, int index )
+    {
+        return (Integer) readObject( instance, index );
+    }
+
+    @Override
+    public void writeLong( Object instance, int index, long value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public long readLong( Object instance, int index )
+    {
+        return (Long) readObject( instance, index );
+    }
+
+    @Override
+    public void writeFloat( Object instance, int index, float value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public float readFloat( Object instance, int index )
+    {
+        return (Float) readObject( instance, index );
+    }
+
+    @Override
+    public void writeDouble( Object instance, int index, double value )
+    {
+        writeObject( instance, index, value );
+    }
+
+    @Override
+    public double readDouble( Object instance, int index )
+    {
+        return (Double) readObject( instance, index );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodValuePropertyAccessor.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodValuePropertyAccessor.java
new file mode 100644
index 0000000..7657c41
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/MethodValuePropertyAccessor.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.metadata.AccessorType;
+
+public abstract class MethodValuePropertyAccessor
+    extends AbstractValuePropertyAccessor
+{
+
+    private final Method setter;
+
+    private final Method getter;
+
+    private final Class<?> definedClass;
+
+    protected MethodValuePropertyAccessor( Method setter, Method getter, Class<?> definedClass )
+    {
+        this.setter = setter;
+        this.getter = getter;
+        this.definedClass = definedClass;
+    }
+
+    @Override
+    public Class<?> getDefinedClass()
+    {
+        return definedClass;
+    }
+
+    @Override
+    public Class<?> getDeclaringClass()
+    {
+        return getter.getDeclaringClass();
+    }
+
+    @Override
+    public AccessorType getAccessorType()
+    {
+        return AccessorType.Method;
+    }
+
+    @Override
+    public Class<?> getType()
+    {
+        return getter.getReturnType();
+    }
+
+    protected Method getGetterMethod()
+    {
+        return getter;
+    }
+
+    protected Method getSetterMethod()
+    {
+        return setter;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorFactory.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorFactory.java
new file mode 100644
index 0000000..ff447c3
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+public interface PropertyAccessorFactory
+{
+
+    PropertyAccessor fieldAccess( Field field, Class<?> definedClass );
+
+    PropertyAccessor methodAccess( Method method, Class<?> definedClass );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorStrategy.java
new file mode 100644
index 0000000..ca276ce
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/PropertyAccessorStrategy.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.internal.util.InternalUtil;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+public class PropertyAccessorStrategy
+{
+
+    private final PropertyAccessorFactory reflectionPropertyAccessorFactory = new ReflectionPropertyAccessorFactory();
+
+    private final PropertyAccessorFactory reflectASMPropertyAccessorFactory = new ReflectASMPropertyAccessorFactory();
+
+    private final PropertyAccessorFactory sunUnsafePropertyAccessorFactory;
+
+    private final Logger logger;
+
+    PropertyAccessorStrategy( Logger logger )
+    {
+        this.logger = logger.getChildLogger( getClass() );
+
+        PropertyAccessorFactory factory = null;
+        if ( InternalUtil.isUnsafeAvailable() )
+        {
+            factory = InternalUtil.buildSunUnsafePropertyAccessor();
+            this.logger.trace( "Found sun.misc.Unsafe" );
+        }
+        sunUnsafePropertyAccessorFactory = factory;
+    }
+
+    PropertyAccessor byField( Field field, Class<?> definedClass )
+    {
+        PropertyAccessor propertyAccessor = null;
+        if ( sunUnsafePropertyAccessorFactory != null )
+        {
+            propertyAccessor = sunUnsafePropertyAccessorFactory.fieldAccess( field, definedClass );
+        }
+
+        if ( propertyAccessor == null )
+        {
+            propertyAccessor = reflectASMPropertyAccessorFactory.fieldAccess( field, definedClass );
+        }
+
+        if ( propertyAccessor != null )
+        {
+            return propertyAccessor;
+        }
+
+        return reflectionPropertyAccessorFactory.fieldAccess( field, definedClass );
+    }
+
+    PropertyAccessor byMethod( Method method, Class<?> definedClass )
+    {
+        PropertyAccessor propertyAccessor = reflectASMPropertyAccessorFactory.methodAccess( method, definedClass );
+        if ( propertyAccessor != null )
+        {
+            return propertyAccessor;
+        }
+
+        return reflectionPropertyAccessorFactory.methodAccess( method, definedClass );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectASMPropertyAccessorFactory.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectASMPropertyAccessorFactory.java
new file mode 100644
index 0000000..892d0ec
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectASMPropertyAccessorFactory.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+import com.esotericsoftware.reflectasm.FieldAccess;
+import com.esotericsoftware.reflectasm.MethodAccess;
+
+public class ReflectASMPropertyAccessorFactory
+    implements PropertyAccessorFactory
+{
+
+    private final Map<Class<?>, MethodAccess> methodAccessCache = new HashMap<Class<?>, MethodAccess>();
+
+    private final Map<Class<?>, FieldAccess> fieldAccessCache = new HashMap<Class<?>, FieldAccess>();
+
+    @Override
+    public PropertyAccessor fieldAccess( Field field, Class<?> definedClass )
+    {
+        if ( field.getType().isArray() )
+        {
+            return null;
+        }
+
+        try
+        {
+            return buildForField( field, definedClass );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            // If field is not public
+            return null;
+        }
+    }
+
+    @Override
+    public PropertyAccessor methodAccess( Method method, Class<?> definedClass )
+    {
+        if ( method.getReturnType().isArray() )
+        {
+            return null;
+        }
+
+        try
+        {
+            return buildForMethod( method, definedClass );
+        }
+        catch ( IllegalArgumentException e )
+        {
+            return null;
+        }
+    }
+
+    private FieldAccess getFieldAccess( Field field )
+    {
+        Class<?> declaringClass = field.getDeclaringClass();
+
+        FieldAccess fieldAccess = fieldAccessCache.get( declaringClass );
+        if ( fieldAccess != null )
+        {
+            return fieldAccess;
+        }
+
+        fieldAccess = FieldAccess.get( declaringClass );
+        fieldAccessCache.put( declaringClass, fieldAccess );
+
+        return fieldAccess;
+    }
+
+    private MethodAccess getMethodAccess( Method method )
+    {
+        Class<?> definedClass = method.getDeclaringClass();
+
+        MethodAccess methodAccess = methodAccessCache.get( definedClass );
+        if ( methodAccess != null )
+        {
+            return methodAccess;
+        }
+
+        methodAccess = MethodAccess.get( definedClass );
+        methodAccessCache.put( definedClass, methodAccess );
+
+        return methodAccess;
+    }
+
+    private PropertyAccessor buildForField( Field field, Class<?> definedClass )
+    {
+        final FieldAccess fieldAccess = getFieldAccess( field );
+        final int fieldIndex = fieldAccess.getIndex( field.getName() );
+        return new FieldValuePropertyAccessor( field, definedClass )
+        {
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                fieldAccess.set( instance, fieldIndex, value );
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                return (T) fieldAccess.get( instance, fieldIndex );
+            }
+        };
+    }
+
+    private PropertyAccessor buildForMethod( Method method, Class<?> definedClass )
+    {
+        final MethodAccess methodAccess = getMethodAccess( method );
+
+        Method getter = BeanUtil.findGetterMethod( method );
+        Method setter = BeanUtil.findSetterMethod( method );
+
+        final int getterMethodIndex = methodAccess.getIndex( getter.getName(), method.getParameterTypes() );
+        final int setterMethodIndex = methodAccess.getIndex( setter.getName(), method.getParameterTypes() );
+
+        return new MethodValuePropertyAccessor( setter, getter, definedClass )
+        {
+
+            @Override
+            public void writeShort( Object instance, short value )
+            {
+                writeObject( instance, value );
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                methodAccess.invoke( instance, setterMethodIndex, value );
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                return (T) methodAccess.invoke( instance, getterMethodIndex );
+            }
+
+        };
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorFactory.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorFactory.java
new file mode 100644
index 0000000..7838179
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorFactory.java
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.exceptions.IllegalPropertyAccessException;
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+public class ReflectionPropertyAccessorFactory
+    implements PropertyAccessorFactory
+{
+
+    @Override
+    public PropertyAccessor fieldAccess( Field field, Class<?> definedClass )
+    {
+        if ( field.getType().isArray() )
+        {
+            return buildForArrayField( field, definedClass );
+        }
+
+        return buildForValueField( field, definedClass );
+    }
+
+    @Override
+    public PropertyAccessor methodAccess( Method method, Class<?> definedClass )
+    {
+        if ( method.getReturnType().isArray() )
+        {
+            return buildForArrayMethod( method, definedClass );
+        }
+
+        return buildForValueMethod( method, definedClass );
+    }
+
+    private PropertyAccessor buildForValueField( final Field field, final Class<?> definedClass )
+    {
+        field.setAccessible( true );
+        return new FieldValuePropertyAccessor( field, definedClass )
+        {
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                try
+                {
+                    getField().set( instance, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                try
+                {
+                    return (T) getField().get( instance );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+        };
+    }
+
+    private PropertyAccessor buildForArrayField( final Field field, final Class<?> definedClass )
+    {
+        field.setAccessible( true );
+        return new FieldArrayPropertyAccessor( field, definedClass )
+        {
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                try
+                {
+                    getField().set( instance, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                try
+                {
+                    return (T) getField().get( instance );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, int index, T value )
+            {
+                try
+                {
+                    Array.set( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance, int index )
+            {
+                try
+                {
+                    return (T) Array.get( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeShort( Object instance, int index, short value )
+            {
+                try
+                {
+                    Array.setShort( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeLong( Object instance, int index, long value )
+            {
+                try
+                {
+                    Array.setLong( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeInt( Object instance, int index, int value )
+            {
+                try
+                {
+                    Array.setInt( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeFloat( Object instance, int index, float value )
+            {
+                try
+                {
+                    Array.setFloat( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeDouble( Object instance, int index, double value )
+            {
+                try
+                {
+                    Array.setDouble( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeChar( Object instance, int index, char value )
+            {
+                try
+                {
+                    Array.setChar( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeByte( Object instance, int index, byte value )
+            {
+                try
+                {
+                    Array.setByte( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public void writeBoolean( Object instance, int index, boolean value )
+            {
+                try
+                {
+                    Array.setBoolean( instance, index, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public short readShort( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getShort( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public long readLong( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getLong( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public int readInt( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getInt( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public float readFloat( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getFloat( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public double readDouble( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getDouble( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public char readChar( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getChar( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public byte readByte( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getByte( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+
+            @Override
+            public boolean readBoolean( Object instance, int index )
+            {
+                try
+                {
+                    return Array.getBoolean( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading field " + getField().getName(),
+                                                              e );
+                }
+            }
+        };
+    }
+
+    private PropertyAccessor buildForValueMethod( Method method, Class<?> definedClass )
+    {
+        Method getter = BeanUtil.findGetterMethod( method );
+        Method setter = BeanUtil.findSetterMethod( method );
+
+        getter.setAccessible( true );
+        setter.setAccessible( true );
+
+        return new MethodValuePropertyAccessor( setter, getter, definedClass )
+        {
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                try
+                {
+                    getSetterMethod().invoke( instance, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing with method "
+                        + getSetterMethod().getName(), e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                try
+                {
+                    return (T) getGetterMethod().invoke( instance );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading with method "
+                        + getGetterMethod().getName(), e );
+                }
+            }
+        };
+    }
+
+    private PropertyAccessor buildForArrayMethod( Method method, Class<?> definedClass )
+    {
+        final Method getter = BeanUtil.findGetterMethod( method );
+        final Method setter = BeanUtil.findSetterMethod( method );
+        final Method arrayGetter = BeanUtil.findArrayGetterMethod( method );
+        final Method arraySetter = BeanUtil.findArraySetterMethod( method );
+
+        getter.setAccessible( true );
+        setter.setAccessible( true );
+
+        return new MethodArrayPropertyAccessor( setter, getter, definedClass )
+        {
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                try
+                {
+                    getSetterMethod().invoke( instance, value );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing with method "
+                        + getSetterMethod().getName(), e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                try
+                {
+                    return (T) getGetterMethod().invoke( instance );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading with method "
+                        + getGetterMethod().getName(), e );
+                }
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, int index, T value )
+            {
+                try
+                {
+                    arraySetter.invoke( instance, value, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while writing with method "
+                        + getSetterMethod().getName(), e );
+                }
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance, int index )
+            {
+                try
+                {
+                    return (T) arrayGetter.invoke( instance, index );
+                }
+                catch ( Exception e )
+                {
+                    throw new IllegalPropertyAccessException( "Exception while reading with method "
+                        + getGetterMethod().getName(), e );
+                }
+            }
+        };
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/SunUnsafePropertyAccessorFactory.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/SunUnsafePropertyAccessorFactory.java
new file mode 100644
index 0000000..c59c4d2
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/SunUnsafePropertyAccessorFactory.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.internal.util.UnsafeUtil;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+
+@SuppressWarnings( "restriction" )
+final class SunUnsafePropertyAccessorFactory
+    implements PropertyAccessorFactory
+{
+
+    private static final sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe();
+
+    SunUnsafePropertyAccessorFactory()
+    {
+    }
+
+    @Override
+    public PropertyAccessor fieldAccess( Field field, Class<?> definedClass )
+    {
+        if ( field.getType().isArray() )
+        {
+            return buildForArrayField( field, definedClass );
+        }
+
+        return buildForValueField( field, definedClass );
+    }
+
+    @Override
+    public PropertyAccessor methodAccess( Method method, Class<?> definedClass )
+    {
+        throw new UnsupportedOperationException( "Method access is not supported by Unsafe style" );
+    }
+
+    private PropertyAccessor buildForValueField( final Field field, final Class<?> definedClass )
+    {
+        return new FieldValuePropertyAccessor( field, definedClass )
+        {
+
+            private final long offset;
+
+            {
+                offset = UNSAFE.objectFieldOffset( field );
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                UNSAFE.putObject( instance, offset, value );
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                return (T) UNSAFE.getObject( instance, offset );
+            }
+
+            @Override
+            public void writeBoolean( Object instance, boolean value )
+            {
+                UNSAFE.putBoolean( instance, offset, value );
+            }
+
+            @Override
+            public boolean readBoolean( Object instance )
+            {
+                return UNSAFE.getBoolean( instance, offset );
+            }
+
+            @Override
+            public void writeByte( Object instance, byte value )
+            {
+                UNSAFE.putByte( instance, offset, value );
+            }
+
+            @Override
+            public byte readByte( Object instance )
+            {
+                return UNSAFE.getByte( instance, offset );
+            }
+
+            @Override
+            public void writeShort( Object instance, short value )
+            {
+                UNSAFE.putShort( instance, offset, value );
+            }
+
+            @Override
+            public short readShort( Object instance )
+            {
+                return UNSAFE.getShort( instance, offset );
+            }
+
+            @Override
+            public void writeChar( Object instance, char value )
+            {
+                UNSAFE.putChar( instance, offset, value );
+            }
+
+            @Override
+            public char readChar( Object instance )
+            {
+                return UNSAFE.getChar( instance, offset );
+            }
+
+            @Override
+            public void writeInt( Object instance, int value )
+            {
+                UNSAFE.putInt( instance, offset, value );
+            }
+
+            @Override
+            public int readInt( Object instance )
+            {
+                return UNSAFE.getInt( instance, offset );
+            }
+
+            @Override
+            public void writeLong( Object instance, long value )
+            {
+                UNSAFE.putLong( instance, offset, value );
+            }
+
+            @Override
+            public long readLong( Object instance )
+            {
+                return UNSAFE.getLong( instance, offset );
+            }
+
+            @Override
+            public void writeFloat( Object instance, float value )
+            {
+                UNSAFE.putFloat( instance, offset, value );
+            }
+
+            @Override
+            public float readFloat( Object instance )
+            {
+                return UNSAFE.getFloat( instance, offset );
+            }
+
+            @Override
+            public void writeDouble( Object instance, double value )
+            {
+                UNSAFE.putDouble( instance, offset, value );
+            }
+
+            @Override
+            public double readDouble( Object instance )
+            {
+                return UNSAFE.getDouble( instance, offset );
+            }
+        };
+    }
+
+    private PropertyAccessor buildForArrayField( final Field field, final Class<?> definedClass )
+    {
+        return new FieldArrayPropertyAccessor( field, definedClass )
+        {
+
+            private final long offset;
+
+            private final int arrayBaseOffset;
+
+            private final int arrayIndexScale;
+
+            {
+                offset = UNSAFE.objectFieldOffset( field );
+                arrayBaseOffset = UNSAFE.arrayBaseOffset( field.getType() );
+                arrayIndexScale = UNSAFE.arrayIndexScale( field.getType() );
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, T value )
+            {
+                UNSAFE.putObject( instance, offset, value );
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance )
+            {
+                return (T) UNSAFE.getObject( instance, offset );
+            }
+
+            @Override
+            public <T> void writeObject( Object instance, int index, T value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putObject( instance, offset, value );
+            }
+
+            @Override
+            @SuppressWarnings( "unchecked" )
+            public <T> T readObject( Object instance, int index )
+            {
+                long localOffset = calculateIndexOffset( index );
+                return (T) UNSAFE.getObject( instance, localOffset );
+            }
+
+            @Override
+            public void writeBoolean( Object instance, int index, boolean value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putBoolean( instance, offset, value );
+            }
+
+            @Override
+            public boolean readBoolean( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getBoolean( instance, offset );
+            }
+
+            @Override
+            public void writeByte( Object instance, int index, byte value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putByte( instance, offset, value );
+            }
+
+            @Override
+            public byte readByte( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getByte( instance, offset );
+            }
+
+            @Override
+            public void writeShort( Object instance, int index, short value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putShort( instance, offset, value );
+            }
+
+            @Override
+            public short readShort( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getShort( instance, offset );
+            }
+
+            @Override
+            public void writeChar( Object instance, int index, char value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putChar( instance, offset, value );
+            }
+
+            @Override
+            public char readChar( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getChar( instance, offset );
+            }
+
+            @Override
+            public void writeInt( Object instance, int index, int value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putInt( instance, offset, value );
+            }
+
+            @Override
+            public int readInt( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getInt( instance, offset );
+            }
+
+            @Override
+            public void writeLong( Object instance, int index, long value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putLong( instance, offset, value );
+            }
+
+            @Override
+            public long readLong( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getLong( instance, offset );
+            }
+
+            @Override
+            public void writeFloat( Object instance, int index, float value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putFloat( instance, offset, value );
+            }
+
+            @Override
+            public float readFloat( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getFloat( instance, offset );
+            }
+
+            @Override
+            public void writeDouble( Object instance, int index, double value )
+            {
+                long offset = calculateIndexOffset( index );
+                UNSAFE.putDouble( instance, offset, value );
+            }
+
+            @Override
+            public double readDouble( Object instance, int index )
+            {
+                long offset = calculateIndexOffset( index );
+                return UNSAFE.getDouble( instance, offset );
+            }
+
+            private long calculateIndexOffset( int index )
+            {
+                return arrayBaseOffset + ( index * arrayIndexScale );
+            }
+        };
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/introspection/AnnotatedTypeIntrospector.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/introspection/AnnotatedTypeIntrospector.java
new file mode 100644
index 0000000..05e7c24
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/beans/introspection/AnnotatedTypeIntrospector.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans.introspection;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.configuration.TypeIntrospector;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class AnnotatedTypeIntrospector
+    implements TypeIntrospector
+{
+
+    private final Class<? extends Annotation> annotationType;
+
+    private final List<String> excludes;
+
+    public AnnotatedTypeIntrospector( Class<? extends Annotation> annotationType, List<String> excludes )
+    {
+        this.annotationType = annotationType;
+        this.excludes = excludes;
+    }
+
+    @Override
+    public List<PropertyDescriptor> introspect( Type type, MarshallerStrategy marshallerStrategy,
+                                                MarshallerContext marshallerContext,
+                                                PropertyDescriptorFactory propertyDescriptorFactory )
+    {
+
+        if ( !( type instanceof Class ) )
+        {
+            return Collections.emptyList();
+        }
+
+        Class<?> clazz = (Class<?>) type;
+        Set<Field> properties = BeanUtil.findPropertiesByClass( clazz, annotationType );
+
+        List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
+        for ( Field property : properties )
+        {
+            if ( isExcluded( property.getName() ) )
+            {
+                continue;
+            }
+
+            Class<?> fieldType = property.getType();
+
+            Marshaller marshaller = marshallerStrategy.getMarshaller( fieldType, marshallerContext, false );
+
+            if ( marshaller == null && fieldType.isArray() )
+            {
+                marshaller = marshallerStrategy.getMarshaller( fieldType.getComponentType(), marshallerContext, false );
+            }
+
+            if ( marshaller instanceof TypeBindableMarshaller )
+            {
+                Type[] typeArguments = TypeUtil.getTypeArgument( property.getGenericType() );
+                marshaller = ( (TypeBindableMarshaller) marshaller ).bindType( typeArguments );
+            }
+
+            propertyDescriptors.add( propertyDescriptorFactory.byField( property, marshaller, clazz ) );
+        }
+
+        return propertyDescriptors;
+    }
+
+    private boolean isExcluded( String propertyName )
+    {
+        return excludes.contains( propertyName );
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/AbstractGeneratedMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/AbstractGeneratedMarshaller.java
new file mode 100644
index 0000000..ab8b9bb
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/AbstractGeneratedMarshaller.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.exceptions.SerializerDefinitionException;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public abstract class AbstractGeneratedMarshaller
+    implements Marshaller
+{
+
+    private final Class<?> clazz;
+
+    private final Map<Class<?>, Marshaller> marshallers;
+
+    private final ClassDescriptor classDescriptor;
+
+    private final List<PropertyDescriptor> propertyDescriptors;
+
+    private final ObjectInstantiator objectInstantiator;
+
+    public AbstractGeneratedMarshaller( Class<?> clazz, Map<Class<?>, Marshaller> marshallers,
+                                        ClassDescriptorAwareSerializer serializer,
+                                        ObjectInstantiatorFactory objectInstantiatorFactory )
+    {
+
+        this.clazz = clazz;
+        this.marshallers = marshallers;
+        this.classDescriptor = serializer.findClassDescriptor( clazz );
+        this.propertyDescriptors = Collections.unmodifiableList( classDescriptor.getPropertyDescriptors() );
+        this.objectInstantiator = objectInstantiatorFactory.getInstantiatorOf( clazz );
+    }
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return clazz.isAssignableFrom( type );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( serializationContext.getSerializationStrategy() == SerializationStrategy.SizeOptimized )
+        {
+            if ( ClassUtil.isReferenceCapable( propertyDescriptor.getType() ) )
+            {
+                long referenceId = dataInput.readLong();
+                V instance;
+                if ( containsReferenceId( referenceId, serializationContext ) )
+                {
+                    instance = (V) findObjectByReferenceId( referenceId, serializationContext );
+                }
+                else
+                {
+                    // Instance not yet received, for first time deserialize it
+                    instance = unmarshall( (V) newInstance(), propertyDescriptor, dataInput, serializationContext );
+                    cacheObjectForUnmarshall( referenceId, instance, serializationContext );
+                }
+
+                return instance;
+            }
+        }
+
+        V value = null;
+        if ( !propertyDescriptor.getType().isArray() )
+        {
+            value = (V) newInstance();
+        }
+
+        return unmarshall( value, propertyDescriptor, dataInput, serializationContext );
+    }
+
+    protected abstract <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                         SerializationContext serializationContext )
+        throws IOException;
+
+    protected boolean isAlreadyMarshalled( Object value, Class<?> type, DataOutput dataOutput,
+                                           SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( serializationContext.getSerializationStrategy() != SerializationStrategy.SizeOptimized )
+        {
+            return false;
+        }
+
+        if ( !ClassUtil.isReferenceCapable( type ) )
+        {
+            return false;
+        }
+
+        long referenceId = findReferenceIdByObject( value, serializationContext );
+        if ( referenceId == -1 )
+        {
+            referenceId = cacheObjectForMarshall( value, serializationContext );
+            dataOutput.writeLong( referenceId );
+            return false;
+        }
+
+        dataOutput.writeLong( referenceId );
+        return true;
+    }
+
+    protected ClassDescriptor getClassDescriptor()
+    {
+        return classDescriptor;
+    }
+
+    protected Object newInstance()
+    {
+        return objectInstantiator.newInstance();
+    }
+
+    protected PropertyDescriptor getPropertyDescriptor( String propertyName )
+    {
+        for ( PropertyDescriptor propertyDescriptor : propertyDescriptors )
+        {
+            if ( propertyDescriptor.getPropertyName().equals( propertyName ) )
+            {
+                return propertyDescriptor;
+            }
+        }
+
+        // This should never happen
+        return null;
+    }
+
+    protected PropertyAccessor getPropertyAccessor( String propertyName )
+    {
+        return getPropertyDescriptor( propertyName ).getPropertyAccessor();
+    }
+
+    protected Marshaller findMarshaller( PropertyDescriptor propertyDescriptor )
+    {
+        if ( propertyDescriptor.getMarshaller() != null )
+        {
+            return propertyDescriptor.getMarshaller();
+        }
+
+        Marshaller marshaller = marshallers.get( propertyDescriptor.getType() );
+        if ( marshaller != null )
+        {
+            return marshaller;
+        }
+
+        return new DelegatingMarshaller( propertyDescriptor );
+    }
+
+    protected long findReferenceIdByObject( Object instance, SerializationContext serializationContext )
+    {
+        return serializationContext.findReferenceIdByObject( instance );
+    }
+
+    protected Object findObjectByReferenceId( long referenceId, SerializationContext serializationContext )
+    {
+        return serializationContext.findObjectByReferenceId( referenceId );
+    }
+
+    protected boolean containsReferenceId( long referenceId, SerializationContext serializationContext )
+    {
+        return serializationContext.containsReferenceId( referenceId );
+    }
+
+    protected long cacheObjectForMarshall( Object instance, SerializationContext serializationContext )
+    {
+        return serializationContext.putMarshalledInstance( instance );
+    }
+
+    protected long cacheObjectForUnmarshall( long referenceId, Object instance,
+                                             SerializationContext serializationContext )
+    {
+        return serializationContext.putUnmarshalledInstance( referenceId, instance );
+    }
+
+    private class DelegatingMarshaller
+        implements Marshaller
+    {
+
+        private final PropertyDescriptor marshalledProperty;
+
+        private Marshaller marshaller;
+
+        private DelegatingMarshaller( PropertyDescriptor marshalledProperty )
+        {
+            this.marshalledProperty = marshalledProperty;
+        }
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return marshalledProperty.getType().isAssignableFrom( type );
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+
+            Marshaller marshaller = this.marshaller;
+            if ( marshaller == null )
+            {
+                marshaller = getMarshaller();
+            }
+
+            if ( marshaller == null )
+            {
+                throw new SerializerDefinitionException( "No marshaller for property " + marshalledProperty + " found" );
+            }
+
+            marshaller.marshall( value, propertyDescriptor, dataOutput, serializationContext );
+        }
+
+        @Override
+        public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+            Marshaller marshaller = this.marshaller;
+            if ( marshaller == null )
+            {
+                marshaller = getMarshaller();
+            }
+
+            if ( marshaller == null )
+            {
+                throw new SerializerDefinitionException( "No marshaller for property " + marshalledProperty + " found" );
+            }
+
+            return marshaller.unmarshall( propertyDescriptor, dataInput, serializationContext );
+        }
+
+        private synchronized Marshaller getMarshaller()
+        {
+            if ( marshaller == null )
+            {
+                marshaller = findMarshaller( marshalledProperty );
+            }
+            return marshaller;
+        }
+
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/BytecodeMarshallerGenerator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/BytecodeMarshallerGenerator.java
new file mode 100644
index 0000000..b47a3d3
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/BytecodeMarshallerGenerator.java
@@ -0,0 +1,902 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.exceptions.SerializerMarshallerGeneratorException;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.internal.InternalMarshallerStrategy;
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class BytecodeMarshallerGenerator
+    implements Opcodes, GeneratorConstants, MarshallerGenerator
+{
+
+    private final GeneratorClassLoader classloader = CreateClassLoader.createClassLoader( getClass().getClassLoader() );
+
+    @Override
+    public Marshaller generateMarshaller( Class<?> type, List<PropertyDescriptor> propertyDescriptors,
+                                          Map<Class<?>, Marshaller> marshallers,
+                                          ClassDescriptorAwareSerializer serializer,
+                                          SerializationStrategy serializationStrategy,
+                                          ObjectInstantiatorFactory objectInstantiatorFactory, File debugCacheDirectory )
+    {
+
+        try
+        {
+            ClassWriter cw = new ClassWriter( 0 );
+
+            // Copy properties and sort them by name
+            List<PropertyDescriptor> propertyDescriptorsCopy = new ArrayList<PropertyDescriptor>( propertyDescriptors );
+            Collections.sort( propertyDescriptorsCopy );
+
+            // Build className e.g. "SomeTypeMarshaller$$X$$Lightning"
+            String className =
+                new StringBuilder( !type.isArray() ? type.getSimpleName() : type.getComponentType().getSimpleName()
+                    + "Array" ).append( "Marshaller" ).append( GENEREATED_CLASS_ID.getAndIncrement() ).append( "Lightning" ).toString();
+
+            // Build class
+            cw.visit( V1_6, ACC_PUBLIC & ACC_SUPER, className, null, SUPER_CLASS_INTERNAL_TYPE, null );
+
+            // Build marshaller fields
+            createMarshallerFields( cw, propertyDescriptorsCopy );
+
+            // Build constructor
+            createConstructor( cw, className, propertyDescriptorsCopy );
+
+            // Build Marshaller#marshall method
+            createMarshallMethod( cw, className, type, serializationStrategy, propertyDescriptorsCopy );
+
+            // Build Marshaller#unmarshall method
+            createUnmarshallMethod( cw, className, type, propertyDescriptorsCopy );
+
+            // Closing class visit
+            cw.visitEnd();
+
+            final byte[] bytecode = cw.toByteArray();
+
+            if ( debugCacheDirectory != null )
+            {
+                File file = new File( debugCacheDirectory, className + ".class" );
+                FileOutputStream out = new FileOutputStream( file );
+                out.write( bytecode );
+                out.flush();
+                out.close();
+            }
+
+            Class<? extends Marshaller> generatedClass = classloader.loadClass( bytecode );
+            Constructor<? extends Marshaller> constructor =
+                generatedClass.getConstructor( Class.class, Map.class, ClassDescriptorAwareSerializer.class,
+                                               ObjectInstantiatorFactory.class, List.class, MarshallerStrategy.class );
+
+            constructor.setAccessible( true );
+            return constructor.newInstance( type, marshallers, serializer, objectInstantiatorFactory,
+                                            propertyDescriptorsCopy, new InternalMarshallerStrategy() );
+        }
+        catch ( Exception e )
+        {
+            throw new SerializerMarshallerGeneratorException(
+                                                              "Marshaller for type " + type + " could not be generated",
+                                                              e );
+        }
+    }
+
+    private void createMarshallerFields( ClassWriter cw, List<PropertyDescriptor> propertyDescriptors )
+    {
+        for ( int i = 0; i < propertyDescriptors.size(); i++ )
+        {
+            PropertyDescriptor propertyDescriptor = propertyDescriptors.get( i );
+            FieldVisitor fv = null;
+
+            // Write PropertyDescriptor field
+            fv =
+                cw.visitField( ACC_FINAL & ACC_PRIVATE, toFinalFieldName( "descriptor", propertyDescriptor ),
+                               PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR, null, null );
+            fv.visitEnd();
+
+            if ( propertyDescriptor.getType().isArray()
+                && !propertyDescriptor.getType().getComponentType().isPrimitive() )
+            {
+                // Write ComponentType PropertyDescriptor field
+                fv =
+                    cw.visitField( ACC_FINAL & ACC_PRIVATE, toFinalFieldName( "component", propertyDescriptor ),
+                                   CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR, null, null );
+                fv.visitEnd();
+            }
+
+            // Write Marshaller field
+            fv =
+                cw.visitField( ACC_FINAL & ACC_PRIVATE, toFinalFieldName( "marshaller", propertyDescriptor ),
+                               MARSHALLER_CLASS_DESCRIPTOR, null, null );
+            fv.visitEnd();
+
+            // Write PropertyAccessor field
+            fv =
+                cw.visitField( ACC_FINAL & ACC_PRIVATE, toFinalFieldName( "accessor", propertyDescriptor ),
+                               PROPERTYACCESSOR_CLASS_DESCRIPTOR, null, null );
+            fv.visitEnd();
+        }
+    }
+
+    private void createConstructor( ClassWriter cw, String className, List<PropertyDescriptor> propertyDescriptors )
+    {
+        MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "<init>", MARSHALLER_CONSTRUCTOR_SIGNATURE, null, null );
+        mv.visitCode();
+
+        // Load this
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Load first parameter type (Class)
+        mv.visitVarInsn( ALOAD, 1 );
+
+        // Load second parameter type (Map)
+        mv.visitVarInsn( ALOAD, 2 );
+
+        // Load third parameter type (ClassDescriptorAwaySerializer)
+        mv.visitVarInsn( ALOAD, 3 );
+
+        // Load fourth parameter type (ObjenesisSerializer)
+        mv.visitVarInsn( ALOAD, 4 );
+
+        // Call super(Class, Map)
+        mv.visitMethodInsn( INVOKESPECIAL, SUPER_CLASS_INTERNAL_TYPE, "<init>", MARSHALLER_SUPER_CONSTRUCTOR_SIGNATURE );
+
+        // Fill fields with marshallers
+        for ( int i = 0; i < propertyDescriptors.size(); i++ )
+        {
+            PropertyDescriptor propertyDescriptor = propertyDescriptors.get( i );
+            String fieldName = toFinalFieldName( "marshaller", propertyDescriptor );
+            mv.visitVarInsn( ALOAD, 0 );
+            mv.visitVarInsn( ALOAD, 0 );
+
+            // Load property type
+            mv.visitVarInsn( ALOAD, 5 );
+            mv.visitIntInsn( BIPUSH, i );
+            mv.visitMethodInsn( INVOKEINTERFACE, LIST_CLASS_INTERNAL_TYPE, "get", "(I)Ljava/lang/Object;" );
+
+            // Store PropertyDescriptor
+            mv.visitTypeInsn( CHECKCAST, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE );
+            mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                               PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+
+            if ( propertyDescriptor.getType().isArray()
+                && !propertyDescriptor.getType().getComponentType().isPrimitive() )
+            {
+                Label labelNonNull = new Label();
+
+                // Get type from PropertyAccessor
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                                   PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+                mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "getType",
+                                    "()Ljava/lang/Class;" );
+
+                // Get array component type
+                mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_CLASS_INTERNAL_TYPE, "getComponentType",
+                                    CLASS_GET_COMPONENT_TYPE );
+                mv.visitVarInsn( ASTORE, 9 );
+
+                // Generate cheating PropertyDescriptor for component type
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitTypeInsn( NEW, CHEATINGPROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE );
+                mv.visitInsn( DUP );
+                mv.visitLdcInsn( propertyDescriptor.getPropertyName() + "Element" );
+                mv.visitVarInsn( ALOAD, 9 );
+                mv.visitInsn( ACONST_NULL );
+                mv.visitMethodInsn( INVOKESPECIAL, CHEATINGPROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "<init>",
+                                    CHEATINGPROPERTYDESCRIPTOR_CONSTRUCTOR );
+                mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
+                                   CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+
+                // Search marshaller by using interal ones
+                mv.visitVarInsn( ALOAD, 6 );
+                mv.visitVarInsn( ALOAD, 9 );
+                mv.visitInsn( ACONST_NULL );
+                mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLERSTRATEGY_CLASS_INTERNAL_TYPE, "getMarshaller",
+                                    MARSHALLERSTRATEGY_GET_MARSHALLER_SIGNATURE );
+                mv.visitVarInsn( ASTORE, 8 );
+                mv.visitVarInsn( ALOAD, 8 );
+
+                // Search marshaller for property type
+                mv.visitJumpInsn( IFNONNULL, labelNonNull );
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
+                                   CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+                mv.visitMethodInsn( INVOKEVIRTUAL, SUPER_CLASS_INTERNAL_TYPE, "findMarshaller",
+                                    MARSHALLER_FIND_MARSHALLER_SIGNATURE );
+                mv.visitVarInsn( ASTORE, 8 );
+
+                // Save marshaller to field
+                mv.visitLabel( labelNonNull );
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitVarInsn( ALOAD, 8 );
+                mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
+                                   MARSHALLER_CLASS_DESCRIPTOR );
+            }
+            else
+            {
+                // Check if marshaller is defined
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitVarInsn( ALOAD, 0 );
+                mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                                   PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+                mv.visitMethodInsn( INVOKEVIRTUAL, SUPER_CLASS_INTERNAL_TYPE, "findMarshaller",
+                                    MARSHALLER_FIND_MARSHALLER_SIGNATURE );
+                mv.visitFieldInsn( PUTFIELD, className, fieldName, MARSHALLER_CLASS_DESCRIPTOR );
+            }
+
+            // Load this to method stack
+            mv.visitVarInsn( ALOAD, 0 );
+            mv.visitInsn( DUP );
+
+            // Load property accessor
+            mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                               PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+            mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "getPropertyAccessor",
+                                PROPERTY_DESCRIPTOR_GET_PROPERTYACCESSOR_SIGNATURE );
+
+            // Save PropertyAccessor to field
+            mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
+                               PROPERTYACCESSOR_CLASS_DESCRIPTOR );
+        }
+
+        mv.visitInsn( RETURN );
+        mv.visitMaxs( -1, 12 );
+        mv.visitEnd();
+    }
+
+    private void createMarshallMethod( ClassWriter cw, String className, Class<?> type,
+                                       SerializationStrategy serializationStrategy,
+                                       List<PropertyDescriptor> propertyDescriptors )
+    {
+
+        MethodVisitor mv =
+            cw.visitMethod( ACC_PUBLIC, "marshall", MARSHALLER_MARSHALL_SIGNATURE, null, MARSHALLER_EXCEPTIONS );
+
+        // If element type is not reference capable or SerializationStrategy is
+        // not SizeOptimized just prevent generation of code
+        if ( serializationStrategy == SerializationStrategy.SizeOptimized && ClassUtil.isReferenceCapable( type ) )
+        {
+            // Load this to method stack
+            mv.visitVarInsn( ALOAD, 0 );
+
+            // Load value to method stack
+            mv.visitVarInsn( ALOAD, 1 );
+
+            // Load type to method stack
+            mv.visitVarInsn( ALOAD, 2 );
+
+            // Load dataOutput to method stack
+            mv.visitVarInsn( ALOAD, 3 );
+
+            // Load serializationContext to method stack
+            mv.visitVarInsn( ALOAD, 4 );
+
+            // Call super.isAlreadyMarshalled(...);
+            mv.visitMethodInsn( INVOKEVIRTUAL, SUPER_CLASS_INTERNAL_TYPE, "isAlreadyMarshalled",
+                                MARSHALLER_IS_ALREADY_MARSHALLED_SIGNATURE );
+
+            // Label if value is not yet marshalled
+            Label notYetMarshalled = new Label();
+
+            // Test if already marshalled
+            mv.visitJumpInsn( IFEQ, notYetMarshalled );
+
+            // If marshalled - just return
+            mv.visitInsn( RETURN );
+
+            // Visit label - if not yet marshalled - marshall it
+            mv.visitLabel( notYetMarshalled );
+        }
+
+        for ( PropertyDescriptor propertyDescriptor : propertyDescriptors )
+        {
+            if ( propertyDescriptor.getType().isArray()
+                && !propertyDescriptor.getType().getComponentType().isPrimitive() )
+            {
+                visitObjectArrayPropertyAccessorRead( mv, className, propertyDescriptor );
+            }
+            else
+            {
+                visitValuePropertyAccessorRead( mv, className, propertyDescriptor );
+            }
+        }
+
+        // Add Return instruction
+        mv.visitInsn( RETURN );
+
+        // End visiting
+        mv.visitMaxs( 9, 9 );
+        mv.visitEnd();
+    }
+
+    private void visitValuePropertyAccessorRead( MethodVisitor mv, String className,
+                                                 PropertyDescriptor propertyDescriptor )
+    {
+        Class<?> propertyType = propertyDescriptor.getType();
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Load property marshaller on stack
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
+                           MARSHALLER_CLASS_DESCRIPTOR );
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Read PropertyAccessor from field
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
+                           PROPERTYACCESSOR_CLASS_DESCRIPTOR );
+
+        // Load value to method stack
+        mv.visitVarInsn( ALOAD, 1 );
+
+        // Load value by type on stack
+        visitPropertyAccessorValueRead( propertyType, mv );
+
+        // If type is primitive add some "autoboxing" magic
+        if ( propertyType.isPrimitive() )
+        {
+            visitWrapperAutoboxing( propertyType, mv );
+        }
+
+        // Load type to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                           PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+
+        // Load DataOutput to method stack
+        mv.visitVarInsn( ALOAD, 3 );
+
+        // Load SerializationContext to method stack
+        mv.visitVarInsn( ALOAD, 4 );
+
+        // Call Marshaller#marshall on properties marshaller
+        mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLER_CLASS_INTERNAL_TYPE, "marshall", MARSHALLER_MARSHALL_SIGNATURE );
+    }
+
+    private void visitObjectArrayPropertyAccessorRead( MethodVisitor mv, String className,
+                                                       PropertyDescriptor propertyDescriptor )
+    {
+        Class<?> propertyType = propertyDescriptor.getType();
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Read PropertyAccessor from field
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
+                           PROPERTYACCESSOR_CLASS_DESCRIPTOR );
+        mv.visitTypeInsn( CHECKCAST, ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE );
+        mv.visitVarInsn( ASTORE, 8 );
+
+        // Load property type
+        mv.visitVarInsn( ALOAD, 8 );
+        mv.visitInsn( DUP );
+        mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYACCESSOR_CLASS_INTERNAL_TYPE, "getType",
+                            OBJECT_GET_CLASS_SIGNATURE );
+        mv.visitVarInsn( ASTORE, 5 );
+
+        // Load value to method stack
+        mv.visitVarInsn( ALOAD, 1 );
+
+        // Save array to stack position 6
+        visitPropertyAccessorValueRead( propertyType, mv );
+        mv.visitTypeInsn( CHECKCAST, Type.getType( propertyType ).getInternalName() );
+        mv.visitVarInsn( ASTORE, 6 );
+
+        // Save length to stream
+        mv.visitVarInsn( ALOAD, 3 );
+        mv.visitVarInsn( ALOAD, 6 );
+        mv.visitInsn( ARRAYLENGTH );
+        mv.visitMethodInsn( INVOKEINTERFACE, DATAOUTPUT_CLASS_INTERNAL_TYPE, "writeInt", "(I)V" );
+
+        // Loop over every element in array
+        Label forLoopEnd = new Label();
+        Label forLoopStart = new Label();
+        mv.visitInsn( ICONST_0 );
+        mv.visitVarInsn( ISTORE, 7 );
+        mv.visitJumpInsn( GOTO, forLoopEnd );
+        mv.visitLabel( forLoopStart );
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Load property marshaller on stack
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
+                           MARSHALLER_CLASS_DESCRIPTOR );
+
+        // Load PropertyAccessor to method stack
+        mv.visitVarInsn( ALOAD, 8 );
+
+        // Load array to method stack
+        mv.visitVarInsn( ALOAD, 6 );
+
+        // Load index to method stack
+        mv.visitVarInsn( ILOAD, 7 );
+
+        // Get value from array
+        mv.visitMethodInsn( INVOKEINTERFACE, ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE, "readObject",
+                            PROPERTY_ACCESSOR_ARRAY_READ_OBJECT_SIGNATURE );
+        mv.visitTypeInsn( CHECKCAST, Type.getType( propertyType.getComponentType() ).getInternalName() );
+
+        // If type is primitive add some "autoboxing" magic
+        if ( propertyType.getComponentType().isPrimitive() )
+        {
+            visitWrapperAutoboxing( propertyType.getComponentType(), mv );
+        }
+
+        // Load type to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
+                           CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+
+        // Load DataOutput to method stack
+        mv.visitVarInsn( ALOAD, 3 );
+
+        // Load SerializationContext to method stack
+        mv.visitVarInsn( ALOAD, 4 );
+
+        // Call Marshaller#marshall on properties marshaller
+        mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLER_CLASS_INTERNAL_TYPE, "marshall", MARSHALLER_MARSHALL_SIGNATURE );
+
+        // Test if loop ends
+        mv.visitIincInsn( 7, 1 );
+        mv.visitLabel( forLoopEnd );
+        mv.visitVarInsn( ILOAD, 7 );
+        mv.visitVarInsn( ALOAD, 6 );
+        mv.visitInsn( ARRAYLENGTH );
+        mv.visitJumpInsn( IF_ICMPLT, forLoopStart );
+    }
+
+    private void createUnmarshallMethod( ClassWriter cw, String className, Class<?> type,
+                                         List<PropertyDescriptor> propertyDescriptors )
+    {
+        MethodVisitor mv =
+            cw.visitMethod( ACC_PUBLIC, "unmarshall", MARSHALLER_UNMARSHALL_SIGNATURE, null, MARSHALLER_EXCEPTIONS );
+
+        for ( PropertyDescriptor propertyDescriptor : propertyDescriptors )
+        {
+            if ( propertyDescriptor.getType().isArray()
+                && !propertyDescriptor.getType().getComponentType().isPrimitive() )
+            {
+                visitObjectArrayPropertyAccessorWrite( mv, className, propertyDescriptor );
+            }
+            else
+            {
+                visitValuePropertyAccessorWrite( mv, className, propertyDescriptor );
+            }
+        }
+
+        // Load instance to method stack
+        mv.visitVarInsn( ALOAD, 1 );
+
+        // Add Return statement
+        visitReturn( type, mv );
+
+        // End visiting
+        mv.visitMaxs( 11, 11 );
+        mv.visitEnd();
+    }
+
+    private void visitValuePropertyAccessorWrite( MethodVisitor mv, String className,
+                                                  PropertyDescriptor propertyDescriptor )
+    {
+        Class<?> propertyType = propertyDescriptor.getType();
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Read PropertyAccessor from field
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
+                           PROPERTYACCESSOR_CLASS_DESCRIPTOR );
+
+        // Store PropertyAccessor for later use
+        mv.visitVarInsn( ASTORE, 5 );
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Load property marshaller to method stack
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
+                           MARSHALLER_CLASS_DESCRIPTOR );
+
+        // Load this to method stack
+        mv.visitVarInsn( ALOAD, 0 );
+
+        // Load PropertyDescriptor to method stack
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
+                           PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+
+        // Load DataInput to method stack
+        mv.visitVarInsn( ALOAD, 3 );
+
+        // Load SerializationContext to method stack
+        mv.visitVarInsn( ALOAD, 4 );
+
+        // Call Marshaller#unmarshall on properties marshaller
+        mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLER_CLASS_INTERNAL_TYPE, "unmarshall",
+                            MARSHALLER_BASE_UNMARSHALL_SIGNATURE );
+
+        // Save value
+        mv.visitVarInsn( ASTORE, 6 );
+
+        // Load PropertyAccessor to method stack
+        mv.visitVarInsn( ALOAD, 5 );
+
+        // Load instance to method stack
+        mv.visitVarInsn( ALOAD, 1 );
+
+        // Load value to method stack
+        mv.visitVarInsn( ALOAD, 6 );
+
+        // If type is primitive add some "autoboxing" magic
+        if ( propertyType.isPrimitive() )
+        {
+            visitPrimitiveAutoboxing( propertyType, mv );
+        }
+
+        // Call PropertyAccessor#writeX
+        visitPropertyAccessorValueWrite( propertyType, mv );
+    }
+
+    private void visitObjectArrayPropertyAccessorWrite( MethodVisitor mv, String className,
+                                                        PropertyDescriptor propertyDescriptor )
+    {
+        Class<?> propertyType = propertyDescriptor.getType();
+        Class<?> componentType = propertyType.getComponentType();
+
+        // Read size
+        mv.visitVarInsn( ALOAD, 3 );
+        mv.visitMethodInsn( INVOKEINTERFACE, DATAINPUT_CLASS_INTERNAL_TYPE, "readInt", "()I" );
+        mv.visitInsn( DUP );
+        mv.visitVarInsn( ISTORE, 5 );
+
+        // Instantiate array
+        mv.visitTypeInsn( ANEWARRAY, Type.getType( componentType ).getInternalName() );
+        mv.visitVarInsn( ASTORE, 6 );
+
+        // Read PropertyAccessor from field
+        mv.visitVarInsn( ALOAD, 0 );
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
+                           PROPERTYACCESSOR_CLASS_DESCRIPTOR );
+        mv.visitVarInsn( ASTORE, 9 );
+
+        // Get component type
+        mv.visitVarInsn( ALOAD, 0 );
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
+                           CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
+        mv.visitVarInsn( ASTORE, 8 );
+
+        mv.visitVarInsn( ALOAD, 0 );
+        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
+                           MARSHALLER_CLASS_DESCRIPTOR );
+        mv.visitVarInsn( ASTORE, 10 );
+
+        // For loop
+        Label forLoopStart = new Label();
+        Label forLoopEnd = new Label();
+        mv.visitInsn( ICONST_0 );
+        mv.visitVarInsn( ISTORE, 7 );
+        mv.visitJumpInsn( GOTO, forLoopEnd );
+        mv.visitLabel( forLoopStart );
+
+        // Write value to array
+        mv.visitVarInsn( ALOAD, 9 );
+        mv.visitVarInsn( ALOAD, 6 );
+        mv.visitVarInsn( ILOAD, 7 );
+
+        // Read value from stream to 4th stack position
+        mv.visitVarInsn( ALOAD, 10 );
+        mv.visitVarInsn( ALOAD, 8 );
+        mv.visitVarInsn( ALOAD, 3 );
+        mv.visitVarInsn( ALOAD, 4 );
+        mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLER_CLASS_INTERNAL_TYPE, "unmarshall",
+                            MARSHALLER_BASE_UNMARSHALL_SIGNATURE );
+
+        mv.visitMethodInsn( INVOKEINTERFACE, ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE, "writeObject",
+                            PROPERTY_ACCESSOR_ARRAY_WRITE_OBJECT_SIGNATURE );
+
+        // Increment counter
+        mv.visitIincInsn( 7, 1 );
+
+        // Test for loop end
+        mv.visitLabel( forLoopEnd );
+        mv.visitVarInsn( ILOAD, 7 );
+        mv.visitVarInsn( ILOAD, 5 );
+        mv.visitJumpInsn( IF_ICMPLT, forLoopStart );
+
+        // Write array to object
+        mv.visitVarInsn( ALOAD, 9 );
+        mv.visitVarInsn( ALOAD, 1 );
+        mv.visitVarInsn( ALOAD, 6 );
+        visitPropertyAccessorValueWrite( propertyType.getComponentType(), mv );
+    }
+
+    private void visitReturn( Class<?> type, MethodVisitor mv )
+    {
+        int returnOpcode = ARETURN;
+
+        if ( type == boolean.class )
+        {
+            returnOpcode = IRETURN;
+        }
+        else if ( type == byte.class )
+        {
+            returnOpcode = IRETURN;
+        }
+        else if ( type == char.class )
+        {
+            returnOpcode = IRETURN;
+        }
+        else if ( type == short.class )
+        {
+            returnOpcode = IRETURN;
+        }
+        else if ( type == int.class )
+        {
+            returnOpcode = IRETURN;
+        }
+        else if ( type == long.class )
+        {
+            returnOpcode = LRETURN;
+        }
+        else if ( type == float.class )
+        {
+            returnOpcode = FRETURN;
+        }
+        else if ( type == double.class )
+        {
+            returnOpcode = DRETURN;
+        }
+        else
+        {
+            returnOpcode = ARETURN;
+        }
+
+        mv.visitInsn( returnOpcode );
+    }
+
+    private void visitPropertyAccessorValueRead( Class<?> type, MethodVisitor mv )
+    {
+        String methodName = null;
+        String methodSignature = null;
+
+        if ( type == boolean.class )
+        {
+            methodName = "readBoolean";
+            methodSignature = PROPERTY_ACCESSOR_READ_BOOLEAN_SIGNATURE;
+        }
+        else if ( type == byte.class )
+        {
+            methodName = "readByte";
+            methodSignature = PROPERTY_ACCESSOR_READ_BYTE_SIGNATURE;
+        }
+        else if ( type == char.class )
+        {
+            methodName = "readChar";
+            methodSignature = PROPERTY_ACCESSOR_READ_CHAR_SIGNATURE;
+        }
+        else if ( type == short.class )
+        {
+            methodName = "readShort";
+            methodSignature = PROPERTY_ACCESSOR_READ_SHORT_SIGNATURE;
+        }
+        else if ( type == int.class )
+        {
+            methodName = "readInt";
+            methodSignature = PROPERTY_ACCESSOR_READ_INT_SIGNATURE;
+        }
+        else if ( type == long.class )
+        {
+            methodName = "readLong";
+            methodSignature = PROPERTY_ACCESSOR_READ_LONG_SIGNATURE;
+        }
+        else if ( type == float.class )
+        {
+            methodName = "readFloat";
+            methodSignature = PROPERTY_ACCESSOR_READ_FLOAT_SIGNATURE;
+        }
+        else if ( type == double.class )
+        {
+            methodName = "readDouble";
+            methodSignature = PROPERTY_ACCESSOR_READ_DOUBLE_SIGNATURE;
+        }
+        else
+        {
+            methodName = "readObject";
+            methodSignature = PROPERTY_ACCESSOR_READ_OBJECT_SIGNATURE;
+        }
+
+        mv.visitMethodInsn( INVOKEINTERFACE, VALUEPROPERTYACCESSOR_CLASS_INTERNAL_TYPE, methodName, methodSignature );
+    }
+
+    private void visitPropertyAccessorValueWrite( Class<?> type, MethodVisitor mv )
+    {
+        String methodName = null;
+        String methodSignature = null;
+
+        if ( type == boolean.class )
+        {
+            methodName = "writeBoolean";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_BOOLEAN_SIGNATURE;
+        }
+        else if ( type == byte.class )
+        {
+            methodName = "writeByte";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_BYTE_SIGNATURE;
+        }
+        else if ( type == char.class )
+        {
+            methodName = "writeChar";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_CHAR_SIGNATURE;
+        }
+        else if ( type == short.class )
+        {
+            methodName = "writeShort";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_SHORT_SIGNATURE;
+        }
+        else if ( type == int.class )
+        {
+            methodName = "writeInt";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_INT_SIGNATURE;
+        }
+        else if ( type == long.class )
+        {
+            methodName = "writeLong";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_LONG_SIGNATURE;
+        }
+        else if ( type == float.class )
+        {
+            methodName = "writeFloat";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_FLOAT_SIGNATURE;
+        }
+        else if ( type == double.class )
+        {
+            methodName = "writeDouble";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_DOUBLE_SIGNATURE;
+        }
+        else
+        {
+            methodName = "writeObject";
+            methodSignature = PROPERTY_ACCESSOR_WRITE_OBJECT_SIGNATURE;
+        }
+
+        mv.visitMethodInsn( INVOKEINTERFACE, VALUEPROPERTYACCESSOR_CLASS_INTERNAL_TYPE, methodName, methodSignature );
+    }
+
+    private void visitPrimitiveAutoboxing( Class<?> type, MethodVisitor mv )
+    {
+        if ( type == boolean.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Boolean" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z" );
+        }
+        else if ( type == byte.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Byte" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B" );
+        }
+        else if ( type == char.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Character" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C" );
+        }
+        else if ( type == short.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Short" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S" );
+        }
+        else if ( type == int.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Integer" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I" );
+        }
+        else if ( type == long.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Long" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J" );
+        }
+        else if ( type == float.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Float" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F" );
+        }
+        else if ( type == double.class )
+        {
+            mv.visitTypeInsn( CHECKCAST, "java/lang/Double" );
+            mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D" );
+        }
+    }
+
+    private void visitWrapperAutoboxing( Class<?> type, MethodVisitor mv )
+    {
+        if ( type == boolean.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Boolean", "valueOf", BOOLEAN_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == byte.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Byte", "valueOf", BYTE_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == char.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Character", "valueOf", CHAR_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == short.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Short", "valueOf", SHORT_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == int.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Integer", "valueOf", INT_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == long.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Long", "valueOf", LONG_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == float.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Float", "valueOf", FLOAT_VALUE_OF_SIGNATURE );
+        }
+        else if ( type == double.class )
+        {
+            mv.visitMethodInsn( INVOKESTATIC, "java/lang/Double", "valueOf", DOUBLE_VALUE_OF_SIGNATURE );
+        }
+    }
+
+    private String toFinalFieldName( String prefix, PropertyDescriptor propertyDescriptor )
+    {
+        return new StringBuilder( prefix.toUpperCase() ).append( "_" ).append( propertyDescriptor.getPropertyName().toUpperCase() ).append( "_LIGHTNING" ).toString();
+    }
+
+    protected void visitSystemOutPrintln( MethodVisitor mv, int stackPosition )
+    {
+        mv.visitVarInsn( ASTORE, stackPosition );
+        mv.visitFieldInsn( GETSTATIC, Type.getType( System.class ).getInternalName(), "out",
+                           Type.getType( PrintStream.class ).getDescriptor() );
+        mv.visitVarInsn( ALOAD, stackPosition );
+        mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType( Object.class ).getInternalName(), "toString",
+                            "()Ljava/lang/String;" );
+        mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType( PrintStream.class ).getInternalName(), "println",
+                            "(Ljava/lang/String;)V" );
+        mv.visitVarInsn( ALOAD, stackPosition );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/CreateClassLoader.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/CreateClassLoader.java
new file mode 100644
index 0000000..d66f736
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/CreateClassLoader.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class CreateClassLoader
+    implements PrivilegedAction<GeneratorClassLoader>
+{
+
+    private final ClassLoader classLoader;
+
+    public CreateClassLoader( final ClassLoader classLoader )
+    {
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public GeneratorClassLoader run()
+    {
+        return new GeneratorClassLoader( classLoader );
+    }
+
+    public static final GeneratorClassLoader createClassLoader( ClassLoader classLoader )
+    {
+        return AccessController.doPrivileged( new CreateClassLoader( classLoader ) );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorClassLoader.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorClassLoader.java
new file mode 100644
index 0000000..98458ff
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorClassLoader.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+public class GeneratorClassLoader
+    extends ClassLoader
+{
+
+    public GeneratorClassLoader( final ClassLoader classLoader )
+    {
+        super( classLoader );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public <T> Class<T> loadClass( final byte[] data )
+    {
+        return (Class<T>) defineClass( null, data, 0, data.length );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorConstants.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorConstants.java
new file mode 100644
index 0000000..efc4f84
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/GeneratorConstants.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.CheatPropertyDescriptor;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.metadata.ArrayPropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.apache.directmemory.lightning.metadata.ValuePropertyAccessor;
+import org.objectweb.asm.Type;
+
+public interface GeneratorConstants
+{
+
+    static String MARSHALLER_MARSHALL_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE,
+                                  new Type[] { Type.getType( Object.class ), Type.getType( PropertyDescriptor.class ),
+                                      Type.getType( DataOutput.class ), Type.getType( SerializationContext.class ) } );
+
+    static String MARSHALLER_BASE_UNMARSHALL_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Object.class ), new Type[] { Type.getType( PropertyDescriptor.class ),
+            Type.getType( DataInput.class ), Type.getType( SerializationContext.class ) } );
+
+    static String MARSHALLER_UNMARSHALL_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Object.class ),
+                                  new Type[] { Type.getType( Object.class ), Type.getType( PropertyDescriptor.class ),
+                                      Type.getType( DataInput.class ), Type.getType( SerializationContext.class ) } );
+
+    static String MARSHALLER_FIND_MARSHALLER_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Marshaller.class ),
+                                  new Type[] { Type.getType( PropertyDescriptor.class ) } );
+
+    static String MARSHALLER_GET_PROPERTY_ACCESSOR_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( PropertyAccessor.class ), new Type[] { Type.getType( String.class ) } );
+
+    static String MARSHALLER_IS_ALREADY_MARSHALLED_SIGNATURE =
+        Type.getMethodDescriptor( Type.BOOLEAN_TYPE,
+                                  new Type[] { Type.getType( Object.class ), Type.getType( Class.class ),
+                                      Type.getType( DataOutput.class ), Type.getType( SerializationContext.class ) } );
+
+    static String MARSHALLER_CONSTRUCTOR_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE,
+                                  new Type[] { Type.getType( Class.class ), Type.getType( Map.class ),
+                                      Type.getType( ClassDescriptorAwareSerializer.class ),
+                                      Type.getType( ObjectInstantiatorFactory.class ), Type.getType( List.class ),
+                                      Type.getType( MarshallerStrategy.class ) } );
+
+    static String MARSHALLER_SUPER_CONSTRUCTOR_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( Class.class ), Type.getType( Map.class ),
+            Type.getType( ClassDescriptorAwareSerializer.class ), Type.getType( ObjectInstantiatorFactory.class ) } );
+
+    static String PROPERTY_DESCRIPTOR_GET_MARSHALLER_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Marshaller.class ), new Type[0] );
+
+    static String PROPERTY_DESCRIPTOR_GET_PROPERTYACCESSOR_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( PropertyAccessor.class ), new Type[0] );
+
+    static String OBJECT_GET_CLASS_SIGNATURE = Type.getMethodDescriptor( Type.getType( Class.class ), new Type[0] );
+
+    static String CLASS_GET_COMPONENT_TYPE = Type.getMethodDescriptor( Type.getType( Class.class ), new Type[0] );
+
+    static String ARRAY_LENGTH_SIGNATURE = Type.getMethodDescriptor( Type.INT_TYPE, new Type[0] );
+
+    static String MARSHALLERSTRATEGY_GET_MARSHALLER_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Marshaller.class ),
+                                  new Type[] { Type.getType( java.lang.reflect.Type.class ),
+                                      Type.getType( MarshallerContext.class ) } );
+
+    static String CHEATINGPROPERTYDESCRIPTOR_CONSTRUCTOR =
+        Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( String.class ),
+            Type.getType( Class.class ), Type.getType( Marshaller.class ) } );
+
+    static String SUPER_CLASS_INTERNAL_TYPE = Type.getType( AbstractGeneratedMarshaller.class ).getInternalName();
+
+    static String MARSHALLER_CLASS_INTERNAL_TYPE = Type.getType( Marshaller.class ).getInternalName();
+
+    static String IOEXCEPTION_CLASS_INTERNAL_TYPE = Type.getType( IOException.class ).getInternalName();
+
+    static String LIST_CLASS_INTERNAL_TYPE = Type.getType( List.class ).getInternalName();
+
+    static String PROPERTYACCESSOR_CLASS_INTERNAL_TYPE = Type.getType( PropertyAccessor.class ).getInternalName();
+
+    static String VALUEPROPERTYACCESSOR_CLASS_INTERNAL_TYPE =
+        Type.getType( ValuePropertyAccessor.class ).getInternalName();
+
+    static String ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE =
+        Type.getType( ArrayPropertyAccessor.class ).getInternalName();
+
+    static String PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE = Type.getType( PropertyDescriptor.class ).getInternalName();
+
+    static String CHEATINGPROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE =
+        Type.getType( CheatPropertyDescriptor.class ).getInternalName();
+
+    static String CLASS_CLASS_INTERNAL_TYPE = Type.getType( Class.class ).getInternalName();
+
+    static String DATAOUTPUT_CLASS_INTERNAL_TYPE = Type.getType( DataOutput.class ).getInternalName();
+
+    static String DATAINPUT_CLASS_INTERNAL_TYPE = Type.getType( DataInput.class ).getInternalName();
+
+    static String MARSHALLERSTRATEGY_CLASS_INTERNAL_TYPE = Type.getType( MarshallerStrategy.class ).getInternalName();
+
+    static String MARSHALLER_CLASS_DESCRIPTOR = Type.getType( Marshaller.class ).getDescriptor();
+
+    static String PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR = Type.getType( PropertyDescriptor.class ).getDescriptor();
+
+    static String PROPERTYACCESSOR_CLASS_DESCRIPTOR = Type.getType( PropertyAccessor.class ).getDescriptor();
+
+    static String CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR =
+        Type.getType( CheatPropertyDescriptor.class ).getDescriptor();
+
+    static String[] MARSHALLER_EXCEPTIONS = { IOEXCEPTION_CLASS_INTERNAL_TYPE };
+
+    static AtomicLong GENEREATED_CLASS_ID = new AtomicLong();
+
+    static String PROPERTY_DESCRIPTOR_FIELD_NAME = "PROPERTY_DESCRIPTORS";
+
+    static String PROPERTY_ACCESSOR_READ_BOOLEAN_SIGNATURE =
+        Type.getMethodDescriptor( Type.BOOLEAN_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_BYTE_SIGNATURE =
+        Type.getMethodDescriptor( Type.BYTE_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_CHAR_SIGNATURE =
+        Type.getMethodDescriptor( Type.CHAR_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_SHORT_SIGNATURE =
+        Type.getMethodDescriptor( Type.SHORT_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_INT_SIGNATURE =
+        Type.getMethodDescriptor( Type.INT_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_LONG_SIGNATURE =
+        Type.getMethodDescriptor( Type.LONG_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_FLOAT_SIGNATURE =
+        Type.getMethodDescriptor( Type.FLOAT_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_DOUBLE_SIGNATURE =
+        Type.getMethodDescriptor( Type.DOUBLE_TYPE, new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_READ_OBJECT_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Object.class ), new Type[] { Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_WRITE_BOOLEAN_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.BOOLEAN_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_BYTE_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                     new Type[] {
+                                                                                         Type.getType( Object.class ),
+                                                                                         Type.BYTE_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_CHAR_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                     new Type[] {
+                                                                                         Type.getType( Object.class ),
+                                                                                         Type.CHAR_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_SHORT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                      new Type[] {
+                                                                                          Type.getType( Object.class ),
+                                                                                          Type.SHORT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_INT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                    new Type[] {
+                                                                                        Type.getType( Object.class ),
+                                                                                        Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_LONG_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                     new Type[] {
+                                                                                         Type.getType( Object.class ),
+                                                                                         Type.LONG_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_FLOAT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE,
+                                                                                      new Type[] {
+                                                                                          Type.getType( Object.class ),
+                                                                                          Type.FLOAT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_DOUBLE_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.DOUBLE_TYPE } );
+
+    static String PROPERTY_ACCESSOR_WRITE_OBJECT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.getType( Object.class ) } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_BOOLEAN_SIGNATURE =
+        Type.getMethodDescriptor( Type.BOOLEAN_TYPE, new Type[] { Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_BYTE_SIGNATURE = Type.getMethodDescriptor( Type.BYTE_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_CHAR_SIGNATURE = Type.getMethodDescriptor( Type.CHAR_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_SHORT_SIGNATURE = Type.getMethodDescriptor( Type.SHORT_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_INT_SIGNATURE = Type.getMethodDescriptor( Type.INT_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_LONG_SIGNATURE = Type.getMethodDescriptor( Type.LONG_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_FLOAT_SIGNATURE = Type.getMethodDescriptor( Type.FLOAT_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_DOUBLE_SIGNATURE =
+        Type.getMethodDescriptor( Type.DOUBLE_TYPE, new Type[] { Type.getType( Object.class ), Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_READ_OBJECT_SIGNATURE =
+        Type.getMethodDescriptor( Type.getType( Object.class ), new Type[] { Type.getType( Object.class ),
+            Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_BOOLEAN_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( Object.class ), Type.INT_TYPE,
+            Type.BOOLEAN_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_BYTE_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.BYTE_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_CHAR_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.CHAR_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_SHORT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.SHORT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_INT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.INT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_LONG_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.LONG_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_FLOAT_SIGNATURE = Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {
+        Type.getType( Object.class ), Type.INT_TYPE, Type.FLOAT_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_DOUBLE_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( Object.class ), Type.INT_TYPE,
+            Type.DOUBLE_TYPE } );
+
+    static String PROPERTY_ACCESSOR_ARRAY_WRITE_OBJECT_SIGNATURE =
+        Type.getMethodDescriptor( Type.VOID_TYPE,
+                                  new Type[] { Type.getType( Object.class ), Type.INT_TYPE, Type.getType( Object.class ) } );
+
+    static String BOOLEAN_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Boolean.class ),
+                                                                         new Type[] { Type.BOOLEAN_TYPE } );
+
+    static String BYTE_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Byte.class ),
+                                                                      new Type[] { Type.BYTE_TYPE } );
+
+    static String CHAR_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Character.class ),
+                                                                      new Type[] { Type.CHAR_TYPE } );
+
+    static String SHORT_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Short.class ),
+                                                                       new Type[] { Type.SHORT_TYPE } );
+
+    static String INT_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Integer.class ),
+                                                                     new Type[] { Type.INT_TYPE } );
+
+    static String LONG_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Long.class ),
+                                                                      new Type[] { Type.LONG_TYPE } );
+
+    static String FLOAT_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Float.class ),
+                                                                       new Type[] { Type.FLOAT_TYPE } );
+
+    static String DOUBLE_VALUE_OF_SIGNATURE = Type.getMethodDescriptor( Type.getType( Double.class ),
+                                                                        new Type[] { Type.DOUBLE_TYPE } );
+
+    static String ARRAY_TYPE_BOOLEAN = Type.getInternalName( boolean[].class );
+
+    static String ARRAY_TYPE_BYTE = Type.getInternalName( byte[].class );
+
+    static String ARRAY_TYPE_CHAR = Type.getInternalName( char[].class );
+
+    static String ARRAY_TYPE_SHORT = Type.getInternalName( short[].class );
+
+    static String ARRAY_TYPE_INT = Type.getInternalName( int[].class );
+
+    static String ARRAY_TYPE_LONG = Type.getInternalName( long[].class );
+
+    static String ARRAY_TYPE_FLOAT = Type.getInternalName( float[].class );
+
+    static String ARRAY_TYPE_DOUBLE = Type.getInternalName( double[].class );
+
+    static String ARRAY_TYPE_OBJECT = Type.getInternalName( Object[].class );
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/MarshallerGenerator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/MarshallerGenerator.java
new file mode 100644
index 0000000..6637c54
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/MarshallerGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.generator;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public interface MarshallerGenerator
+{
+
+    Marshaller generateMarshaller( Class<?> type, List<PropertyDescriptor> propertyDescriptors,
+                                   Map<Class<?>, Marshaller> marshallers, ClassDescriptorAwareSerializer serializer,
+                                   SerializationStrategy serializationStrategy,
+                                   ObjectInstantiatorFactory objectInstantiatorFactory, File debugCacheDirectory );
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/NullInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/NullInstantiator.java
new file mode 100644
index 0000000..1a53fda
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/NullInstantiator.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+
+/**
+ * The instantiator that always return a null instance
+ * 
+ * @author Henri Tremblay
+ */
+public class NullInstantiator
+    implements ObjectInstantiator
+{
+
+    /**
+     * @return Always null
+     */
+    @Override
+    public Object newInstance()
+    {
+        return null;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisBase.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisBase.java
new file mode 100644
index 0000000..c41daa8
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisBase.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.instantiator.strategy.InstantiatorStrategy;
+
+/**
+ * Base class to extend if you want to have a class providing your own default strategy. Can also be instantiated
+ * directly.
+ * 
+ * @author Henri Tremblay
+ */
+public class ObjenesisBase
+    implements ObjectInstantiatorFactory
+{
+
+    /** Strategy used by this Objenesi implementation to create classes */
+    protected final InstantiatorStrategy strategy;
+
+    /** Strategy cache. Key = Class, Value = InstantiatorStrategy */
+    protected Map<String, ObjectInstantiator> cache;
+
+    /**
+     * Constructor allowing to pick a strategy and using cache
+     * 
+     * @param strategy Strategy to use
+     */
+    public ObjenesisBase( InstantiatorStrategy strategy )
+    {
+        this( strategy, true );
+    }
+
+    /**
+     * Flexible constructor allowing to pick the strategy and if caching should be used
+     * 
+     * @param strategy Strategy to use
+     * @param useCache If {@link ObjectInstantiator}s should be cached
+     */
+    public ObjenesisBase( InstantiatorStrategy strategy, boolean useCache )
+    {
+        if ( strategy == null )
+        {
+            throw new IllegalArgumentException( "A strategy can't be null" );
+        }
+        this.strategy = strategy;
+        this.cache = useCache ? new HashMap<String, ObjectInstantiator>() : null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getClass().getName() + " using " + strategy.getClass().getName()
+            + ( cache == null ? " without" : " with" ) + " caching";
+    }
+
+    /**
+     * Will create a new object without any constructor being called
+     * 
+     * @param clazz Class to instantiate
+     * @return New instance of clazz
+     */
+    @Override
+    public Object newInstance( Class<?> clazz )
+    {
+        return getInstantiatorOf( clazz ).newInstance();
+    }
+
+    /**
+     * Will pick the best instantiator for the provided class. If you need to create a lot of instances from the same
+     * class, it is way more efficient to create them from the same ObjectInstantiator than calling
+     * {@link #newInstance(Class)}.<br>
+     * Explicitly made this NON-THREADSAFE for performance reasons.
+     * 
+     * @param clazz Class to instantiate
+     * @return Instantiator dedicated to the class
+     */
+    @Override
+    public ObjectInstantiator getInstantiatorOf( Class<?> clazz )
+    {
+        if ( cache == null )
+        {
+            return strategy.newInstantiatorOf( clazz );
+        }
+        ObjectInstantiator instantiator = cache.get( clazz.getName() );
+        if ( instantiator == null )
+        {
+            instantiator = strategy.newInstantiatorOf( clazz );
+            cache.put( clazz.getName(), instantiator );
+        }
+        return instantiator;
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisException.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisException.java
new file mode 100644
index 0000000..53c7c46
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisException.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+/**
+ * Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is runtime to prevent
+ * having to catch it. It will do normal exception wrapping for JDK 1.4 and more and basic message wrapping for JDK 1.3.
+ * 
+ * @author Henri Tremblay
+ */
+public class ObjenesisException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -2677230016262426968L;
+
+    private static final boolean jdk14 =
+        ( Double.parseDouble( System.getProperty( "java.specification.version" ) ) > 1.3 );
+
+    /**
+     * @param msg Error message
+     */
+    public ObjenesisException( String msg )
+    {
+        super( msg );
+    }
+
+    /**
+     * @param cause Wrapped exception. The message will be the one of the cause.
+     */
+    public ObjenesisException( Throwable cause )
+    {
+        super( cause == null ? null : cause.toString() );
+        if ( jdk14 )
+        {
+            initCause( cause );
+        }
+    }
+
+    /**
+     * @param msg Error message
+     * @param cause Wrapped exception
+     */
+    public ObjenesisException( String msg, Throwable cause )
+    {
+        super( msg );
+        if ( jdk14 )
+        {
+            initCause( cause );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisHelper.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisHelper.java
new file mode 100644
index 0000000..24eaae5
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisHelper.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import java.io.Serializable;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+
+/**
+ * Use Objenesis in a static way. <strong>It is strongly not recommended to use this class.</strong>
+ * 
+ * @author Henri Tremblay
+ */
+public final class ObjenesisHelper
+{
+
+    private static final ObjectInstantiatorFactory OBJENESIS_STD = new ObjenesisStd();
+
+    private static final ObjectInstantiatorFactory OBJENESIS_SERIALIZER = new ObjenesisSerializer();
+
+    private ObjenesisHelper()
+    {
+    }
+
+    /**
+     * Will create a new object without any constructor being called
+     * 
+     * @param clazz Class to instantiate
+     * @return New instance of clazz
+     */
+    public static Object newInstance( Class<?> clazz )
+    {
+        return OBJENESIS_STD.newInstance( clazz );
+    }
+
+    /**
+     * Will create an object just like it's done by ObjectInputStream.readObject (the default constructor of the first
+     * non serializable class will be called)
+     * 
+     * @param clazz Class to instantiate
+     * @return New instance of clazz
+     */
+    public static Serializable newSerializableInstance( Class<?> clazz )
+    {
+        return (Serializable) OBJENESIS_SERIALIZER.newInstance( clazz );
+    }
+
+    /**
+     * Will pick the best instantiator for the provided class. If you need to create a lot of instances from the same
+     * class, it is way more efficient to create them from the same ObjectInstantiator than calling
+     * {@link #newInstance(Class)}.
+     * 
+     * @param clazz Class to instantiate
+     * @return Instantiator dedicated to the class
+     */
+    public static ObjectInstantiator getInstantiatorOf( Class<?> clazz )
+    {
+        return OBJENESIS_STD.getInstantiatorOf( clazz );
+    }
+
+    /**
+     * Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating ObjectInputStream.readObject
+     * behavior.
+     * 
+     * @see #newSerializableInstance(Class)
+     * @param clazz Class to instantiate
+     * @return Instantiator dedicated to the class
+     */
+    public static ObjectInstantiator getSerializableObjectInstantiatorOf( Class<?> clazz )
+    {
+        return OBJENESIS_SERIALIZER.getInstantiatorOf( clazz );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisSerializer.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisSerializer.java
new file mode 100644
index 0000000..59d1e34
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisSerializer.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import org.apache.directmemory.lightning.internal.instantiator.strategy.SerializingInstantiatorStrategy;
+
+/**
+ * Objenesis implementation using the {@link SerializingInstantiatorStrategy}.
+ * 
+ * @author Henri Tremblay
+ */
+public class ObjenesisSerializer
+    extends ObjenesisBase
+{
+
+    /**
+     * Default constructor using the
+     * {@link org.apache.directmemory.lightning.internal.instantiator.strategy.SerializingInstantiatorStrategy}
+     */
+    public ObjenesisSerializer()
+    {
+        super( new SerializingInstantiatorStrategy() );
+    }
+
+    /**
+     * Instance using the
+     * {@link org.apache.directmemory.lightning.internal.instantiator.strategy.SerializingInstantiatorStrategy} with or
+     * without caching {@link org.apache.directmemory.lightning.instantiator.ObjectInstantiator}s
+     * 
+     * @param useCache If {@link org.apache.directmemory.lightning.instantiator.ObjectInstantiator} s should be cached
+     */
+    public ObjenesisSerializer( boolean useCache )
+    {
+        super( new SerializingInstantiatorStrategy(), useCache );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisStd.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisStd.java
new file mode 100644
index 0000000..4803229
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/ObjenesisStd.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import org.apache.directmemory.lightning.internal.instantiator.strategy.StdInstantiatorStrategy;
+
+/**
+ * Objenesis implementation using the
+ * {@link org.apache.directmemory.lightning.internal.instantiator.strategy.StdInstantiatorStrategy} .
+ * 
+ * @author Henri Tremblay
+ */
+public class ObjenesisStd
+    extends ObjenesisBase
+{
+
+    /**
+     * Default constructor using the
+     * {@link org.apache.directmemory.lightning.internal.instantiator.strategy.StdInstantiatorStrategy}
+     */
+    public ObjenesisStd()
+    {
+        super( new StdInstantiatorStrategy() );
+    }
+
+    /**
+     * Instance using the
+     * {@link org.apache.directmemory.lightning.internal.instantiator.strategy.StdInstantiatorStrategy} with or without
+     * caching {@link org.apache.directmemory.lightning.instantiator.ObjectInstantiator}s
+     * 
+     * @param useCache If {@link org.apache.directmemory.lightning.instantiator.ObjectInstantiator} s should be cached
+     */
+    public ObjenesisStd( boolean useCache )
+    {
+        super( new StdInstantiatorStrategy(), useCache );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/SerializationInstantiatorHelper.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/SerializationInstantiatorHelper.java
new file mode 100644
index 0000000..0abfe24
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/SerializationInstantiatorHelper.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator;
+
+import java.io.Serializable;
+
+/**
+ * Helper for common serialization-compatible instantiation functions
+ * 
+ * @author Leonardo Mesquita
+ */
+public class SerializationInstantiatorHelper
+{
+
+    /**
+     * Returns the first non-serializable superclass of a given class. According to Java Object Serialization
+     * Specification, objects read from a stream are initialized by calling an accessible no-arg constructor from the
+     * first non-serializable superclass in the object's hierarchy, allowing the state of non-serializable fields to be
+     * correctly initialized.
+     * 
+     * @param type Serializable class for which the first non-serializable superclass is to be found
+     * @return The first non-serializable superclass of 'type'.
+     * @see java.io.Serializable
+     */
+    public static Class<?> getNonSerializableSuperClass( Class<?> type )
+    {
+        Class<?> result = type;
+        while ( Serializable.class.isAssignableFrom( result ) )
+        {
+            result = result.getSuperclass();
+            if ( result == null )
+            {
+                throw new Error( "Bad class hierarchy: No non-serializable parents" );
+            }
+        }
+        return result;
+
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/AccessibleInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/AccessibleInstantiator.java
new file mode 100644
index 0000000..3462c31
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/AccessibleInstantiator.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.basic;
+
+/**
+ * Instantiates a class by grabbing the no-args constructor, making it accessible and then calling
+ * Constructor.newInstance(). Although this still requires no-arg constructors, it can call non-public constructors (if
+ * the security manager allows it).
+ * 
+ * @author Joe Walnes
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class AccessibleInstantiator
+    extends ConstructorInstantiator
+{
+
+    public AccessibleInstantiator( Class<?> type )
+    {
+        super( type );
+        if ( constructor != null )
+        {
+            constructor.setAccessible( true );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ConstructorInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ConstructorInstantiator.java
new file mode 100644
index 0000000..df93435
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ConstructorInstantiator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.basic;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance(). This can deal with
+ * default public constructors, but that's about it.
+ * 
+ * @author Joe Walnes
+ * @see ObjectInstantiator
+ */
+public class ConstructorInstantiator
+    implements ObjectInstantiator
+{
+
+    protected Constructor<?> constructor;
+
+    public ConstructorInstantiator( Class<?> type )
+    {
+        try
+        {
+            constructor = type.getDeclaredConstructor( (Class[]) null );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return constructor.newInstance( (Object[]) null );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/NewInstanceInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/NewInstanceInstantiator.java
new file mode 100644
index 0000000..d1ebb80
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/NewInstanceInstantiator.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.basic;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * The simplest instantiator - simply calls Class.newInstance(). This can deal with default public constructors, but
+ * that's about it.
+ * 
+ * @author Joe Walnes
+ * @see ObjectInstantiator
+ */
+public class NewInstanceInstantiator
+    implements ObjectInstantiator
+{
+
+    private final Class<?> type;
+
+    public NewInstanceInstantiator( Class<?> type )
+    {
+        this.type = type;
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return type.newInstance();
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectInputStreamInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectInputStreamInstantiator.java
new file mode 100644
index 0000000..d4b08cd
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectInputStreamInstantiator.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.basic;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.ObjectStreamConstants;
+import java.io.Serializable;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by using a dummy input stream that always feeds data for an empty object of the same kind. NOTE:
+ * This instantiator may not work properly if the class being instantiated defines a "readResolve" method, since it may
+ * return objects that have been returned previously (i.e., there's no guarantee that the returned object is a new one),
+ * or even objects from a completely different class.
+ * 
+ * @author Leonardo Mesquita
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class ObjectInputStreamInstantiator
+    implements ObjectInstantiator
+{
+
+    private static class MockStream
+        extends InputStream
+    {
+
+        private int pointer;
+
+        private byte[] data;
+
+        private int sequence;
+
+        private static final int[] NEXT = new int[] { 1, 2, 2 };
+
+        private byte[][] buffers;
+
+        private final byte[] FIRST_DATA;
+
+        private static byte[] HEADER;
+
+        private static byte[] REPEATING_DATA;
+
+        static
+        {
+            initialize();
+        }
+
+        private static void initialize()
+        {
+            try
+            {
+                ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+                DataOutputStream dout = new DataOutputStream( byteOut );
+                dout.writeShort( ObjectStreamConstants.STREAM_MAGIC );
+                dout.writeShort( ObjectStreamConstants.STREAM_VERSION );
+                HEADER = byteOut.toByteArray();
+
+                byteOut = new ByteArrayOutputStream();
+                dout = new DataOutputStream( byteOut );
+
+                dout.writeByte( ObjectStreamConstants.TC_OBJECT );
+                dout.writeByte( ObjectStreamConstants.TC_REFERENCE );
+                dout.writeInt( ObjectStreamConstants.baseWireHandle );
+                REPEATING_DATA = byteOut.toByteArray();
+            }
+            catch ( IOException e )
+            {
+                throw new Error( "IOException: " + e.getMessage() );
+            }
+
+        }
+
+        public MockStream( Class<?> clazz )
+        {
+            this.pointer = 0;
+            this.sequence = 0;
+            this.data = HEADER;
+
+            // (byte) TC_OBJECT
+            // (byte) TC_CLASSDESC
+            // (short length)
+            // (byte * className.length)
+            // (long)serialVersionUID
+            // (byte) SC_SERIALIZABLE
+            // (short)0 <fields>
+            // TC_ENDBLOCKDATA
+            // TC_NULL
+            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+            DataOutputStream dout = new DataOutputStream( byteOut );
+            try
+            {
+                dout.writeByte( ObjectStreamConstants.TC_OBJECT );
+                dout.writeByte( ObjectStreamConstants.TC_CLASSDESC );
+                dout.writeUTF( clazz.getName() );
+                dout.writeLong( ObjectStreamClass.lookup( clazz ).getSerialVersionUID() );
+                dout.writeByte( ObjectStreamConstants.SC_SERIALIZABLE );
+                dout.writeShort( (short) 0 ); // Zero fields
+                dout.writeByte( ObjectStreamConstants.TC_ENDBLOCKDATA );
+                dout.writeByte( ObjectStreamConstants.TC_NULL );
+            }
+            catch ( IOException e )
+            {
+                throw new Error( "IOException: " + e.getMessage() );
+            }
+            this.FIRST_DATA = byteOut.toByteArray();
+            buffers = new byte[][] { HEADER, FIRST_DATA, REPEATING_DATA };
+        }
+
+        private void advanceBuffer()
+        {
+            pointer = 0;
+            sequence = NEXT[sequence];
+            data = buffers[sequence];
+        }
+
+        @Override
+        public int read()
+            throws IOException
+        {
+            int result = data[pointer++];
+            if ( pointer >= data.length )
+            {
+                advanceBuffer();
+            }
+
+            return result;
+        }
+
+        @Override
+        public int available()
+            throws IOException
+        {
+            return Integer.MAX_VALUE;
+        }
+
+        @Override
+        public int read( byte[] b, int off, int len )
+            throws IOException
+        {
+            int left = len;
+            int remaining = data.length - pointer;
+
+            while ( remaining <= left )
+            {
+                System.arraycopy( data, pointer, b, off, remaining );
+                off += remaining;
+                left -= remaining;
+                advanceBuffer();
+                remaining = data.length - pointer;
+            }
+            if ( left > 0 )
+            {
+                System.arraycopy( data, pointer, b, off, left );
+                pointer += left;
+            }
+
+            return len;
+        }
+    }
+
+    private ObjectInputStream inputStream;
+
+    public ObjectInputStreamInstantiator( Class<?> clazz )
+    {
+        if ( Serializable.class.isAssignableFrom( clazz ) )
+        {
+            try
+            {
+                this.inputStream = new ObjectInputStream( new MockStream( clazz ) );
+            }
+            catch ( IOException e )
+            {
+                throw new Error( "IOException: " + e.getMessage() );
+            }
+        }
+        else
+        {
+            throw new ObjenesisException( new NotSerializableException( clazz + " not serializable" ) );
+        }
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return inputStream.readObject();
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new Error( "ClassNotFoundException: " + e.getMessage() );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectStreamClassInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectStreamClassInstantiator.java
new file mode 100644
index 0000000..5ca72c8
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/basic/ObjectStreamClassInstantiator.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.basic;
+
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by using reflection to make a call to private method ObjectStreamClass.newInstance, present in
+ * many JVM implementations. This instantiator will create classes in a way compatible with serialization, calling the
+ * first non-serializable superclass' no-arg constructor.
+ * 
+ * @author Leonardo Mesquita
+ * @see ObjectInstantiator
+ * @see java.io.Serializable
+ */
+public class ObjectStreamClassInstantiator
+    implements ObjectInstantiator
+{
+
+    private static Method newInstanceMethod;
+
+    private static void initialize()
+    {
+        if ( newInstanceMethod == null )
+        {
+            try
+            {
+                newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( "newInstance", new Class[] {} );
+                newInstanceMethod.setAccessible( true );
+            }
+            catch ( RuntimeException e )
+            {
+                throw new ObjenesisException( e );
+            }
+            catch ( NoSuchMethodException e )
+            {
+                throw new ObjenesisException( e );
+            }
+        }
+    }
+
+    private final ObjectStreamClass objStreamClass;
+
+    public ObjectStreamClassInstantiator( Class<?> type )
+    {
+        initialize();
+        objStreamClass = ObjectStreamClass.lookup( type );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return newInstanceMethod.invoke( objStreamClass, new Object[] {} );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiator.java
new file mode 100644
index 0000000..bc09305
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiator.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.gcj;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to work on GCJ JVMs. This
+ * instantiator will not call any constructors.
+ * 
+ * @author Leonardo Mesquita
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class GCJInstantiator
+    extends GCJInstantiatorBase
+{
+
+    public GCJInstantiator( Class<?> type )
+    {
+        super( type );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return newObjectMethod.invoke( dummyStream, new Object[] { type, Object.class } );
+        }
+        catch ( RuntimeException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiatorBase.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiatorBase.java
new file mode 100644
index 0000000..b4a965f
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJInstantiatorBase.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.gcj;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Base class for GCJ-based instantiators. It initializes reflection access to method ObjectInputStream.newObject, as
+ * well as creating a dummy ObjectInputStream to be used as the "this" argument for the method.
+ * 
+ * @author Leonardo Mesquita
+ */
+public abstract class GCJInstantiatorBase
+    implements ObjectInstantiator
+{
+
+    protected static Method newObjectMethod = null;
+
+    protected static ObjectInputStream dummyStream;
+
+    private static class DummyStream
+        extends ObjectInputStream
+    {
+
+        public DummyStream()
+            throws IOException
+        {
+        }
+    }
+
+    private static void initialize()
+    {
+        if ( newObjectMethod == null )
+        {
+            try
+            {
+                newObjectMethod =
+                    ObjectInputStream.class.getDeclaredMethod( "newObject", new Class[] { Class.class, Class.class } );
+                newObjectMethod.setAccessible( true );
+                dummyStream = new DummyStream();
+            }
+            catch ( RuntimeException e )
+            {
+                throw new ObjenesisException( e );
+            }
+            catch ( NoSuchMethodException e )
+            {
+                throw new ObjenesisException( e );
+            }
+            catch ( IOException e )
+            {
+                throw new ObjenesisException( e );
+            }
+        }
+    }
+
+    protected final Class<?> type;
+
+    public GCJInstantiatorBase( Class<?> type )
+    {
+        this.type = type;
+        initialize();
+    }
+
+    @Override
+    public abstract Object newInstance();
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJSerializationInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJSerializationInstantiator.java
new file mode 100644
index 0000000..2875407
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/gcj/GCJSerializationInstantiator.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.gcj;
+
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+import org.apache.directmemory.lightning.internal.instantiator.SerializationInstantiatorHelper;
+
+/**
+ * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to work on GCJ JVMs. This
+ * instantiator will create classes in a way compatible with serialization, calling the first non-serializable
+ * superclass' no-arg constructor.
+ * 
+ * @author Leonardo Mesquita
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class GCJSerializationInstantiator
+    extends GCJInstantiatorBase
+{
+
+    private Class<?> superType;
+
+    public GCJSerializationInstantiator( Class<?> type )
+    {
+        super( type );
+        this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass( type );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return newObjectMethod.invoke( dummyStream, new Object[] { type, superType } );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercInstantiator.java
new file mode 100644
index 0000000..8ca5adb
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercInstantiator.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.perc;
+
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal Perc private methods. It is only supposed to work on Perc JVMs.
+ * This instantiator will not call any constructors. The code was provided by Aonix Perc support team.
+ * 
+ * @author Henri Tremblay
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class PercInstantiator
+    implements ObjectInstantiator
+{
+
+    private final Method newInstanceMethod;
+
+    private final Object[] typeArgs = new Object[] { null, Boolean.FALSE };
+
+    public PercInstantiator( Class<?> type )
+    {
+
+        typeArgs[0] = type;
+
+        try
+        {
+            newInstanceMethod =
+                ObjectInputStream.class.getDeclaredMethod( "newInstance", new Class[] { Class.class, Boolean.TYPE } );
+            newInstanceMethod.setAccessible( true );
+        }
+        catch ( RuntimeException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return newInstanceMethod.invoke( null, typeArgs );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercSerializationInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercSerializationInstantiator.java
new file mode 100644
index 0000000..e695e5c
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/perc/PercSerializationInstantiator.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.perc;
+
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal Perc private methods. It is only supposed to work on Perc JVMs.
+ * This instantiator will create classes in a way compatible with serialization, calling the first non-serializable
+ * superclass' no-arg constructor.
+ * <p/>
+ * Based on code provided by Aonix but <b>doesn't work right now</b>
+ * 
+ * @author Henri Tremblay
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class PercSerializationInstantiator
+    implements ObjectInstantiator
+{
+
+    private Object[] typeArgs;
+
+    private final java.lang.reflect.Method newInstanceMethod;
+
+    public PercSerializationInstantiator( Class<?> type )
+    {
+
+        // Find the first unserializable parent class
+        Class<?> unserializableType = type;
+
+        while ( Serializable.class.isAssignableFrom( unserializableType ) )
+        {
+            unserializableType = unserializableType.getSuperclass();
+        }
+
+        try
+        {
+            // Get the special Perc method to call
+            Class<?> percMethodClass = Class.forName( "COM.newmonics.PercClassLoader.Method" );
+
+            newInstanceMethod =
+                ObjectInputStream.class.getDeclaredMethod( "noArgConstruct", new Class[] { Class.class, Object.class,
+                    percMethodClass } );
+            newInstanceMethod.setAccessible( true );
+
+            // Create invoke params
+            Class<?> percClassClass = Class.forName( "COM.newmonics.PercClassLoader.PercClass" );
+            Method getPercClassMethod = percClassClass.getDeclaredMethod( "getPercClass", new Class[] { Class.class } );
+            Object someObject = getPercClassMethod.invoke( null, new Object[] { unserializableType } );
+            Method findMethodMethod =
+                someObject.getClass().getDeclaredMethod( "findMethod", new Class[] { String.class } );
+            Object percMethod = findMethodMethod.invoke( someObject, new Object[] { "<init>()V" } );
+
+            typeArgs = new Object[] { unserializableType, type, percMethod };
+
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return newInstanceMethod.invoke( null, typeArgs );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/BaseInstantiatorStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/BaseInstantiatorStrategy.java
new file mode 100644
index 0000000..db3ecad
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/BaseInstantiatorStrategy.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.strategy;
+
+/**
+ * Base {@link InstantiatorStrategy} class basically containing helpful constant to sort out JVMs.
+ * 
+ * @author Henri Tremblay
+ */
+public abstract class BaseInstantiatorStrategy
+    implements InstantiatorStrategy
+{
+
+    /** JVM_NAME prefix for BEA releases of JRockit */
+    protected static final String BEA_JROCKIT = "BEA";
+
+    /** JVM_NAME prefix for Oracle releases of JRockit */
+    protected static final String ORACLE_JROCKIT = "Oracle JRockit(R)";
+
+    /** JVM_NAME prefix for GCJ */
+    protected static final String GNU = "GNU libgcj";
+
+    /** JVM_NAME prefix for Sun Java HotSpot */
+    protected static final String SUN = "Java HotSpot";
+
+    /** JVM_NAME prefix for Aonix PERC */
+    protected static final String PERC = "PERC";
+
+    /** JVM version */
+    protected static final String VM_VERSION = System.getProperty( "java.runtime.version" );
+
+    /** JVM version */
+    protected static final String VM_INFO = System.getProperty( "java.vm.info" );
+
+    /** Vendor version */
+    protected static final String VENDOR_VERSION = System.getProperty( "java.vm.version" );
+
+    /** Vendor name */
+    protected static final String VENDOR = System.getProperty( "java.vm.vendor" );
+
+    /** JVM name */
+    protected static final String JVM_NAME = System.getProperty( "java.vm.name" );
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/InstantiatorStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/InstantiatorStrategy.java
new file mode 100644
index 0000000..9df7a13
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/InstantiatorStrategy.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.strategy;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+
+/**
+ * Defines a strategy to determine the best instantiator for a class.
+ * 
+ * @author Henri Tremblay
+ */
+public interface InstantiatorStrategy
+{
+
+    /**
+     * Create a dedicated instantiator for the given class
+     * 
+     * @param type Class that will be instantiate
+     * @return Dedicated instantiator
+     */
+    ObjectInstantiator newInstantiatorOf( Class<?> type );
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/SerializingInstantiatorStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/SerializingInstantiatorStrategy.java
new file mode 100644
index 0000000..042c999
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/SerializingInstantiatorStrategy.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.strategy;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.basic.ObjectStreamClassInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.gcj.GCJSerializationInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.perc.PercSerializationInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.sun.Sun13SerializationInstantiator;
+import org.apache.directmemory.lightning.internal.util.InternalUtil;
+
+/**
+ * Guess the best serializing instantiator for a given class. The returned instantiator will instantiate classes like
+ * the genuine java serialization framework (the constructor of the first not serializable class will be called).
+ * Currently, the selection doesn't depend on the class. It relies on the
+ * <ul>
+ * <li>JVM version</li>
+ * <li>JVM vendor</li>
+ * <li>JVM vendor version</li>
+ * </ul>
+ * However, instantiators are stateful and so dedicated to their class.
+ * 
+ * @author Henri Tremblay
+ * @see ObjectInstantiator
+ */
+public class SerializingInstantiatorStrategy
+    extends BaseInstantiatorStrategy
+{
+
+    /**
+     * Return an {@link ObjectInstantiator} allowing to create instance following the java serialization framework
+     * specifications.
+     * 
+     * @param type Class to instantiate
+     * @return The ObjectInstantiator for the class
+     */
+    @Override
+    public ObjectInstantiator newInstantiatorOf( Class<?> type )
+    {
+        if ( JVM_NAME.startsWith( SUN ) )
+        {
+            if ( VM_VERSION.startsWith( "1.3" ) )
+            {
+                return new Sun13SerializationInstantiator( type );
+            }
+            else if ( InternalUtil.isUnsafeAvailable() )
+            {
+                return InternalUtil.buildSunUnsafeInstantiator( type );
+            }
+        }
+        else if ( JVM_NAME.startsWith( GNU ) )
+        {
+            return new GCJSerializationInstantiator( type );
+        }
+        else if ( JVM_NAME.startsWith( PERC ) )
+        {
+            return new PercSerializationInstantiator( type );
+        }
+
+        return new ObjectStreamClassInstantiator( type );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/StdInstantiatorStrategy.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/StdInstantiatorStrategy.java
new file mode 100644
index 0000000..72f1351
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/strategy/StdInstantiatorStrategy.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.strategy;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.gcj.GCJInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.perc.PercInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.sun.Sun13Instantiator;
+import org.apache.directmemory.lightning.internal.instantiator.sun.SunReflectionFactoryInstantiator;
+import org.apache.directmemory.lightning.internal.util.InternalUtil;
+
+/**
+ * Guess the best instantiator for a given class. The instantiator will instantiate the class without calling any
+ * constructor. Currently, the selection doesn't depend on the class. It relies on the
+ * <ul>
+ * <li>JVM version</li>
+ * <li>JVM vendor</li>
+ * <li>JVM vendor version</li>
+ * </ul>
+ * However, instantiators are stateful and so dedicated to their class.
+ * 
+ * @author Henri Tremblay
+ * @see ObjectInstantiator
+ */
+public class StdInstantiatorStrategy
+    extends BaseInstantiatorStrategy
+{
+
+    /**
+     * Return an {@link ObjectInstantiator} allowing to create instance without any constructor being called.
+     * 
+     * @param type Class to instantiate
+     * @return The ObjectInstantiator for the class
+     */
+    @Override
+    public ObjectInstantiator newInstantiatorOf( Class<?> type )
+    {
+
+        if ( JVM_NAME.startsWith( SUN ) )
+        {
+            if ( VM_VERSION.startsWith( "1.3" ) )
+            {
+                return new Sun13Instantiator( type );
+            }
+            else if ( InternalUtil.isUnsafeAvailable() )
+            {
+                return InternalUtil.buildSunUnsafeInstantiator( type );
+            }
+        }
+        else if ( JVM_NAME.startsWith( ORACLE_JROCKIT ) )
+        {
+            if ( !VENDOR_VERSION.startsWith( "R" ) )
+            {
+                // Beginning with R25.1 sun.misc.Unsafe should work.
+                if ( InternalUtil.isUnsafeAvailable() )
+                {
+                    return InternalUtil.buildSunUnsafeInstantiator( type );
+                }
+            }
+        }
+        else if ( JVM_NAME.startsWith( GNU ) )
+        {
+            return new GCJInstantiator( type );
+        }
+        else if ( JVM_NAME.startsWith( PERC ) )
+        {
+            return new PercInstantiator( type );
+        }
+
+        // Fallback instantiator, should work with:
+        // - Java Hotspot version 1.4 and higher
+        // - JRockit 1.4-R26 and higher
+        // - IBM and Hitachi JVMs
+        // ... might works for others so we just give it a try
+        return new SunReflectionFactoryInstantiator( type );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13Instantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13Instantiator.java
new file mode 100644
index 0000000..c984adc
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13Instantiator.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Instantiates a class by making a call to internal Sun private methods. It is only supposed to work on Sun HotSpot 1.3
+ * JVM. This instantiator will not call any constructors.
+ * 
+ * @author Leonardo Mesquita
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class Sun13Instantiator
+    extends Sun13InstantiatorBase
+{
+
+    public Sun13Instantiator( Class<?> type )
+    {
+        super( type );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return allocateNewObjectMethod.invoke( null, new Object[] { type, Object.class } );
+        }
+        catch ( RuntimeException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new ObjenesisException( e );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13InstantiatorBase.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13InstantiatorBase.java
new file mode 100644
index 0000000..b64f33b
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13InstantiatorBase.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+/**
+ * Base class for Sun 1.3 based instantiators. It initializes reflection access to static method
+ * ObjectInputStream.allocateNewObject.
+ * 
+ * @author Leonardo Mesquita
+ */
+public abstract class Sun13InstantiatorBase
+    implements ObjectInstantiator
+{
+
+    protected static Method allocateNewObjectMethod = null;
+
+    private static void initialize()
+    {
+        if ( allocateNewObjectMethod == null )
+        {
+            try
+            {
+                allocateNewObjectMethod =
+                    ObjectInputStream.class.getDeclaredMethod( "allocateNewObject", new Class[] { Class.class,
+                        Class.class } );
+                allocateNewObjectMethod.setAccessible( true );
+            }
+            catch ( RuntimeException e )
+            {
+                throw new ObjenesisException( e );
+            }
+            catch ( NoSuchMethodException e )
+            {
+                throw new ObjenesisException( e );
+            }
+        }
+    }
+
+    protected final Class<?> type;
+
+    public Sun13InstantiatorBase( Class<?> type )
+    {
+        this.type = type;
+        initialize();
+    }
+
+    @Override
+    public abstract Object newInstance();
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13SerializationInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13SerializationInstantiator.java
new file mode 100644
index 0000000..904b581
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/Sun13SerializationInstantiator.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+import org.apache.directmemory.lightning.internal.instantiator.SerializationInstantiatorHelper;
+
+/**
+ * Instantiates a class by making a call to internal Sun private methods. It is only supposed to work on Sun HotSpot 1.3
+ * JVM. This instantiator will create classes in a way compatible with serialization, calling the first non-serializable
+ * superclass' no-arg constructor.
+ * 
+ * @author Leonardo Mesquita
+ * @see org.apache.directmemory.lightning.instantiator.ObjectInstantiator
+ */
+public class Sun13SerializationInstantiator
+    extends Sun13InstantiatorBase
+{
+
+    private final Class<?> superType;
+
+    public Sun13SerializationInstantiator( Class<?> type )
+    {
+        super( type );
+        this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass( type );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return allocateNewObjectMethod.invoke( null, new Object[] { type, superType } );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactoryInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactoryInstantiator.java
new file mode 100644
index 0000000..b88082d
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactoryInstantiator.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+
+import sun.reflect.ReflectionFactory;
+
+/**
+ * Instantiates an object, WITHOUT calling it's constructor, using internal sun.reflect.ReflectionFactory - a class only
+ * available on JDK's that use Sun's 1.4 (or later) Java implementation. This is the best way to instantiate an object
+ * without any side effects caused by the constructor - however it is not available on every platform.
+ * 
+ * @author Joe Walnes
+ * @see ObjectInstantiator
+ */
+@SuppressWarnings( "restriction" )
+public class SunReflectionFactoryInstantiator
+    implements ObjectInstantiator
+{
+
+    private final Constructor<?> mungedConstructor;
+
+    public SunReflectionFactoryInstantiator( Class<?> type )
+    {
+
+        ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
+        Constructor<?> javaLangObjectConstructor;
+
+        try
+        {
+            javaLangObjectConstructor = Object.class.getConstructor( (Class[]) null );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            throw new Error( "Cannot find constructor for java.lang.Object!" );
+        }
+        mungedConstructor = reflectionFactory.newConstructorForSerialization( type, javaLangObjectConstructor );
+        mungedConstructor.setAccessible( true );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return mungedConstructor.newInstance( (Object[]) null );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactorySerializationInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
new file mode 100644
index 0000000..e9be184
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import java.io.NotSerializableException;
+import java.lang.reflect.Constructor;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.instantiator.ObjenesisException;
+import org.apache.directmemory.lightning.internal.instantiator.SerializationInstantiatorHelper;
+
+import sun.reflect.ReflectionFactory;
+
+/**
+ * Instantiates an object using internal sun.reflect.ReflectionFactory - a class only available on JDK's that use Sun's
+ * 1.4 (or later) Java implementation. This instantiator will create classes in a way compatible with serialization,
+ * calling the first non-serializable superclass' no-arg constructor. This is the best way to instantiate an object
+ * without any side effects caused by the constructor - however it is not available on every platform.
+ * 
+ * @author Leonardo Mesquita
+ * @see ObjectInstantiator
+ */
+@SuppressWarnings( "restriction" )
+public class SunReflectionFactorySerializationInstantiator
+    implements ObjectInstantiator
+{
+
+    private final Constructor<?> mungedConstructor;
+
+    public SunReflectionFactorySerializationInstantiator( Class<?> type )
+    {
+
+        Class<?> nonSerializableAncestor = SerializationInstantiatorHelper.getNonSerializableSuperClass( type );
+        ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
+        Constructor<?> nonSerializableAncestorConstructor;
+        try
+        {
+            nonSerializableAncestorConstructor = nonSerializableAncestor.getConstructor( (Class[]) null );
+        }
+        catch ( NoSuchMethodException e )
+        {
+            /**
+             * @todo (Henri) I think we should throw a NotSerializableException just to put the same message a
+             *       ObjectInputStream. Otherwise, the user won't know if the null returned if a "Not serializable", a
+             *       "No default constructor on ancestor" or a "Exception in constructor"
+             */
+            throw new ObjenesisException( new NotSerializableException( type
+                + " has no suitable superclass constructor" ) );
+        }
+
+        mungedConstructor = reflectionFactory.newConstructorForSerialization( type, nonSerializableAncestorConstructor );
+        mungedConstructor.setAccessible( true );
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            return mungedConstructor.newInstance( (Object[]) null );
+        }
+        catch ( Exception e )
+        {
+            throw new ObjenesisException( e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunUnsafeAllocateInstanceInstantiator.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunUnsafeAllocateInstanceInstantiator.java
new file mode 100644
index 0000000..21bbd4a
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/instantiator/sun/SunUnsafeAllocateInstanceInstantiator.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.instantiator.sun;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.util.UnsafeUtil;
+
+@SuppressWarnings( "restriction" )
+public class SunUnsafeAllocateInstanceInstantiator
+    implements ObjectInstantiator
+{
+
+    private static final sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe();
+
+    protected final Class<?> type;
+
+    public SunUnsafeAllocateInstanceInstantiator( Class<?> type )
+    {
+        this.type = type;
+    }
+
+    @Override
+    public Object newInstance()
+    {
+        try
+        {
+            if ( UNSAFE != null )
+                return UNSAFE.allocateInstance( type );
+        }
+        catch ( Exception e )
+        {
+            // ignore and return null
+        }
+
+        return null;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferInputStream.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferInputStream.java
new file mode 100644
index 0000000..7cc3e78
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+public class BufferInputStream
+    extends InputStream
+{
+
+    private final ByteBuffer byteBuffer;
+
+    public BufferInputStream( ByteBuffer byteBuffer )
+    {
+        this.byteBuffer = byteBuffer;
+    }
+
+    @Override
+    public synchronized int read()
+        throws IOException
+    {
+        if ( !byteBuffer.hasRemaining() )
+        {
+            return -1;
+        }
+        return byteBuffer.get();
+    }
+
+    @Override
+    public synchronized int read( byte[] bytes, int off, int len )
+        throws IOException
+    {
+        len = Math.min( len, byteBuffer.remaining() );
+        byteBuffer.get( bytes, off, len );
+        return len;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferOutputStream.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferOutputStream.java
new file mode 100644
index 0000000..8c21645
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/BufferOutputStream.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class BufferOutputStream
+    extends OutputStream
+{
+
+    private final ByteBuffer byteBuffer;
+
+    public BufferOutputStream( ByteBuffer byteBuffer )
+    {
+        this.byteBuffer = byteBuffer;
+    }
+
+    @Override
+    public synchronized void write( int b )
+        throws IOException
+    {
+        byteBuffer.put( (byte) b );
+    }
+
+    @Override
+    public synchronized void write( byte[] bytes, int off, int len )
+        throws IOException
+    {
+        byteBuffer.put( bytes, off, len );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/ReaderInputStream.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/ReaderInputStream.java
new file mode 100644
index 0000000..f8431fc
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/ReaderInputStream.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+public class ReaderInputStream
+    extends InputStream
+{
+
+    /** Source Reader */
+    private Reader in;
+
+    private String encoding = System.getProperty( "file.encoding" );
+
+    private byte[] slack;
+
+    private int begin;
+
+    /**
+     * Construct a <CODE>ReaderInputStream</CODE> for the specified <CODE>Reader</CODE>.
+     * 
+     * @param reader <CODE>Reader</CODE>. Must not be <code>null</code>.
+     */
+    public ReaderInputStream( Reader reader )
+    {
+        in = reader;
+    }
+
+    /**
+     * Construct a <CODE>ReaderInputStream</CODE> for the specified <CODE>Reader</CODE>, with the specified encoding.
+     * 
+     * @param reader non-null <CODE>Reader</CODE>.
+     * @param encoding non-null <CODE>String</CODE> encoding.
+     */
+    public ReaderInputStream( Reader reader, String encoding )
+    {
+        this( reader );
+        if ( encoding == null )
+        {
+            throw new IllegalArgumentException( "encoding must not be null" );
+        }
+        else
+        {
+            this.encoding = encoding;
+        }
+    }
+
+    /**
+     * Reads from the <CODE>Reader</CODE>, returning the same value.
+     * 
+     * @return the value of the next character in the <CODE>Reader</CODE>.
+     * @exception IOException if the original <code>Reader</code> fails to be read
+     */
+    @Override
+    public synchronized int read()
+        throws IOException
+    {
+        if ( in == null )
+        {
+            throw new IOException( "Stream Closed" );
+        }
+
+        byte result;
+        if ( slack != null && begin < slack.length )
+        {
+            result = slack[begin];
+            if ( ++begin == slack.length )
+            {
+                slack = null;
+            }
+        }
+        else
+        {
+            byte[] buf = new byte[1];
+            if ( read( buf, 0, 1 ) <= 0 )
+            {
+                result = -1;
+            }
+            result = buf[0];
+        }
+
+        if ( result < -1 )
+        {
+            result += 256;
+        }
+
+        return result;
+    }
+
+    /**
+     * Reads from the <code>Reader</code> into a byte array
+     * 
+     * @param b the byte array to read into
+     * @param off the offset in the byte array
+     * @param len the length in the byte array to fill
+     * @return the actual number read into the byte array, -1 at the end of the stream
+     * @exception IOException if an error occurs
+     */
+    @Override
+    public synchronized int read( byte[] b, int off, int len )
+        throws IOException
+    {
+        if ( in == null )
+        {
+            throw new IOException( "Stream Closed" );
+        }
+
+        while ( slack == null )
+        {
+            char[] buf = new char[len]; // might read too much
+            int n = in.read( buf );
+            if ( n == -1 )
+            {
+                return -1;
+            }
+            if ( n > 0 )
+            {
+                slack = new String( buf, 0, n ).getBytes( encoding );
+                begin = 0;
+            }
+        }
+
+        if ( len > slack.length - begin )
+        {
+            len = slack.length - begin;
+        }
+
+        System.arraycopy( slack, begin, b, off, len );
+
+        if ( ( begin += len ) >= slack.length )
+        {
+            slack = null;
+        }
+
+        return len;
+    }
+
+    /**
+     * Marks the read limit of the StringReader.
+     * 
+     * @param limit the maximum limit of bytes that can be read before the mark position becomes invalid
+     */
+    @Override
+    public synchronized void mark( final int limit )
+    {
+        try
+        {
+            in.mark( limit );
+        }
+        catch ( IOException ioe )
+        {
+            throw new RuntimeException( ioe.getMessage() );
+        }
+    }
+
+    /**
+     * @return the current number of bytes ready for reading
+     * @exception IOException if an error occurs
+     */
+    @Override
+    public synchronized int available()
+        throws IOException
+    {
+        if ( in == null )
+        {
+            throw new IOException( "Stream Closed" );
+        }
+        if ( slack != null )
+        {
+            return slack.length - begin;
+        }
+        if ( in.ready() )
+        {
+            return 1;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+    /**
+     * @return false - mark is not supported
+     */
+    @Override
+    public boolean markSupported()
+    {
+        return false; // would be imprecise
+    }
+
+    /**
+     * Resets the StringReader.
+     * 
+     * @exception IOException if the StringReader fails to be reset
+     */
+    @Override
+    public synchronized void reset()
+        throws IOException
+    {
+        if ( in == null )
+        {
+            throw new IOException( "Stream Closed" );
+        }
+        slack = null;
+        in.reset();
+    }
+
+    /**
+     * Closes the Stringreader.
+     * 
+     * @exception IOException if the original StringReader fails to be closed
+     */
+    @Override
+    public synchronized void close()
+        throws IOException
+    {
+        if ( in != null )
+        {
+            in.close();
+            slack = null;
+            in = null;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/WriterOutputStream.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/WriterOutputStream.java
new file mode 100644
index 0000000..2120bb9
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/io/WriterOutputStream.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+/* ------------------------------------------------------------ */
+/**
+ * Wrap a Writer as an OutputStream. When all you have is a Writer and only an OutputStream will do. Try not to use this
+ * as it indicates that your design is a dogs breakfast (JSP made me write it).
+ * 
+ * @author Greg Wilkins (gregw) - Mort Bay Consulting Pty. Ltd.
+ */
+public class WriterOutputStream
+    extends OutputStream
+{
+
+    protected Writer _writer;
+
+    protected String _encoding;
+
+    private byte[] _buf = new byte[1];
+
+    /* ------------------------------------------------------------ */
+    public WriterOutputStream( Writer writer, String encoding )
+    {
+        _writer = writer;
+        _encoding = encoding;
+    }
+
+    /* ------------------------------------------------------------ */
+    public WriterOutputStream( Writer writer )
+    {
+        _writer = writer;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void close()
+        throws IOException
+    {
+        _writer.close();
+        _writer = null;
+        _encoding = null;
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void flush()
+        throws IOException
+    {
+        _writer.flush();
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write( byte[] b )
+        throws IOException
+    {
+        if ( _encoding == null )
+            _writer.write( new String( b ) );
+        else
+            _writer.write( new String( b, _encoding ) );
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public void write( byte[] b, int off, int len )
+        throws IOException
+    {
+        if ( _encoding == null )
+            _writer.write( new String( b, off, len ) );
+        else
+            _writer.write( new String( b, off, len, _encoding ) );
+    }
+
+    /* ------------------------------------------------------------ */
+    @Override
+    public synchronized void write( int b )
+        throws IOException
+    {
+        _buf[0] = (byte) b;
+        write( _buf );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshaller.java
new file mode 100644
index 0000000..7a4acc6
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshaller.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class BigDecimalMarshaller
+    extends AbstractMarshaller
+{
+
+    private static final Charset CHARSET = Charset.forName( "ASCII" );
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return BigDecimal.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        String representation = ( (BigDecimal) value ).toString();
+        byte[] data = representation.getBytes( CHARSET );
+        dataOutput.writeInt( data.length );
+        dataOutput.write( data );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int length = dataInput.readInt();
+        byte[] data = new byte[length];
+        dataInput.readFully( data );
+
+        return (V) new BigDecimal( new String( data, CHARSET ) );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshaller.java
new file mode 100644
index 0000000..f71f21f
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshaller.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class BigIntegerMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return BigInteger.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        byte[] data = ( (BigInteger) value ).toByteArray();
+        dataOutput.writeInt( data.length );
+        dataOutput.write( data );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int length = dataInput.readInt();
+        byte[] data = new byte[length];
+        dataInput.readFully( data );
+
+        return (V) new BigInteger( data );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanArrayMarshaller.java
new file mode 100644
index 0000000..ea696bd
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class BooleanArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return boolean[].class == type || Boolean[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( boolean[].class == propertyDescriptor.getType() )
+        {
+            boolean[] array = (boolean[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( boolean arrayValue : array )
+            {
+                dataOutput.writeBoolean( arrayValue );
+            }
+        }
+        else
+        {
+            Boolean[] array = (Boolean[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( boolean arrayValue : array )
+            {
+                dataOutput.writeBoolean( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( boolean[].class == propertyDescriptor.getType() )
+        {
+            boolean[] array = new boolean[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readBoolean();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Boolean[] array = new Boolean[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readBoolean();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshaller.java
new file mode 100644
index 0000000..061ac0f
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class BooleanMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return boolean.class == type || Boolean.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Boolean.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeBoolean( (Boolean) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Boolean.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Boolean.valueOf( dataInput.readBoolean() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteArrayMarshaller.java
new file mode 100644
index 0000000..a3e5c8a
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ByteArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return byte[].class == type || Byte[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( byte[].class == propertyDescriptor.getType() )
+        {
+            byte[] array = (byte[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( byte arrayValue : array )
+            {
+                dataOutput.writeByte( arrayValue );
+            }
+        }
+        else
+        {
+            Byte[] array = (Byte[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( byte arrayValue : array )
+            {
+                dataOutput.writeByte( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( byte[].class == propertyDescriptor.getType() )
+        {
+            byte[] array = new byte[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readByte();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Byte[] array = new Byte[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readByte();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshaller.java
new file mode 100644
index 0000000..0e112cf
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ByteMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return byte.class == type || Byte.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Byte.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeByte( (Byte) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Byte.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Byte.valueOf( dataInput.readByte() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterArrayMarshaller.java
new file mode 100644
index 0000000..bb19e74
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class CharacterArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return char[].class == type || Character[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( char[].class == propertyDescriptor.getType() )
+        {
+            char[] array = (char[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( char arrayValue : array )
+            {
+                dataOutput.writeChar( arrayValue );
+            }
+        }
+        else
+        {
+            Character[] array = (Character[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( char arrayValue : array )
+            {
+                dataOutput.writeChar( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( char[].class == propertyDescriptor.getType() )
+        {
+            char[] array = new char[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readChar();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Character[] array = new Character[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readChar();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshaller.java
new file mode 100644
index 0000000..337bdff
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class CharacterMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return char.class == type || Character.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Character.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeChar( (Character) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Character.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Character.valueOf( dataInput.readChar() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleArrayMarshaller.java
new file mode 100644
index 0000000..7acdaec
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class DoubleArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return double[].class == type || Double[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( double[].class == propertyDescriptor.getType() )
+        {
+            double[] array = (double[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( double arrayValue : array )
+            {
+                dataOutput.writeDouble( arrayValue );
+            }
+        }
+        else
+        {
+            Double[] array = (Double[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( double arrayValue : array )
+            {
+                dataOutput.writeDouble( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( double[].class == propertyDescriptor.getType() )
+        {
+            double[] array = new double[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readDouble();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Double[] array = new Double[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readDouble();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshaller.java
new file mode 100644
index 0000000..a668f70
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class DoubleMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return double.class == type || Double.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Double.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeDouble( (Double) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Double.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Double.valueOf( dataInput.readDouble() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/EnumMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/EnumMarshaller.java
new file mode 100644
index 0000000..907dc79
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/EnumMarshaller.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class EnumMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Enum.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        dataOutput.writeLong( serializationContext.getClassDefinitionContainer().getClassDefinitionByType( propertyDescriptor.getType() ).getId() );
+        dataOutput.writeInt( ( (Enum<?>) value ).ordinal() );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        long typeId = dataInput.readLong();
+        Class<?> propertyType = serializationContext.getClassDefinitionContainer().getTypeById( typeId );
+
+        int ordinal = dataInput.readInt();
+        Enum<?>[] values = ( (Class<Enum<?>>) propertyType ).getEnumConstants();
+        for ( Enum<?> value : values )
+        {
+            if ( value.ordinal() == ordinal )
+            {
+                return (V) value;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ExternalizableMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ExternalizableMarshaller.java
new file mode 100644
index 0000000..cb59667
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ExternalizableMarshaller.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ExternalizableMarshaller
+    extends AbstractObjectMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Externalizable.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        ( (Externalizable) value ).writeExternal( (ObjectOutput) dataOutput );
+    }
+
+    @Override
+    public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        try
+        {
+            ( (Externalizable) value ).readExternal( (ObjectInput) dataInput );
+            return value;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new IOException( "Error while deserialization", e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatArrayMarshaller.java
new file mode 100644
index 0000000..826345d
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class FloatArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return float[].class == type || Float[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( float[].class == propertyDescriptor.getType() )
+        {
+            float[] array = (float[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( float arrayValue : array )
+            {
+                dataOutput.writeFloat( arrayValue );
+            }
+        }
+        else
+        {
+            Float[] array = (Float[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( float arrayValue : array )
+            {
+                dataOutput.writeFloat( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( float[].class == propertyDescriptor.getType() )
+        {
+            float[] array = new float[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readFloat();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Float[] array = new Float[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readFloat();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshaller.java
new file mode 100644
index 0000000..0004096
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class FloatMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return float.class == type || Float.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Float.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeFloat( (Float) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Float.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Float.valueOf( dataInput.readFloat() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerArrayMarshaller.java
new file mode 100644
index 0000000..17d0cd7
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class IntegerArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return int[].class == type || Integer[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( int[].class == propertyDescriptor.getType() )
+        {
+            int[] array = (int[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( int arrayValue : array )
+            {
+                dataOutput.writeInt( arrayValue );
+            }
+        }
+        else
+        {
+            Integer[] array = (Integer[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( int arrayValue : array )
+            {
+                dataOutput.writeInt( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( int[].class == propertyDescriptor.getType() )
+        {
+            int[] array = new int[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readInt();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Integer[] array = new Integer[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readInt();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshaller.java
new file mode 100644
index 0000000..1975e9d
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class IntegerMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return int.class == type || Integer.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Integer.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeInt( (Integer) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Integer.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Integer.valueOf( dataInput.readInt() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshaller.java
new file mode 100644
index 0000000..ff5a9c4
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshaller.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.exceptions.SerializerExecutionException;
+import org.apache.directmemory.lightning.internal.CheatPropertyDescriptor;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ListMarshaller
+    extends AbstractMarshaller
+    implements TypeBindableMarshaller
+{
+
+    private final Type listType;
+
+    private Marshaller listTypeMarshaller;
+
+    public ListMarshaller()
+    {
+        this( null );
+    }
+
+    private ListMarshaller( Type listType )
+    {
+        this.listType = listType;
+    }
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return List.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( writePossibleNull( value, dataOutput ) )
+        {
+            List<?> list = (List<?>) value;
+            dataOutput.writeInt( list.size() );
+
+            Marshaller marshaller = null;
+            ClassDefinition classDefinition = null;
+            PropertyDescriptor pd = null;
+            if ( listType != null )
+            {
+                ensureMarshallerInitialized( serializationContext );
+                marshaller = listTypeMarshaller;
+                Class<?> baseType = TypeUtil.getBaseType( listType );
+                classDefinition =
+                    serializationContext.getClassDefinitionContainer().getClassDefinitionByType( baseType );
+                pd = new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "List", baseType, marshaller );
+            }
+
+            for ( Object entry : list )
+            {
+                if ( writePossibleNull( entry, dataOutput ) )
+                {
+                    if ( listType == null )
+                    {
+                        marshaller = serializationContext.findMarshaller( entry.getClass() );
+                        classDefinition =
+                            serializationContext.getClassDefinitionContainer().getClassDefinitionByType( entry.getClass() );
+                        pd =
+                            new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "List",
+                                                         entry.getClass(), marshaller );
+                    }
+
+                    if ( classDefinition == null )
+                    {
+                        throw new SerializerExecutionException( "No ClassDefinition found for type " + entry.getClass() );
+                    }
+
+                    dataOutput.writeLong( classDefinition.getId() );
+                    marshaller.marshall( entry, pd, dataOutput, serializationContext );
+                }
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        List list = new ArrayList( size );
+        if ( size > 0 )
+        {
+            for ( int i = 0; i < size; i++ )
+            {
+                if ( isNull( dataInput ) )
+                {
+                    list.add( null );
+                }
+                else
+                {
+                    long classId = dataInput.readLong();
+                    ClassDefinition classDefinition =
+                        serializationContext.getClassDefinitionContainer().getClassDefinitionById( classId );
+
+                    Marshaller marshaller;
+                    if ( listType != null )
+                    {
+                        ensureMarshallerInitialized( serializationContext );
+                        marshaller = listTypeMarshaller;
+                    }
+                    else
+                    {
+                        marshaller = serializationContext.findMarshaller( classDefinition.getType() );
+                    }
+
+                    PropertyDescriptor pd =
+                        new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "List",
+                                                     classDefinition.getType(), marshaller );
+                    list.add( marshaller.unmarshall( pd, dataInput, serializationContext ) );
+                }
+            }
+        }
+
+        return (V) list;
+    }
+
+    @Override
+    public Marshaller bindType( Type... bindingTypes )
+    {
+        if ( bindingTypes == null )
+        {
+            return new ListMarshaller();
+        }
+
+        if ( bindingTypes.length != 1 )
+        {
+            throw new SerializerExecutionException( "List type binding has no single generic: "
+                + Arrays.toString( bindingTypes ) );
+        }
+
+        Type listType = bindingTypes[0];
+        return new ListMarshaller( listType );
+    }
+
+    private void ensureMarshallerInitialized( SerializationContext serializationContext )
+    {
+        if ( listTypeMarshaller != null )
+            return;
+
+        listTypeMarshaller = serializationContext.findMarshaller( listType );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongArrayMarshaller.java
new file mode 100644
index 0000000..8594aaf
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class LongArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return long[].class == type || Long[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( long[].class == propertyDescriptor.getType() )
+        {
+            long[] array = (long[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( long arrayValue : array )
+            {
+                dataOutput.writeLong( arrayValue );
+            }
+        }
+        else
+        {
+            Long[] array = (Long[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( long arrayValue : array )
+            {
+                dataOutput.writeLong( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( long[].class == propertyDescriptor.getType() )
+        {
+            long[] array = new long[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readLong();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Long[] array = new Long[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readLong();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshaller.java
new file mode 100644
index 0000000..cf53a49
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class LongMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return long.class == type || Long.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Long.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeLong( (Long) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Long.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Long.valueOf( dataInput.readLong() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshaller.java
new file mode 100644
index 0000000..8d6c2a7
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshaller.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.exceptions.SerializerExecutionException;
+import org.apache.directmemory.lightning.internal.CheatPropertyDescriptor;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class MapMarshaller
+    extends AbstractMarshaller
+    implements TypeBindableMarshaller
+{
+
+    private final Type mapKeyType;
+
+    private final Type mapValueType;
+
+    private Marshaller mapKeyTypeMarshaller;
+
+    private Marshaller mapValueTypeMarshaller;
+
+    public MapMarshaller()
+    {
+        this( null, null );
+    }
+
+    private MapMarshaller( Type mapKeyType, Type mapValueType )
+    {
+        this.mapKeyType = mapKeyType;
+        this.mapValueType = mapValueType;
+    }
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Map.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( writePossibleNull( value, dataOutput ) )
+        {
+            Map<?, ?> map = (Map<?, ?>) value;
+            dataOutput.writeInt( map.size() );
+
+            Marshaller keyMarshaller = null;
+            ClassDefinition keyClassDefinition = null;
+            PropertyDescriptor keyPd = null;
+            Marshaller valueMarshaller = null;
+            ClassDefinition valueClassDefinition = null;
+            PropertyDescriptor valuePd = null;
+            if ( mapKeyType != null )
+            {
+                ensureMarshallersInitialized( serializationContext );
+                keyMarshaller = mapKeyTypeMarshaller;
+                Class<?> baseType = TypeUtil.getBaseType( mapKeyType );
+                keyClassDefinition =
+                    serializationContext.getClassDefinitionContainer().getClassDefinitionByType( baseType );
+                keyPd =
+                    new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Key", baseType, keyMarshaller );
+
+                valueMarshaller = mapValueTypeMarshaller;
+                baseType = TypeUtil.getBaseType( mapValueType );
+                valueClassDefinition =
+                    serializationContext.getClassDefinitionContainer().getClassDefinitionByType( baseType );
+                valuePd =
+                    new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Value", baseType,
+                                                 valueMarshaller );
+            }
+
+            for ( Entry<?, ?> entry : map.entrySet() )
+            {
+                if ( mapKeyType == null )
+                {
+                    keyMarshaller =
+                        entry.getKey() != null ? serializationContext.findMarshaller( entry.getKey().getClass() )
+                                        : null;
+                    keyClassDefinition =
+                        serializationContext.getClassDefinitionContainer().getClassDefinitionByType( entry.getKey().getClass() );
+                    keyPd =
+                        new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Key",
+                                                     entry.getKey().getClass(), keyMarshaller );
+
+                    if ( entry.getValue() != null )
+                    {
+                        valueMarshaller =
+                            entry.getValue() != null ? serializationContext.findMarshaller( entry.getValue().getClass() )
+                                            : null;
+                        valueClassDefinition =
+                            serializationContext.getClassDefinitionContainer().getClassDefinitionByType( entry.getValue().getClass() );
+                        valuePd =
+                            new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Value",
+                                                         entry.getValue().getClass(), valueMarshaller );
+                    }
+                }
+
+                if ( writePossibleNull( entry.getKey(), dataOutput ) )
+                {
+                    dataOutput.writeLong( keyClassDefinition.getId() );
+                    keyMarshaller.marshall( entry.getKey(), keyPd, dataOutput, serializationContext );
+                }
+
+                if ( writePossibleNull( entry.getValue(), dataOutput ) )
+                {
+                    dataOutput.writeLong( valueClassDefinition.getId() );
+                    valueMarshaller.marshall( entry.getValue(), valuePd, dataOutput, serializationContext );
+                }
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        Map map = new LinkedHashMap( size );
+        if ( size > 0 )
+        {
+            for ( int i = 0; i < size; i++ )
+            {
+                Object key = null;
+                if ( !isNull( dataInput ) )
+                {
+                    long keyClassId = dataInput.readLong();
+                    ClassDefinition keyClassDefinition =
+                        serializationContext.getClassDefinitionContainer().getClassDefinitionById( keyClassId );
+
+                    Marshaller keyMarshaller;
+                    if ( mapKeyType != null )
+                    {
+                        ensureMarshallersInitialized( serializationContext );
+                        keyMarshaller = mapKeyTypeMarshaller;
+                    }
+                    else
+                    {
+                        keyMarshaller = serializationContext.findMarshaller( keyClassDefinition.getType() );
+                    }
+
+                    PropertyDescriptor pd =
+                        new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Key",
+                                                     keyClassDefinition.getType(), keyMarshaller );
+                    key = keyMarshaller.unmarshall( pd, dataInput, serializationContext );
+                }
+
+                Object value = null;
+                if ( !isNull( dataInput ) )
+                {
+                    long valueClassId = dataInput.readLong();
+                    ClassDefinition valueClassDefinition =
+                        serializationContext.getClassDefinitionContainer().getClassDefinitionById( valueClassId );
+
+                    Marshaller valueMarshaller;
+                    if ( mapKeyType != null )
+                    {
+                        ensureMarshallersInitialized( serializationContext );
+                        valueMarshaller = mapValueTypeMarshaller;
+                    }
+                    else
+                    {
+                        valueMarshaller = serializationContext.findMarshaller( valueClassDefinition.getType() );
+                    }
+
+                    PropertyDescriptor pd =
+                        new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Value",
+                                                     valueClassDefinition.getType(), valueMarshaller );
+                    value = valueMarshaller.unmarshall( pd, dataInput, serializationContext );
+                }
+
+                map.put( key, value );
+            }
+        }
+
+        return (V) map;
+    }
+
+    @Override
+    public Marshaller bindType( Type... bindingTypes )
+    {
+        if ( bindingTypes == null )
+        {
+            return new MapMarshaller();
+        }
+
+        if ( bindingTypes.length != 2 )
+        {
+            throw new SerializerExecutionException( "Map type binding has no double generic: "
+                + Arrays.toString( bindingTypes ) );
+        }
+
+        Class<?> mapKeyType = (Class<?>) bindingTypes[0];
+        Class<?> mapValueType = (Class<?>) bindingTypes[1];
+        return new MapMarshaller( mapKeyType, mapValueType );
+    }
+
+    private void ensureMarshallersInitialized( SerializationContext serializationContext )
+    {
+        if ( mapKeyTypeMarshaller != null && mapValueTypeMarshaller != null )
+            return;
+
+        mapKeyTypeMarshaller = serializationContext.findMarshaller( mapKeyType );
+        mapValueTypeMarshaller = serializationContext.findMarshaller( mapValueType );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SerializableMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SerializableMarshaller.java
new file mode 100644
index 0000000..41f4205
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SerializableMarshaller.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class SerializableMarshaller
+    extends AbstractObjectMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Serializable.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        ObjectOutputStream stream = new ObjectOutputStream( (OutputStream) dataOutput );
+        stream.writeObject( value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        ObjectInputStream stream = new ObjectInputStream( (InputStream) dataInput );
+        try
+        {
+            return (V) stream.readObject();
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new IOException( "Error while deserialization", e );
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshaller.java
new file mode 100644
index 0000000..8341514
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshaller.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.TypeBindableMarshaller;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.exceptions.SerializerExecutionException;
+import org.apache.directmemory.lightning.internal.CheatPropertyDescriptor;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class SetMarshaller
+    extends AbstractMarshaller
+    implements TypeBindableMarshaller
+{
+
+    private final Type setType;
+
+    private Marshaller setTypeMarshaller;
+
+    public SetMarshaller()
+    {
+        this( null );
+    }
+
+    private SetMarshaller( Type setType )
+    {
+        this.setType = setType;
+    }
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Set.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( writePossibleNull( value, dataOutput ) )
+        {
+            Set<?> set = (Set<?>) value;
+            dataOutput.writeInt( set.size() );
+
+            Marshaller marshaller = null;
+            ClassDefinition classDefinition = null;
+            PropertyDescriptor pd = null;
+            if ( setType != null )
+            {
+                ensureMarshallerInitialized( serializationContext );
+                marshaller = setTypeMarshaller;
+                Class<?> baseType = TypeUtil.getBaseType( setType );
+                classDefinition =
+                    serializationContext.getClassDefinitionContainer().getClassDefinitionByType( baseType );
+                pd = new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Set", baseType, marshaller );
+            }
+
+            for ( Object entry : set )
+            {
+                if ( writePossibleNull( entry, dataOutput ) )
+                {
+                    if ( setType == null )
+                    {
+                        marshaller = serializationContext.findMarshaller( entry.getClass() );
+                        classDefinition =
+                            serializationContext.getClassDefinitionContainer().getClassDefinitionByType( entry.getClass() );
+                        pd =
+                            new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Set",
+                                                         entry.getClass(), marshaller );
+                    }
+
+                    dataOutput.writeLong( classDefinition.getId() );
+                    marshaller.marshall( entry, pd, dataOutput, serializationContext );
+                }
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        Set set = new HashSet( size );
+        if ( size > 0 )
+        {
+            for ( int i = 0; i < size; i++ )
+            {
+                if ( isNull( dataInput ) )
+                {
+                    set.add( null );
+                }
+                else
+                {
+                    long classId = dataInput.readLong();
+                    ClassDefinition classDefinition =
+                        serializationContext.getClassDefinitionContainer().getClassDefinitionById( classId );
+
+                    Marshaller marshaller;
+                    if ( setType != null )
+                    {
+                        ensureMarshallerInitialized( serializationContext );
+                        marshaller = setTypeMarshaller;
+                    }
+                    else
+                    {
+                        marshaller = serializationContext.findMarshaller( classDefinition.getType() );
+                    }
+
+                    PropertyDescriptor pd =
+                        new CheatPropertyDescriptor( propertyDescriptor.getPropertyName() + "Set",
+                                                     classDefinition.getType(), marshaller );
+                    set.add( marshaller.unmarshall( pd, dataInput, serializationContext ) );
+                }
+            }
+        }
+
+        return (V) set;
+    }
+
+    @Override
+    public Marshaller bindType( Type... bindingTypes )
+    {
+        if ( bindingTypes == null )
+        {
+            return new SetMarshaller();
+        }
+
+        if ( bindingTypes.length != 1 )
+        {
+            throw new SerializerExecutionException( "Set type binding has no single generic: "
+                + Arrays.toString( bindingTypes ) );
+        }
+
+        Type setType = bindingTypes[0];
+        return new SetMarshaller( setType );
+    }
+
+    private void ensureMarshallerInitialized( SerializationContext serializationContext )
+    {
+        if ( setTypeMarshaller != null )
+            return;
+
+        setTypeMarshaller = serializationContext.findMarshaller( setType );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortArrayMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortArrayMarshaller.java
new file mode 100644
index 0000000..4eaacc4
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortArrayMarshaller.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ShortArrayMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return short[].class == type || Short[].class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        if ( short[].class == propertyDescriptor.getType() )
+        {
+            short[] array = (short[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( short arrayValue : array )
+            {
+                dataOutput.writeShort( arrayValue );
+            }
+        }
+        else
+        {
+            Short[] array = (Short[]) value;
+            dataOutput.writeInt( array.length );
+
+            for ( short arrayValue : array )
+            {
+                dataOutput.writeShort( arrayValue );
+            }
+        }
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        int size = dataInput.readInt();
+        if ( short[].class == propertyDescriptor.getType() )
+        {
+            short[] array = new short[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readShort();
+            }
+
+            return (V) array;
+        }
+        else
+        {
+            Short[] array = new Short[size];
+            for ( int i = 0; i < size; i++ )
+            {
+                array[i] = dataInput.readShort();
+            }
+
+            return (V) array;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshaller.java
new file mode 100644
index 0000000..590f543
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class ShortMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return short.class == type || Short.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( Short.class == propertyDescriptor.getType() )
+        {
+            if ( !writePossibleNull( value, dataOutput ) )
+            {
+                return;
+            }
+        }
+
+        dataOutput.writeShort( (Short) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( Short.class == propertyDescriptor.getType() )
+        {
+            if ( isNull( dataInput ) )
+            {
+                return null;
+            }
+        }
+
+        return (V) Short.valueOf( dataInput.readShort() );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StreamedMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StreamedMarshaller.java
new file mode 100644
index 0000000..67a28fa
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StreamedMarshaller.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.Streamed;
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class StreamedMarshaller
+    extends AbstractObjectMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return Streamed.class.isAssignableFrom( type );
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        ( (Streamed) value ).writeTo( dataOutput );
+    }
+
+    @Override
+    public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        ( (Streamed) value ).readFrom( dataInput );
+        return value;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StringMarshaller.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StringMarshaller.java
new file mode 100644
index 0000000..ba8ecb0
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/marshaller/StringMarshaller.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.base.AbstractMarshaller;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class StringMarshaller
+    extends AbstractMarshaller
+{
+
+    @Override
+    public boolean acceptType( Class<?> type )
+    {
+        return String.class == type;
+    }
+
+    @Override
+    public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                          SerializationContext serializationContext )
+        throws IOException
+    {
+
+        if ( !writePossibleNull( value, dataOutput ) )
+        {
+            return;
+        }
+
+        dataOutput.writeUTF( (String) value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public <V> V unmarshall( PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                             SerializationContext serializationContext )
+        throws IOException
+    {
+        if ( isNull( dataInput ) )
+        {
+            return null;
+        }
+
+        return (V) dataInput.readUTF();
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/BeanUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/BeanUtil.java
new file mode 100644
index 0000000..7846545
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/BeanUtil.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.exceptions.SerializerDefinitionException;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.PropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.objectweb.asm.Type;
+
+public final class BeanUtil
+{
+
+    private BeanUtil()
+    {
+    }
+
+    public static Set<Field> findPropertiesByClass( Class<?> type, Class<? extends Annotation> attributeAnnotation )
+    {
+        Set<Field> properties = new HashSet<Field>();
+        properties.addAll( findPropertiesByInstanceFields( type, attributeAnnotation ) );
+        properties.addAll( findPropertiesByMethods( type, type, attributeAnnotation ) );
+        properties.addAll( findPropertiesByInterfaces( type, attributeAnnotation ) );
+
+        if ( type.getSuperclass() != null && type.getSuperclass() != Object.class )
+        {
+            properties.addAll( findPropertiesByClass( type.getSuperclass(), attributeAnnotation ) );
+        }
+
+        return properties;
+    }
+
+    public static Set<Field> findPropertiesByInstanceFields( Class<?> type,
+                                                             Class<? extends Annotation> attributeAnnotation )
+    {
+        Set<Field> attributes = new HashSet<Field>();
+        for ( Field field : type.getDeclaredFields() )
+        {
+            if ( field.isAnnotationPresent( attributeAnnotation ) )
+            {
+                attributes.add( field );
+            }
+        }
+
+        return attributes;
+    }
+
+    public static Set<Field> findPropertiesByMethods( Class<?> type, Class<?> searchType,
+                                                      Class<? extends Annotation> attributeAnnotation )
+    {
+        Set<Field> attributes = new HashSet<Field>();
+        for ( Method method : searchType.getDeclaredMethods() )
+        {
+            if ( method.isAnnotationPresent( attributeAnnotation ) )
+            {
+                String propertyName = BeanUtil.buildPropertyName( method );
+                Field field = BeanUtil.getFieldByPropertyName( propertyName, type );
+                if ( field == null )
+                {
+                    if ( attributeAnnotation == Attribute.class )
+                    {
+                        Attribute attribute = method.getAnnotation( Attribute.class );
+                        field = BeanUtil.getFieldByPropertyName( attribute.property(), type );
+                    }
+
+                    if ( field == null )
+                    {
+                        throw new SerializerDefinitionException( "No property for method " + method + " was found" );
+                    }
+                }
+
+                attributes.add( field );
+            }
+        }
+
+        return attributes;
+    }
+
+    public static Set<Field> findPropertiesByInterfaces( Class<?> type, Class<? extends Annotation> attributeAnnotation )
+    {
+        Set<Field> attributes = new HashSet<Field>();
+
+        for ( Class<?> interfaze : type.getInterfaces() )
+        {
+            // Add all annotated methods in interface
+            attributes.addAll( findInterfaceProperties0( type, interfaze, attributeAnnotation ) );
+        }
+
+        return attributes;
+    }
+
+    private static Set<Field> findInterfaceProperties0( Class<?> type, Class<?> interfaze,
+                                                        Class<? extends Annotation> attributeAnnotation )
+    {
+        Set<Field> attributes = new HashSet<Field>();
+
+        // Add all annotated methods in interface
+        attributes.addAll( findPropertiesByMethods( type, interfaze, attributeAnnotation ) );
+
+        // Look up super-interface
+        if ( interfaze.getSuperclass() != null )
+        {
+            attributes.addAll( findInterfaceProperties0( type, interfaze.getSuperclass(), attributeAnnotation ) );
+        }
+
+        return attributes;
+    }
+
+    public static Field getFieldByPropertyName( String propertyName, Class<?> type )
+    {
+        try
+        {
+            return type.getDeclaredField( propertyName );
+        }
+        catch ( NoSuchFieldException e )
+        {
+            if ( type.getSuperclass() != null && type.getSuperclass() != Object.class )
+            {
+                return getFieldByPropertyName( propertyName, type.getSuperclass() );
+            }
+            return null;
+        }
+    }
+
+    public static Method findSetterMethod( Method method )
+    {
+        if ( method.getName().startsWith( "set" ) )
+        {
+            return method;
+        }
+
+        String propertyName = StringUtil.toUpperCamelCase( extractPropertyName( method.getName() ) );
+
+        Class<?> type = method.getReturnType();
+        Class<?> clazz = method.getDeclaringClass();
+        String setterName = "set" + propertyName;
+
+        try
+        {
+            return clazz.getDeclaredMethod( setterName, type );
+        }
+        catch ( Exception e )
+        {
+            // Seems there's no setter, so ignore all exceptions
+            return null;
+        }
+    }
+
+    public static Method findArraySetterMethod( Method method )
+    {
+        if ( method.getName().startsWith( "set" ) )
+        {
+            return method;
+        }
+
+        String propertyName = StringUtil.toUpperCamelCase( extractPropertyName( method.getName() ) );
+
+        Class<?> type = method.getReturnType();
+        Class<?> clazz = method.getDeclaringClass();
+        String setterName = "set" + propertyName;
+
+        try
+        {
+            return clazz.getDeclaredMethod( setterName, type, int.class );
+        }
+        catch ( Exception e )
+        {
+            // Seems there's no setter, so ignore all exceptions
+            return null;
+        }
+    }
+
+    public static Method findGetterMethod( Method method )
+    {
+        if ( method.getName().startsWith( "get" ) || method.getName().startsWith( "is" ) )
+        {
+            return method;
+        }
+
+        String propertyName = StringUtil.toUpperCamelCase( extractPropertyName( method.getName() ) );
+
+        Class<?> type = method.getParameterTypes()[0];
+        Class<?> clazz = method.getDeclaringClass();
+        String getterObjectName = "get" + propertyName;
+        String getterBooleanName = "is" + propertyName;
+
+        try
+        {
+            return clazz.getDeclaredMethod( getterObjectName, type );
+        }
+        catch ( Exception e )
+        {
+            if ( type == boolean.class )
+            {
+                try
+                {
+                    return clazz.getDeclaredMethod( getterBooleanName, type );
+                }
+                catch ( Exception ex )
+                {
+                    // Intentionally left blank - just fall through
+                }
+            }
+
+            // Seems there's no setter, so ignore all exceptions
+            return null;
+        }
+    }
+
+    public static Method findArrayGetterMethod( Method method )
+    {
+        if ( method.getName().startsWith( "get" ) || method.getName().startsWith( "is" ) )
+        {
+            return method;
+        }
+
+        String propertyName = StringUtil.toUpperCamelCase( extractPropertyName( method.getName() ) );
+
+        Class<?> type = method.getParameterTypes()[0];
+        Class<?> clazz = method.getDeclaringClass();
+        String getterObjectName = "get" + propertyName;
+        String getterBooleanName = "is" + propertyName;
+
+        try
+        {
+            return clazz.getDeclaredMethod( getterObjectName, type );
+        }
+        catch ( Exception e )
+        {
+            if ( type == boolean.class )
+            {
+                try
+                {
+                    return clazz.getDeclaredMethod( getterBooleanName, type, int.class );
+                }
+                catch ( Exception ex )
+                {
+                    // Intentionally left blank - just fall through
+                }
+            }
+
+            // Seems there's no setter, so ignore all exceptions
+            return null;
+        }
+    }
+
+    public static String buildPropertyName( Method method )
+    {
+        return buildPropertyName( method.getName() );
+    }
+
+    public static String buildPropertyName( String methodName )
+    {
+        return StringUtil.toLowerCamelCase( extractPropertyName( methodName ) );
+    }
+
+    public static String buildInternalSignature( Iterable<PropertyDescriptor> propertyDescriptors )
+    {
+        StringBuilder internalSignature = new StringBuilder();
+        for ( PropertyDescriptor propertyDescriptor : propertyDescriptors )
+        {
+            internalSignature.append( propertyDescriptor.getInternalSignature() );
+        }
+        return internalSignature.toString();
+    }
+
+    public static <T> String buildInternalSignature( String propertyName, PropertyAccessor propertyAccessor )
+    {
+        String type = Type.getDescriptor( propertyAccessor.getType() );
+        return new StringBuilder( "{" ).append( propertyName ).append( "}" ).append( type ).toString();
+    }
+
+    private static String extractPropertyName( String methodName )
+    {
+        if ( methodName.toUpperCase().startsWith( "GET" ) || methodName.toUpperCase().startsWith( "IS" )
+            || methodName.toUpperCase().startsWith( "SET" ) )
+        {
+
+            char[] characters = methodName.toCharArray();
+            for ( int i = 1; i < characters.length; i++ )
+            {
+                if ( Character.isUpperCase( characters[i] ) )
+                {
+                    return StringUtil.toLowerCamelCase( methodName.substring( i ) );
+                }
+            }
+        }
+        return StringUtil.toLowerCamelCase( methodName );
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/ClassUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/ClassUtil.java
new file mode 100644
index 0000000..268460c
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/ClassUtil.java
@@ -0,0 +1,509 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public final class ClassUtil
+{
+
+    public static final ClassDefinition[] CLASS_DESCRIPTORS = new ClassDefinition[] {
+        new JavaBuildInTypeClassDefinition( boolean.class, 1 ), new JavaBuildInTypeClassDefinition( Boolean.class, 2 ),
+        new JavaBuildInTypeClassDefinition( byte.class, 3 ), new JavaBuildInTypeClassDefinition( Byte.class, 4 ),
+        new JavaBuildInTypeClassDefinition( char.class, 5 ), new JavaBuildInTypeClassDefinition( Character.class, 6 ),
+        new JavaBuildInTypeClassDefinition( double.class, 7 ), new JavaBuildInTypeClassDefinition( Double.class, 8 ),
+        new JavaBuildInTypeClassDefinition( float.class, 9 ), new JavaBuildInTypeClassDefinition( Float.class, 10 ),
+        new JavaBuildInTypeClassDefinition( int.class, 11 ), new JavaBuildInTypeClassDefinition( Integer.class, 12 ),
+        new JavaBuildInTypeClassDefinition( long.class, 13 ), new JavaBuildInTypeClassDefinition( Long.class, 14 ),
+        new JavaBuildInTypeClassDefinition( short.class, 15 ), new JavaBuildInTypeClassDefinition( Short.class, 16 ),
+        new JavaBuildInTypeClassDefinition( String.class, 17 ), new JavaBuildInTypeClassDefinition( List.class, 18 ),
+        new JavaBuildInTypeClassDefinition( Set.class, 19 ), new JavaBuildInTypeClassDefinition( Map.class, 20 ),
+        new JavaBuildInTypeClassDefinition( BigInteger.class, 21 ),
+        new JavaBuildInTypeClassDefinition( BigDecimal.class, 22 ) };
+
+    private static final Map<Class<?>, Long> SERIAL_VERSION_UID_CACHE = new ConcurrentHashMap<Class<?>, Long>();
+
+    private ClassUtil()
+    {
+    }
+
+    public static boolean isReferenceCapable( Class<?> type )
+    {
+        return !type.isPrimitive() && Boolean.class != type && Byte.class != type && Short.class != type
+            && Integer.class != type && Long.class != type && Float.class != type && Double.class != type;
+    }
+
+    public static Class<?> loadClass( String canonicalName )
+        throws ClassNotFoundException
+    {
+        return loadClass( canonicalName, ClassUtil.class.getClassLoader() );
+    }
+
+    public static Class<?> loadClass( String canonicalName, ClassLoader classLoader )
+        throws ClassNotFoundException
+    {
+        Class<?> type = null;
+        try
+        {
+            type = classLoader.loadClass( canonicalName );
+        }
+        catch ( ClassNotFoundException e )
+        {
+            // Intentionally left blank
+        }
+
+        if ( type == null )
+        {
+            try
+            {
+                type = Class.forName( canonicalName );
+            }
+            catch ( ClassNotFoundException e )
+            {
+                // Intentionally left blank
+            }
+        }
+
+        if ( type == null )
+        {
+            try
+            {
+                ClassLoader tcl = Thread.currentThread().getContextClassLoader();
+                type = tcl.loadClass( canonicalName );
+            }
+            catch ( ClassNotFoundException e )
+            {
+                // Intentionally left blank
+            }
+        }
+
+        if ( type == null )
+        {
+            try
+            {
+                ClassLoader ccl = ClassUtil.class.getClassLoader();
+                type = ccl.loadClass( canonicalName );
+            }
+            catch ( ClassNotFoundException e )
+            {
+                // Intentionally left blank
+            }
+        }
+
+        if ( type != null )
+        {
+            return type;
+        }
+
+        throw new ClassNotFoundException( "Class " + canonicalName + " not found on classpath" );
+    }
+
+    public static long calculateSerialVersionUID( Class<?> clazz )
+    {
+        Long serialVersionUID = SERIAL_VERSION_UID_CACHE.get( clazz );
+        if ( serialVersionUID != null )
+        {
+            return serialVersionUID;
+        }
+
+        if ( Serializable.class.isAssignableFrom( clazz ) )
+        {
+            serialVersionUID = ObjectStreamClass.lookup( clazz ).getSerialVersionUID();
+            SERIAL_VERSION_UID_CACHE.put( clazz, serialVersionUID );
+            return serialVersionUID;
+        }
+
+        serialVersionUID = getSerialVersionUIDFromField( clazz );
+        if ( serialVersionUID != null )
+        {
+            SERIAL_VERSION_UID_CACHE.put( clazz, serialVersionUID );
+            return serialVersionUID;
+        }
+
+        try
+        {
+            ClassReader reader = new ClassReader( Type.getInternalName( clazz ).replace( "/", "." ) );
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            DataOutputStream out = new DataOutputStream( baos );
+
+            SerialVersionClassVisitor classVisitor = new SerialVersionClassVisitor();
+            reader.accept( classVisitor, 0 );
+
+            // Classname
+            out.writeUTF( toJavaName( classVisitor.name ) );
+
+            // Modifiers
+            out.writeInt( clazz.getModifiers()
+                & ( Modifier.PUBLIC | Modifier.FINAL | Modifier.INTERFACE | Modifier.ABSTRACT ) );
+
+            // Interfaces
+            Collections.sort( classVisitor.interfaces );
+            for ( int i = 0; i < classVisitor.interfaces.size(); i++ )
+            {
+                out.writeUTF( toJavaName( classVisitor.interfaces.get( i ) ) );
+            }
+
+            // Fields
+            Field[] fields = clazz.getDeclaredFields();
+            Arrays.sort( fields, new Comparator<Field>()
+            {
+
+                @Override
+                public int compare( Field o1, Field o2 )
+                {
+                    return o1.getName().compareTo( o2.getName() );
+                }
+            } );
+
+            for ( Field field : fields )
+            {
+                int mods = field.getModifiers();
+                if ( ( ( mods & Modifier.PRIVATE ) == 0 || ( mods & ( Modifier.STATIC | Modifier.TRANSIENT ) ) == 0 ) )
+                {
+                    out.writeUTF( field.getName() );
+                    out.writeInt( mods );
+                    out.writeUTF( Type.getDescriptor( field.getType() ) );
+                }
+            }
+
+            // Static Initializer
+            if ( classVisitor.staticInitializerFound )
+            {
+                out.writeUTF( "<clinit>" );
+                out.writeInt( Modifier.STATIC );
+                out.writeUTF( "()V" );
+            }
+
+            // Constructors
+            Constructor<?>[] constructors = clazz.getDeclaredConstructors();
+            Arrays.sort( constructors, new Comparator<Constructor<?>>()
+            {
+
+                @Override
+                public int compare( Constructor<?> o1, Constructor<?> o2 )
+                {
+                    return Type.getConstructorDescriptor( o1 ).compareTo( Type.getConstructorDescriptor( o2 ) );
+                }
+            } );
+
+            for ( int i = 0; i < constructors.length; i++ )
+            {
+                Constructor<?> constructor = constructors[i];
+                int mods = constructor.getModifiers();
+                if ( ( mods & Modifier.PRIVATE ) == 0 )
+                {
+                    out.writeUTF( "<init>" );
+                    out.writeInt( mods );
+                    out.writeUTF( toJavaName( Type.getConstructorDescriptor( constructor ) ) );
+                }
+            }
+
+            // Methods
+            Method[] methods = clazz.getDeclaredMethods();
+            Arrays.sort( methods, new Comparator<Method>()
+            {
+
+                @Override
+                public int compare( Method o1, Method o2 )
+                {
+                    return Type.getMethodDescriptor( o1 ).compareTo( Type.getMethodDescriptor( o2 ) );
+                }
+            } );
+
+            for ( int i = 0; i < methods.length; i++ )
+            {
+                Method method = methods[i];
+                int mods = method.getModifiers();
+                if ( ( mods & Modifier.PRIVATE ) == 0 )
+                {
+                    out.writeUTF( "<init>" );
+                    out.writeInt( mods );
+                    out.writeUTF( toJavaName( Type.getMethodDescriptor( method ) ) );
+                }
+            }
+
+            // Final calculation
+            out.flush();
+            MessageDigest digest = MessageDigest.getInstance( "SHA" );
+            byte[] checksum = digest.digest( baos.toByteArray() );
+
+            long hash = 0;
+            for ( int i = Math.min( checksum.length, 8 ) - 1; i >= 0; i-- )
+            {
+                hash = ( hash << 8 ) | ( checksum[i] & 0xFF );
+            }
+
+            SERIAL_VERSION_UID_CACHE.put( clazz, hash );
+            return hash;
+        }
+        catch ( IOException e )
+        {
+        }
+        catch ( NoSuchAlgorithmException e )
+        {
+        }
+
+        return -1L;
+    }
+
+    public static byte[] getClassBytes( Class<?> clazz )
+    {
+        try
+        {
+            ClassLoader classLoader = clazz.getClassLoader();
+            if ( classLoader == null )
+            {
+                classLoader = Thread.currentThread().getContextClassLoader();
+            }
+
+            String internalName = Type.getInternalName( clazz );
+            InputStream stream = classLoader.getResourceAsStream( internalName + ".class" );
+            byte[] data = new byte[stream.available()];
+            stream.read( data );
+            stream.close();
+            return data;
+        }
+        catch ( IOException e )
+        {
+            throw new RuntimeException( "Class bytes could not be read", e );
+        }
+    }
+
+    private static String toJavaName( String classname )
+    {
+        return classname.replace( "/", "." );
+    }
+
+    private static Long getSerialVersionUIDFromField( Class<?> clazz )
+    {
+        try
+        {
+            Field f = clazz.getDeclaredField( "serialVersionUID" );
+            int mask = Modifier.STATIC | Modifier.FINAL;
+            if ( ( f.getModifiers() & mask ) == mask )
+            {
+                f.setAccessible( true );
+                return Long.valueOf( f.getLong( null ) );
+            }
+        }
+        catch ( Exception ex )
+        {
+        }
+        return null;
+    }
+
+    private static class JavaBuildInTypeClassDefinition
+        implements ClassDefinition
+    {
+
+        private final long id;
+
+        private final Class<?> type;
+
+        private final String canonicalName;
+
+        private final byte[] checksum = new byte[20];
+
+        private final long serialVersionUID = -1L;
+
+        JavaBuildInTypeClassDefinition( Class<?> type, long id )
+        {
+            this.id = id;
+            this.type = type;
+            this.canonicalName = type.getCanonicalName();
+        }
+
+        @Override
+        public String getCanonicalName()
+        {
+            return canonicalName;
+        }
+
+        @Override
+        public Class<?> getType()
+        {
+            return type;
+        }
+
+        @Override
+        public byte[] getChecksum()
+        {
+            return checksum;
+        }
+
+        @Override
+        public long getId()
+        {
+            return id;
+        }
+
+        @Override
+        public long getSerialVersionUID()
+        {
+            return serialVersionUID;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( canonicalName == null ) ? 0 : canonicalName.hashCode() );
+            result = prime * result + Arrays.hashCode( checksum );
+            result = prime * result + (int) ( id ^ ( id >>> 32 ) );
+            result = prime * result + (int) ( serialVersionUID ^ ( serialVersionUID >>> 32 ) );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            JavaBuildInTypeClassDefinition other = (JavaBuildInTypeClassDefinition) obj;
+            if ( canonicalName == null )
+            {
+                if ( other.canonicalName != null )
+                    return false;
+            }
+            else if ( !canonicalName.equals( other.canonicalName ) )
+                return false;
+            if ( !Arrays.equals( checksum, other.checksum ) )
+                return false;
+            if ( id != other.id )
+                return false;
+            if ( serialVersionUID != other.serialVersionUID )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "JavaBuildInTypeClassDefinition [id=" + id + ", type=" + type + ", canonicalName=" + canonicalName
+                + ", checksum=" + Arrays.toString( checksum ) + ", serialVersionUID=" + serialVersionUID + "]";
+        }
+    }
+
+    private static class SerialVersionClassVisitor
+        extends ClassVisitor
+    {
+
+        public SerialVersionClassVisitor()
+        {
+            super( Opcodes.ASM4 );
+        }
+
+        private List<String> interfaces = new ArrayList<String>();
+
+        private boolean staticInitializerFound = false;
+
+        private String name;
+
+        @Override
+        public void visit( int version, int access, String name, String signature, String superName, String[] interfaces )
+        {
+            this.name = name;
+            this.interfaces = Arrays.asList( interfaces );
+        }
+
+        @Override
+        public AnnotationVisitor visitAnnotation( String desc, boolean visible )
+        {
+            return null;
+        }
+
+        @Override
+        public void visitAttribute( Attribute attr )
+        {
+        }
+
+        @Override
+        public void visitEnd()
+        {
+        }
+
+        @Override
+        public FieldVisitor visitField( int access, String name, String desc, String signature, Object value )
+        {
+            return null;
+        }
+
+        @Override
+        public void visitInnerClass( String name, String outerName, String innerName, int access )
+        {
+        }
+
+        @Override
+        public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions )
+        {
+            if ( "<clinit>".equals( name ) && ( access & Opcodes.ACC_STATIC ) != 0 )
+            {
+                staticInitializerFound = true;
+            }
+            return null;
+        }
+
+        @Override
+        public void visitOuterClass( String owner, String name, String desc )
+        {
+        }
+
+        @Override
+        public void visitSource( String source, String debug )
+        {
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/Crc64Util.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/Crc64Util.java
new file mode 100644
index 0000000..e836764
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/Crc64Util.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+/**
+ * Crc64 checksum computation. This classes basic content was copied from original position:
+ * http://intact.googlecode.com/ It was changed to use byte data instead of strings
+ * 
+ * @author The European Bioinformatics Institute, and others.
+ * @author Uniparc
+ * @version $Id$
+ */
+public final class Crc64Util
+{
+
+    private static long _crc64Array[] = new long[256];
+
+    /**
+     * Initialization of _crc64Array.
+     */
+    static
+    {
+
+        for ( int i = 0; i <= 255; ++i )
+        {
+            long k = i;
+            for ( int j = 0; j < 8; ++j )
+            {
+                if ( ( k & 1 ) != 0 )
+                {
+                    k = ( k >>> 1 ) ^ 0xd800000000000000l;
+                }
+                else
+                {
+                    k = k >>> 1;
+                }
+            }
+            _crc64Array[i] = k;
+        }
+    }
+
+    private Crc64Util()
+    {
+    }
+
+    /**
+     * Returns a hex string representation of the checksum
+     * 
+     * @param checksum
+     * @return
+     */
+    public static String toString( long checksum )
+    {
+        String crc64String = Long.toHexString( checksum ).toUpperCase();
+        StringBuffer crc64 = new StringBuffer( "0000000000000000" );
+        crc64.replace( crc64.length() - crc64String.length(), crc64.length(), crc64String );
+
+        return crc64.toString();
+    }
+
+    /**
+     * Calculated the checksum of the given data array as a long value.
+     * 
+     * @param data the data to checksum
+     * @return the calculated checksum
+     */
+    public static long checksum( byte[] data )
+    {
+        long crc64Number = 0;
+        for ( int i = 0; i < data.length; ++i )
+        {
+            int symbol = data[i];
+            long a = ( crc64Number >>> 8 );
+            long b = ( crc64Number ^ symbol ) & 0xff;
+            crc64Number = a ^ _crc64Array[(int) b];
+        }
+
+        return crc64Number;
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/InternalUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/InternalUtil.java
new file mode 100644
index 0000000..10cf017
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/InternalUtil.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.lang.reflect.Constructor;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiator;
+import org.apache.directmemory.lightning.internal.beans.PropertyAccessorFactory;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public final class InternalUtil
+{
+
+    public static final Charset CHARSET = Charset.forName( "UTF-8" );
+
+    public static final boolean UNSAFE_AVAILABLE;
+
+    static
+    {
+        boolean unsafeAvailable = false;
+        try
+        {
+            Class.forName( "sun.misc.Unsafe" );
+            unsafeAvailable = true;
+        }
+        catch ( Exception e )
+        {
+            // Intentionally left blank
+        }
+
+        UNSAFE_AVAILABLE = unsafeAvailable;
+    }
+
+    private InternalUtil()
+    {
+    }
+
+    public static byte[] getChecksum( byte[] data, Logger logger )
+    {
+        try
+        {
+            MessageDigest digest = MessageDigest.getInstance( "SHA-1" );
+            digest.update( data, 0, data.length );
+            return digest.digest();
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Could not build checksum of data" );
+        }
+    }
+
+    public static byte[] getChecksum( Collection<PropertyDescriptor> propertyDescriptors, Logger logger )
+    {
+        final StringBuilder builder = new StringBuilder();
+
+        // Clone and sort list of PropertyDescriptors
+        List<PropertyDescriptor> temp = new ArrayList<PropertyDescriptor>( propertyDescriptors );
+        Collections.sort( temp );
+
+        for ( PropertyDescriptor propertyDescriptor : temp )
+        {
+            logger.trace( "Adding property " + propertyDescriptor.getName() + " to checksum" );
+            builder.append( propertyDescriptor.getInternalSignature() );
+        }
+
+        return getChecksum( builder.toString().getBytes( CHARSET ), logger );
+    }
+
+    public static boolean isUnsafeAvailable()
+    {
+        return UNSAFE_AVAILABLE;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public static ObjectInstantiator buildSunUnsafeInstantiator( Class<?> type )
+    {
+        try
+        {
+            Class<? extends ObjectInstantiator> clazz =
+                (Class<? extends ObjectInstantiator>) ClassUtil.loadClass( "org.apache.directmemory.lightning.internal.instantiator.sun.SunUnsafeAllocateInstanceInstantiator" );
+
+            Constructor<? extends ObjectInstantiator> constructor = clazz.getDeclaredConstructor( Class.class );
+            return constructor.newInstance( type );
+        }
+        catch ( Exception e )
+        {
+            return null;
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public static PropertyAccessorFactory buildSunUnsafePropertyAccessor()
+    {
+        try
+        {
+            Class<? extends PropertyAccessorFactory> clazz =
+                (Class<? extends PropertyAccessorFactory>) ClassUtil.loadClass( "org.apache.directmemory.lightning.internal.beans.SunUnsafePropertyAccessorFactory" );
+
+            Constructor<? extends PropertyAccessorFactory> constructor = clazz.getDeclaredConstructor();
+            constructor.setAccessible( true );
+            return constructor.newInstance();
+        }
+        catch ( Exception e )
+        {
+            return null;
+        }
+    }
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/StringUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/StringUtil.java
new file mode 100644
index 0000000..142862a
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/StringUtil.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+public final class StringUtil
+{
+
+    private StringUtil()
+    {
+    }
+
+    public static String toLowerCamelCase( String value )
+    {
+        if ( value == null )
+            return null;
+
+        if ( value.length() == 0 )
+            return value;
+
+        return toCamelCase( value );
+    }
+
+    public static String toUpperCamelCase( String value )
+    {
+        String lowerCamelCase = toLowerCamelCase( value );
+        return String.valueOf( Character.toUpperCase( lowerCamelCase.toCharArray()[0] ) )
+            + lowerCamelCase.substring( 1 );
+    }
+
+    private static String toCamelCase( String value )
+    {
+        StringBuilder camelCase = new StringBuilder();
+        char[] characters = value.toCharArray();
+
+        for ( int i = 0; i < characters.length; i++ )
+        {
+            i = ignoreWhitespace( characters, i );
+            if ( i == -1 )
+                break;
+
+            if ( camelCase.length() == 0 )
+                camelCase.append( Character.toLowerCase( characters[i] ) );
+            else
+                camelCase.append( Character.toUpperCase( characters[i] ) );
+
+            int nextWhitespace = nextWhitespace( characters, i );
+            if ( nextWhitespace == -1 )
+                nextWhitespace = characters.length;
+
+            camelCase.append( value.substring( i + 1, nextWhitespace ) );
+            i = nextWhitespace;
+        }
+
+        return camelCase.toString();
+    }
+
+    private static int ignoreWhitespace( char[] characters, int offset )
+    {
+        for ( int i = offset; i < characters.length; i++ )
+        {
+            char c = characters[i];
+            if ( !Character.isWhitespace( c ) && '-' != c && '_' != c )
+                return i;
+        }
+        return -1;
+    }
+
+    private static int nextWhitespace( char[] characters, int offset )
+    {
+        for ( int i = offset + 1; i < characters.length; i++ )
+        {
+            char c = characters[i];
+            if ( Character.isWhitespace( c ) || '-' == c || '_' == c )
+                return i;
+        }
+        return -1;
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/TypeUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/TypeUtil.java
new file mode 100644
index 0000000..2d9434d
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/TypeUtil.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+public final class TypeUtil
+{
+
+    private TypeUtil()
+    {
+    }
+
+    public static Class<?> getBaseType( Type type )
+    {
+        if ( type instanceof Class )
+        {
+            return (Class<?>) type;
+        }
+
+        if ( type instanceof ParameterizedType )
+        {
+            return (Class<?>) ( (ParameterizedType) type ).getRawType();
+        }
+
+        throw new IllegalStateException( "The requested type is an generic array or wildcard which is not supported" );
+    }
+
+    public static Type[] getTypeArgument( Type type )
+    {
+        if ( type instanceof Class )
+        {
+            return null;
+        }
+
+        if ( type instanceof ParameterizedType )
+        {
+            return ( (ParameterizedType) type ).getActualTypeArguments();
+        }
+
+        throw new IllegalStateException( "The requested type is an generic array or wildcard which is not supported" );
+    }
+
+}
diff --git a/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/UnsafeUtil.java b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/UnsafeUtil.java
new file mode 100644
index 0000000..53fc238
--- /dev/null
+++ b/lightning-core/src/main/java/org/apache/directmemory/lightning/internal/util/UnsafeUtil.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.lang.reflect.Field;
+
+@SuppressWarnings( "restriction" )
+public final class UnsafeUtil
+{
+
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static
+    {
+        sun.misc.Unsafe unsafe;
+        try
+        {
+            Field unsafeField = sun.misc.Unsafe.class.getDeclaredField( "theUnsafe" );
+            unsafeField.setAccessible( true );
+            unsafe = (sun.misc.Unsafe) unsafeField.get( null );
+        }
+        catch ( Exception e )
+        {
+            unsafe = null;
+        }
+
+        UNSAFE = unsafe;
+    }
+
+    private UnsafeUtil()
+    {
+    }
+
+    public static sun.misc.Unsafe getUnsafe()
+    {
+        return UNSAFE;
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java
new file mode 100644
index 0000000..cc8a0cf
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/Benchmark.java
@@ -0,0 +1,526 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.junit.Ignore;
+import org.junit.Test;
+
+@Ignore
+public class Benchmark
+{
+
+    private static final int WARMUP_ROUNDS = 100000;
+
+    private static final int BENCHMARK_ROUNDS = 800000;
+
+    @Test
+    public void benchmarkLightningSerialization()
+        throws Exception
+    {
+        long buildStartTime = System.nanoTime();
+        Serializer serializer =
+            Lightning.newBuilder().debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new BenchmarkSerializerDefinition() ).build();
+        long nanos = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - buildStartTime );
+        System.out.println( "Lightning Serializer build time: " + nanos + " ms" );
+
+        long size = 0;
+        for ( int i = 0; i < WARMUP_ROUNDS; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+            Foo foo = buildRandomFoo();
+            out.writeObject( foo );
+
+            assertNotNull( baos );
+            assertNotNull( out );
+            assertNotNull( baos.toByteArray() );
+            size = baos.toByteArray().length;
+        }
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        long time = 0;
+        for ( int i = 0; i < BENCHMARK_ROUNDS; i++ )
+        {
+            Foo foo = buildRandomFoo();
+
+            long startTime = System.nanoTime();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+            out.writeObject( foo );
+
+            time += System.nanoTime() - startTime;
+            assertNotNull( baos.toByteArray() );
+        }
+
+        double avg = time / (double) BENCHMARK_ROUNDS;
+        System.out.println( "Lightning Serialization Avg: " + String.format( "%5.2f", avg ) + " ns, runs: "
+            + BENCHMARK_ROUNDS + ", size: " + size + " bytes" );
+
+        System.runFinalization();
+        System.gc();
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+    }
+
+    @Test
+    public void benchmarkLightningDeserialization()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().serializerDefinitions( new BenchmarkSerializerDefinition() ).build();
+
+        long size = 0;
+        for ( int i = 0; i < WARMUP_ROUNDS; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+            Foo foo = buildRandomFoo();
+            out.writeObject( foo );
+
+            assertNotNull( baos );
+            assertNotNull( out );
+            assertNotNull( baos.toByteArray() );
+            size = baos.toByteArray().length;
+
+            ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+            SerializerInputStream in = new SerializerInputStream( bais, serializer );
+            Object value = in.readObject();
+            assertNotNull( value );
+            assertEquals( foo, value );
+        }
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        long time = 0;
+        for ( int i = 0; i < BENCHMARK_ROUNDS; i++ )
+        {
+            Foo foo = buildRandomFoo();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+            out.writeObject( foo );
+
+            long startTime = System.nanoTime();
+            ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+            SerializerInputStream in = new SerializerInputStream( bais, serializer );
+            Object value = in.readObject();
+            time += System.nanoTime() - startTime;
+            assertNotNull( value );
+            assertEquals( foo, value );
+        }
+
+        double avg = time / (double) BENCHMARK_ROUNDS;
+        System.out.println( "Lightning Deserialization Avg: " + String.format( "%5.2f", avg ) + " ns, runs: "
+            + BENCHMARK_ROUNDS + ", size: " + size + " bytes" );
+
+        System.runFinalization();
+        System.gc();
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+    }
+
+    @Test
+    public void benchmarkJavaSerialization()
+        throws Exception
+    {
+        long size = 0;
+        for ( int i = 0; i < WARMUP_ROUNDS; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+            Foo foo = buildRandomFoo();
+            out.writeObject( foo );
+
+            assertNotNull( baos );
+            assertNotNull( out );
+            assertNotNull( baos.toByteArray() );
+            size = baos.toByteArray().length;
+        }
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        long time = 0;
+        for ( int i = 0; i < BENCHMARK_ROUNDS; i++ )
+        {
+            Foo foo = buildRandomFoo();
+
+            long startTime = System.nanoTime();
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+            out.writeObject( foo );
+
+            time += System.nanoTime() - startTime;
+            assertNotNull( baos.toByteArray() );
+        }
+
+        double avg = time / (double) BENCHMARK_ROUNDS;
+        System.out.println( "Java Serialization Avg: " + String.format( "%5.2f", avg ) + " ns, runs: "
+            + BENCHMARK_ROUNDS + ", size: " + size + " bytes" );
+
+        System.runFinalization();
+        System.gc();
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+    }
+
+    @Test
+    public void benchmarkJavaDeserialization()
+        throws Exception
+    {
+        long size = 0;
+        for ( int i = 0; i < WARMUP_ROUNDS; i++ )
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+            Foo foo = buildRandomFoo();
+            out.writeObject( foo );
+
+            assertNotNull( baos );
+            assertNotNull( out );
+            assertNotNull( baos.toByteArray() );
+            size = baos.toByteArray().length;
+
+            ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+            ObjectInputStream in = new ObjectInputStream( bais );
+            Object value = in.readObject();
+            assertNotNull( value );
+            assertEquals( foo, value );
+        }
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+
+        long time = 0;
+        for ( int i = 0; i < BENCHMARK_ROUNDS; i++ )
+        {
+            Foo foo = buildRandomFoo();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream( baos );
+            out.writeObject( foo );
+
+            long startTime = System.nanoTime();
+            ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+            ObjectInputStream in = new ObjectInputStream( bais );
+            Object value = in.readObject();
+
+            time += System.nanoTime() - startTime;
+            assertNotNull( value );
+            assertEquals( foo, value );
+        }
+
+        double avg = time / (double) BENCHMARK_ROUNDS;
+        System.out.println( "Java Deserialization Avg: " + String.format( "%5.2f", avg ) + " ns, runs: "
+            + BENCHMARK_ROUNDS + ", size: " + size + " bytes" );
+
+        System.runFinalization();
+        System.gc();
+
+        try
+        {
+            Thread.sleep( 5000 );
+        }
+        catch ( Exception e )
+        {
+        }
+    }
+
+    private static final Random RANDOM = new Random( System.nanoTime() );
+
+    private static final String[] STRING_VALUES = { "HGHO", "jldu", "oösd", "JKGH", "HGFG", "JLHL", "GJJK", "JKGH" };
+
+    private static Foo buildRandomFoo()
+    {
+        Foo foo = new Foo();
+        foo.enumValue = RANDOM.nextInt( 100 ) < 50 ? Bar.Value1 : Bar.Value2;
+        foo.someOther = RANDOM.nextInt();
+        foo.value = RANDOM.nextInt( 100 ) < 50 ? null : RANDOM.nextInt();
+        foo.first = STRING_VALUES[RANDOM.nextInt( STRING_VALUES.length )];
+        foo.second = STRING_VALUES[RANDOM.nextInt( STRING_VALUES.length )];
+
+        return foo;
+    }
+
+    public static class BenchmarkSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+        }
+    }
+
+    @SuppressWarnings( "serial" )
+    public static class Foo
+        implements Serializable
+    {
+
+        private String first;
+
+        private String second;
+
+        private Integer value;
+
+        private int someOther;
+
+        @Attribute
+        private Bar enumValue;
+
+        @Attribute
+        public String getFirst()
+        {
+            return first;
+        }
+
+        public void setFirst( String first )
+        {
+            this.first = first;
+        }
+
+        @Attribute
+        public String getSecond()
+        {
+            return second;
+        }
+
+        public void setSecond( String second )
+        {
+            this.second = second;
+        }
+
+        @Attribute
+        public Integer getValue()
+        {
+            return value;
+        }
+
+        public void setValue( Integer value )
+        {
+            this.value = value;
+        }
+
+        @Attribute
+        // Implicitly required
+        public int getSomeOther()
+        {
+            return someOther;
+        }
+
+        public void setSomeOther( int someOther )
+        {
+            this.someOther = someOther;
+        }
+
+        public Bar getEnumValue()
+        {
+            return enumValue;
+        }
+
+        public void setEnumValue( Bar enumValue )
+        {
+            this.enumValue = enumValue;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Foo [hash=@" + hashCode() + ", first=" + first + ", second=" + second + ", value=" + value
+                + ", someOther=" + someOther + ", enumValue=" + enumValue + "]";
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( enumValue == null ) ? 0 : enumValue.hashCode() );
+            result = prime * result + ( ( first == null ) ? 0 : first.hashCode() );
+            result = prime * result + ( ( second == null ) ? 0 : second.hashCode() );
+            result = prime * result + someOther;
+            result = prime * result + ( ( value == null ) ? 0 : value.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Foo other = (Foo) obj;
+            if ( enumValue != other.enumValue )
+                return false;
+            if ( first == null )
+            {
+                if ( other.first != null )
+                    return false;
+            }
+            else if ( !first.equals( other.first ) )
+                return false;
+            if ( second == null )
+            {
+                if ( other.second != null )
+                    return false;
+            }
+            else if ( !second.equals( other.second ) )
+                return false;
+            if ( someOther != other.someOther )
+                return false;
+            if ( value == null )
+            {
+                if ( other.value != null )
+                    return false;
+            }
+            else if ( !value.equals( other.value ) )
+                return false;
+            return true;
+        }
+    }
+
+    public static enum Bar
+    {
+        Value1, Value2
+    }
+
+    public static class BarMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Bar.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return null;
+        }
+    }
+
+    public static class SomeSpecialIntegerMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Integer.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return value;
+        }
+
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/ClassDefinitionContainerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/ClassDefinitionContainerTestCase.java
new file mode 100644
index 0000000..1ff51d3
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/ClassDefinitionContainerTestCase.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.directmemory.lightning.ClassComparisonStrategy;
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.exceptions.ClassDefinitionInconsistentException;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.junit.Test;
+
+public class ClassDefinitionContainerTestCase
+{
+
+    @Test
+    public void testLightningChecksum()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+    }
+
+    @Test( expected = ClassDefinitionInconsistentException.class )
+    public void testLightningChecksumFailing()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer = Lightning.newBuilder().logger( new DebugLogger() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+    }
+
+    @Test
+    public void testSerialVersionUID()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).classComparisonStrategy( ClassComparisonStrategy.SerialVersionUID ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+    }
+
+    @Test( expected = ClassDefinitionInconsistentException.class )
+    public void testSerialVersionUIDFailing()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).classComparisonStrategy( ClassComparisonStrategy.SerialVersionUID ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer = Lightning.newBuilder().logger( new DebugLogger() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+    }
+
+    @Test
+    public void testClassDefinitionContainerTransportLightningChecksum()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream( baos );
+
+        out.writeObject( container );
+        byte[] data = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( data );
+        ObjectInputStream in = new ObjectInputStream( bais );
+
+        ClassDefinitionContainer remoteContainer = (ClassDefinitionContainer) in.readObject();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( remoteContainer );
+    }
+
+    @Test
+    public void testClassDefinitionContainerTransportSerialVersionUID()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).classComparisonStrategy( ClassComparisonStrategy.SerialVersionUID ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream( baos );
+
+        out.writeObject( container );
+        byte[] data = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( data );
+        ObjectInputStream in = new ObjectInputStream( bais );
+
+        ClassDefinitionContainer remoteContainer = (ClassDefinitionContainer) in.readObject();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).classComparisonStrategy( ClassComparisonStrategy.SerialVersionUID ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( remoteContainer );
+    }
+
+    public static class SerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+            serialize( Bar.class ).attributes();
+        }
+    }
+
+    public static class Foo
+    {
+
+        @Attribute
+        private int id;
+
+        @Attribute
+        private String name;
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId( int id )
+        {
+            this.id = id;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName( String name )
+        {
+            this.name = name;
+        }
+    }
+
+    public static class Bar
+    {
+
+        @Attribute
+        private int id;
+
+        @Attribute
+        private String name;
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId( int id )
+        {
+            this.id = id;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName( String name )
+        {
+            this.name = name;
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/ComplexClassHierarchyTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/ComplexClassHierarchyTestCase.java
new file mode 100644
index 0000000..9943c40
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/ComplexClassHierarchyTestCase.java
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.junit.Test;
+
+public class ComplexClassHierarchyTestCase
+{
+
+    @Test
+    public void testSimpleObject()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        foo.setName( "SomeName" );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( foo );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( foo, value );
+    }
+
+    @Test
+    public void testSomeMoreComplexObjectWithOneDefinition()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        foo.setName( "SomeName" );
+
+        Complex complex = new Complex();
+        complex.setFoo( foo );
+        complex.setBar( Bar.SomeOtherValue );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( complex );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( complex, value );
+    }
+
+    @Test
+    public void testSomeMoreComplexObjectWithTwoDefinition()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new ParentSerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new ParentSerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        foo.setName( "SomeName" );
+
+        Complex complex = new Complex();
+        complex.setFoo( foo );
+        complex.setBar( Bar.SomeOtherValue );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( complex );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( complex, value );
+    }
+
+    public static class SerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+            serialize( Complex.class ).attributes();
+        }
+    }
+
+    public static class ParentSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+
+            install( new ChildSerializerDefinition() );
+        }
+    }
+
+    public static class ChildSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Complex.class ).attributes();
+        }
+    }
+
+    public static class Foo
+    {
+
+        @Attribute
+        private int id;
+
+        @Attribute
+        private String name;
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId( int id )
+        {
+            this.id = id;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName( String name )
+        {
+            this.name = name;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + id;
+            result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Foo other = (Foo) obj;
+            if ( id != other.id )
+                return false;
+            if ( name == null )
+            {
+                if ( other.name != null )
+                    return false;
+            }
+            else if ( !name.equals( other.name ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Foo [id=" + id + ", name=" + name + "]";
+        }
+    }
+
+    public static class Complex
+    {
+
+        @Attribute
+        private Foo foo;
+
+        @Attribute
+        private Bar bar;
+
+        public Foo getFoo()
+        {
+            return foo;
+        }
+
+        public void setFoo( Foo foo )
+        {
+            this.foo = foo;
+        }
+
+        public Bar getBar()
+        {
+            return bar;
+        }
+
+        public void setBar( Bar bar )
+        {
+            this.bar = bar;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( bar == null ) ? 0 : bar.hashCode() );
+            result = prime * result + ( ( foo == null ) ? 0 : foo.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Complex other = (Complex) obj;
+            if ( bar != other.bar )
+                return false;
+            if ( foo == null )
+            {
+                if ( other.foo != null )
+                    return false;
+            }
+            else if ( !foo.equals( other.foo ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Complex [foo=" + foo + ", bar=" + bar + "]";
+        }
+    }
+
+    public static enum Bar
+    {
+        SomeValue, SomeOtherValue, SomeTotallyDifferentValue
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/GenericTypedTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/GenericTypedTestCase.java
new file mode 100644
index 0000000..b5e0e8f
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/GenericTypedTestCase.java
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.logging.LogLevel;
+import org.apache.directmemory.lightning.logging.LoggerAdapter;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.junit.Test;
+
+public class GenericTypedTestCase
+{
+
+    @Test
+    public void testSimpleObject()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        // foo.setName("SomeName");
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( foo );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( foo, value );
+    }
+
+    @Test
+    public void testSomeMoreComplexObjectWithOneDefinition()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new SerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        // foo.setName("SomeName");
+
+        Complex complex = new Complex();
+        complex.setFoo( foo );
+        complex.setBar( Bar.SomeOtherValue );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( complex );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( complex, value );
+    }
+
+    @Test
+    public void testSomeMoreComplexObjectWithTwoDefinition()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new ParentSerializerDefinition() ).build();
+
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new ParentSerializerDefinition() ).build();
+
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.setId( 10000 );
+        // foo.setName("SomeName");
+
+        Complex complex = new Complex();
+        complex.setFoo( foo );
+        complex.setBar( Bar.SomeOtherValue );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( complex );
+
+        assertNotNull( baos );
+        assertNotNull( out );
+        assertNotNull( baos.toByteArray() );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        assertNotNull( value );
+        assertEquals( complex, value );
+    }
+
+    public static class SerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+            serialize( Complex.class ).attributes();
+        }
+    }
+
+    public static class ParentSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Foo.class ).attributes();
+
+            install( new ChildSerializerDefinition() );
+        }
+    }
+
+    public static class ChildSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            serialize( Complex.class ).attributes();
+        }
+    }
+
+    public static class Foo
+    {
+
+        @Attribute
+        private int id;
+
+        @Attribute
+        private List<String> names;
+
+        public int getId()
+        {
+            return id;
+        }
+
+        public void setId( int id )
+        {
+            this.id = id;
+        }
+
+        public List<String> getNames()
+        {
+            return names;
+        }
+
+        public void setNames( List<String> names )
+        {
+            this.names = names;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + id;
+            // result = prime * result + ((name == null) ? 0 : name.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Foo other = (Foo) obj;
+            if ( id != other.id )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Foo [id=" + id + ", names=" + names + "]";
+        }
+    }
+
+    public static class Complex
+    {
+
+        @Attribute
+        private Foo foo;
+
+        @Attribute
+        private Bar bar;
+
+        public Foo getFoo()
+        {
+            return foo;
+        }
+
+        public void setFoo( Foo foo )
+        {
+            this.foo = foo;
+        }
+
+        public Bar getBar()
+        {
+            return bar;
+        }
+
+        public void setBar( Bar bar )
+        {
+            this.bar = bar;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( bar == null ) ? 0 : bar.hashCode() );
+            result = prime * result + ( ( foo == null ) ? 0 : foo.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Complex other = (Complex) obj;
+            if ( bar != other.bar )
+                return false;
+            if ( foo == null )
+            {
+                if ( other.foo != null )
+                    return false;
+            }
+            else if ( !foo.equals( other.foo ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Complex [foo=" + foo + ", bar=" + bar + "]";
+        }
+    }
+
+    public static enum Bar
+    {
+        SomeValue, SomeOtherValue, SomeTotallyDifferentValue
+    }
+
+    public static class DebugLogger
+        extends LoggerAdapter
+    {
+
+        @Override
+        public boolean isLogLevelEnabled( LogLevel logLevel )
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isTraceEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isDebugEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isInfoEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isWarnEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isErrorEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public boolean isFatalEnabled()
+        {
+            return true;
+        }
+
+        @Override
+        public void trace( String message )
+        {
+            log( LogLevel.Trace, message, null );
+        }
+
+        @Override
+        public void trace( String message, Throwable throwable )
+        {
+            log( LogLevel.Trace, message, throwable );
+        }
+
+        @Override
+        public void debug( String message )
+        {
+            log( LogLevel.Debug, message, null );
+        }
+
+        @Override
+        public void debug( String message, Throwable throwable )
+        {
+            log( LogLevel.Debug, message, throwable );
+        }
+
+        @Override
+        public void info( String message )
+        {
+            log( LogLevel.Info, message, null );
+        }
+
+        @Override
+        public void info( String message, Throwable throwable )
+        {
+            log( LogLevel.Info, message, throwable );
+        }
+
+        @Override
+        public void warn( String message )
+        {
+            log( LogLevel.Warn, message, null );
+        }
+
+        @Override
+        public void warn( String message, Throwable throwable )
+        {
+            log( LogLevel.Warn, message, throwable );
+        }
+
+        @Override
+        public void error( String message )
+        {
+            log( LogLevel.Error, message, null );
+        }
+
+        @Override
+        public void error( String message, Throwable throwable )
+        {
+            log( LogLevel.Error, message, throwable );
+        }
+
+        @Override
+        public void fatal( String message )
+        {
+            log( LogLevel.Fatal, message, null );
+        }
+
+        @Override
+        public void fatal( String message, Throwable throwable )
+        {
+            log( LogLevel.Fatal, message, throwable );
+        }
+
+        private void log( LogLevel logLevel, String message, Throwable throwable )
+        {
+            PrintStream stream;
+            if ( throwable != null )
+            {
+                stream = System.err;
+            }
+            else
+            {
+                stream = System.out;
+            }
+
+            stream.println( getName() + " - " + logLevel.name() + ": " + message );
+            if ( throwable != null )
+            {
+                throwable.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/PropertyFinderTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/PropertyFinderTestCase.java
new file mode 100644
index 0000000..9bf3188
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/PropertyFinderTestCase.java
@@ -0,0 +1,626 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.junit.Test;
+
+public class PropertyFinderTestCase
+{
+
+    @Test
+    public void testCustomDefinedPropertyFind1()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Standard.class ).attributes( attribute( "value1" ) );
+                serialize( Standard.class ).attributes( attribute( "value2" ) );
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Standard.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 2, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Standard standard = new Standard();
+        standard.setValue1( "Foo" );
+        standard.setValue2( 321 );
+        out.writeObject( standard );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Standard result = (Standard) in.readObject();
+
+        assertEquals( standard, result );
+    }
+
+    @Test
+    public void testCustomDefinedPropertyFind2()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Standard.class ).attributes( attribute( "value1" ), attribute( "value2" ) );
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Standard.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 2, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Standard standard = new Standard();
+        standard.setValue1( "Foo" );
+        standard.setValue2( 321 );
+        out.writeObject( standard );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Standard result = (Standard) in.readObject();
+
+        assertEquals( standard, result );
+    }
+
+    @Test
+    public void testStandardPropertyFind()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Standard.class ).attributes();
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Standard.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 2, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Standard standard = new Standard();
+        standard.setValue1( "Foo" );
+        standard.setValue2( 321 );
+        out.writeObject( standard );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Standard result = (Standard) in.readObject();
+
+        assertEquals( standard, result );
+    }
+
+    @Test
+    public void testStandardPropertyFindUsingExclude()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Standard.class ).attributes().exclude( "value1" );
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Standard.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 1, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Standard standard = new Standard();
+        standard.setValue1( "Foo" );
+        standard.setValue2( 321 );
+        out.writeObject( standard );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Standard result = (Standard) in.readObject();
+
+        assertNull( "value1 must not be set", result.getValue1() );
+        assertEquals( standard.getValue2(), result.getValue2() );
+    }
+
+    @Test
+    public void testStandardPropertyFindUsingExcludes()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Inherted.class ).attributes().excludes( "value1", "value2" );
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Inherted.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 2, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Inherted inherted = new Inherted();
+        inherted.setValue1( "Foo" );
+        inherted.setValue2( 321 );
+        inherted.setValue3( "Bar" );
+        inherted.setValue4( 123L );
+        out.writeObject( inherted );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Inherted result = (Inherted) in.readObject();
+
+        assertNull( "value1 must not be set", result.getValue1() );
+        assertEquals( result.getValue2(), 0 );
+        assertEquals( inherted.getValue3(), result.getValue3() );
+        assertEquals( inherted.getValue4(), result.getValue4() );
+    }
+
+    @Test
+    public void testInheritancePropertyFind()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Inherted.class ).attributes();
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Inherted.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 4, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Inherted inherted = new Inherted();
+        inherted.setValue1( "Foo" );
+        inherted.setValue2( 321 );
+        inherted.setValue3( "Bar" );
+        inherted.setValue4( 123 );
+        out.writeObject( inherted );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Standard result = (Standard) in.readObject();
+
+        assertEquals( inherted, result );
+    }
+
+    @Test
+    public void testCompositionPropertyFind()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( Composed.class ).attributes();
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( Composed.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 3, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        Composed composed = new Composed( "Foo", 123, "Bar" );
+        out.writeObject( composed );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        Composed result = (Composed) in.readObject();
+
+        assertEquals( composed, result );
+    }
+
+    @Test
+    public void testComposedInheritancePropertyFind()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( ComposedInherted.class ).attributes();
+            }
+        } );
+
+        ClassDescriptorAwareSerializer awareSerializer = (ClassDescriptorAwareSerializer) serializer;
+        ClassDescriptor classDescriptor = awareSerializer.findClassDescriptor( ComposedInherted.class );
+
+        assertNotNull( classDescriptor );
+        assertEquals( 3, classDescriptor.getPropertyDescriptors().size() );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        ComposedInherted composedInherted = new ComposedInherted();
+        composedInherted.setValue1( "Foo" );
+        composedInherted.setValue2( 321 );
+        composedInherted.setValue3( "Bar" );
+        out.writeObject( composedInherted );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        ComposedInherted result = (ComposedInherted) in.readObject();
+
+        assertEquals( composedInherted, result );
+    }
+
+    public static class Standard
+    {
+
+        @Attribute
+        private String value1;
+
+        @Attribute
+        private int value2;
+
+        public String getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( String value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public int getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( int value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + value2;
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Standard other = (Standard) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Standard [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class Inherted
+        extends Standard
+    {
+
+        @Attribute
+        private String value3;
+
+        @Attribute
+        private long value4;
+
+        public String getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( String value3 )
+        {
+            this.value3 = value3;
+        }
+
+        public long getValue4()
+        {
+            return value4;
+        }
+
+        public void setValue4( long value4 )
+        {
+            this.value4 = value4;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = super.hashCode();
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            result = prime * result + (int) ( value4 ^ ( value4 >>> 32 ) );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( !super.equals( obj ) )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Inherted other = (Inherted) obj;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            if ( value4 != other.value4 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Inherted [value3=" + value3 + ", value4=" + value4 + "]";
+        }
+    }
+
+    public static class ComposedInherted
+        extends Standard
+        implements Foo, Bar
+    {
+
+        private String value3;
+
+        public void setValue3( String value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public String getValue3()
+        {
+            return value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = super.hashCode();
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( !super.equals( obj ) )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ComposedInherted other = (ComposedInherted) obj;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ComposedInherted [value3=" + value3 + "]";
+        }
+    }
+
+    public static interface Foo
+    {
+
+        @Attribute
+        String getValue1();
+
+        @Attribute
+        int getValue2();
+    }
+
+    public static interface Bar
+    {
+
+        @Attribute
+        String getValue3();
+    }
+
+    public static class Composed
+        implements Foo, Bar
+    {
+
+        private final String value1;
+
+        private final int value2;
+
+        private final String value3;
+
+        public Composed( String value1, int value2, String value3 )
+        {
+            this.value1 = value1;
+            this.value2 = value2;
+            this.value3 = value3;
+        }
+
+        @Override
+        public String getValue3()
+        {
+            return value3;
+        }
+
+        @Override
+        public String getValue1()
+        {
+            return value1;
+        }
+
+        @Override
+        public int getValue2()
+        {
+            return value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + value2;
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            Composed other = (Composed) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Composed [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/WhatShouldItLookLike.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/WhatShouldItLookLike.java
new file mode 100644
index 0000000..0707020
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/WhatShouldItLookLike.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.MarshallerContext;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractObjectMarshaller;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.configuration.TypeIntrospector;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class WhatShouldItLookLike
+{
+
+    public static void main( String[] args )
+    {
+        Serializer serializer2 =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new ExampleSerializerDefinition() ).build();
+
+        ClassDefinitionContainer container2 = serializer2.getClassDefinitionContainer();
+
+        Serializer remoteSerializer2 =
+            Lightning.newBuilder().logger( new DebugLogger() ).serializerDefinitions( new ExampleSerializerDefinition() ).build();
+
+        remoteSerializer2.setClassDefinitionContainer( container2 );
+
+        Serializer serializer = Lightning.createSerializer( new ExampleSerializerDefinition() );
+        ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+        Serializer remoteSerializer = Lightning.createSerializer( new ExampleSerializerDefinition() );
+        remoteSerializer.setClassDefinitionContainer( container );
+
+        Foo foo = new Foo();
+        foo.enumValue = Bar.Value2;
+        foo.first = "first";
+        foo.second = "second";
+        foo.someOther = 123;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+        out.writeObject( foo );
+        System.out.println( foo );
+
+        byte[] data = baos.toByteArray();
+        System.out.println( Arrays.toString( data ) );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( data );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+        Object value = in.readObject();
+        System.out.println( value );
+    }
+
+    public static class ExampleSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        protected void configure()
+        {
+            // Define serializable class using custom implementation of
+            // Marshaller
+            serialize( Bar.class ).using( new BarMarshaller() );
+            serialize( Bar.class ).using( BarMarshaller.class );
+
+            // Define serializable class using annotated members / methods (by
+            // usage of Lightning's @org.apache.directmemory.lightning.metadata.Attribute
+            // annotation)
+            serialize( Foo.class ).attributes();
+            serialize( Foo.class ).attributes().exclude( "value" );
+            serialize( Foo.class ).attributes().exclude( "value1" ).exclude( "value2" );
+            serialize( Foo.class ).attributes().excludes( "value1", "value2" );
+
+            // Define serializable class using annotated members / methods (by
+            // usage of custom annotation)
+            serialize( Foo.class ).attributes( Attribute.class );
+            serialize( Foo.class ).attributes( Attribute.class ).exclude( "value" );
+            serialize( Foo.class ).attributes( Attribute.class ).exclude( "value1" ).exclude( "value2" );
+            serialize( Foo.class ).attributes( Attribute.class ).excludes( "value1", "value2" );
+
+            // Define serializable class using custom definition of attributes
+            serialize( Foo.class ).attributes( attribute( "value" ),
+                                               attribute( "value" ).using( SomeSpecialIntegerMarshaller.class ),
+                                               attribute( "value" ).using( new SomeSpecialIntegerMarshaller() ) );
+
+            // Define serializable class using a different implementation of
+            // PropertyFinderStrategy
+            serialize( Foo.class ).using( new FooTypeIntrospector() );
+            serialize( Foo.class ).using( FooTypeIntrospector.class );
+
+            // Install child definition
+            install( new SomeChildSerializerDefinition() );
+        }
+    }
+
+    public static class SomeChildSerializerDefinition
+        extends AbstractSerializerDefinition
+    {
+
+        @Override
+        public void configure()
+        {
+            describesAttributes( Attribute.class );
+
+            serialize( Foo.class ).attributes();
+        }
+    }
+
+    public static class FooTypeIntrospector
+        implements TypeIntrospector
+    {
+
+        @Override
+        public List<PropertyDescriptor> introspect( Type type, MarshallerStrategy marshallerStrategy,
+                                                    MarshallerContext marshallerContext,
+                                                    PropertyDescriptorFactory propertyDescriptorFactory )
+        {
+            // TODO Auto-generated method stub
+            return null;
+        }
+    }
+
+    public static class Foo
+    {
+
+        private String first;
+
+        private String second;
+
+        private Integer value;
+
+        private int someOther;
+
+        @Attribute
+        private Bar enumValue;
+
+        @Attribute( required = true )
+        public String getFirst()
+        {
+            return first;
+        }
+
+        public void setFirst( String first )
+        {
+            this.first = first;
+        }
+
+        @Attribute
+        public String getSecond()
+        {
+            return second;
+        }
+
+        public void setSecond( String second )
+        {
+            this.second = second;
+        }
+
+        @Attribute
+        public Integer getValue()
+        {
+            return value;
+        }
+
+        public void setValue( Integer value )
+        {
+            this.value = value;
+        }
+
+        @Attribute
+        // Implicitly required
+        public int getSomeOther()
+        {
+            return someOther;
+        }
+
+        public void setSomeOther( int someOther )
+        {
+            this.someOther = someOther;
+        }
+
+        public Bar getEnumValue()
+        {
+            return enumValue;
+        }
+
+        public void setEnumValue( Bar enumValue )
+        {
+            this.enumValue = enumValue;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "Foo [hash=@" + hashCode() + ", first=" + first + ", second=" + second + ", value=" + value
+                + ", someOther=" + someOther + ", enumValue=" + enumValue + "]";
+        }
+    }
+
+    public static enum Bar
+    {
+        Value1, Value2
+    }
+
+    @Retention( RetentionPolicy.RUNTIME )
+    public static @interface Attribute
+    {
+
+        boolean required() default false;
+    }
+
+    public static class BarMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Bar.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return null;
+        }
+    }
+
+    public static class SomeSpecialIntegerMarshaller
+        extends AbstractObjectMarshaller
+    {
+
+        @Override
+        public boolean acceptType( Class<?> type )
+        {
+            return type == Integer.class;
+        }
+
+        @Override
+        public void marshall( Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput,
+                              SerializationContext serializationContext )
+            throws IOException
+        {
+        }
+
+        @Override
+        public <V> V unmarshall( V value, PropertyDescriptor propertyDescriptor, DataInput dataInput,
+                                 SerializationContext serializationContext )
+            throws IOException
+        {
+
+            return value;
+        }
+
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/ClassDefinitionContainerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/ClassDefinitionContainerTestCase.java
new file mode 100644
index 0000000..ccc8e89
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/ClassDefinitionContainerTestCase.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.internal.InternalClassDefinition;
+import org.apache.directmemory.lightning.internal.InternalClassDefinitionContainer;
+import org.apache.directmemory.lightning.logging.LoggerAdapter;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.junit.Test;
+import org.objectweb.asm.ClassVisitor;
+
+public class ClassDefinitionContainerTestCase
+{
+
+    private static final Class<?>[] CLASSES = { ClassVisitor.class };
+
+    @Test
+    public void testClassDefinitionContainer()
+        throws Exception
+    {
+        final Set<ClassDefinition> classDefinitions = new HashSet<ClassDefinition>();
+
+        for ( Class<?> clazz : CLASSES )
+        {
+            PropertyDescriptor label = null;
+            classDefinitions.add( new InternalClassDefinition( clazz, Collections.<PropertyDescriptor> emptyList(),
+                                                               new LoggerAdapter() ) );
+        }
+
+        ClassDefinitionContainer classDefinitionContainer = new InternalClassDefinitionContainer( classDefinitions );
+
+        for ( ClassDefinition classDefinition : classDefinitionContainer.getClassDefinitions() )
+        {
+            Class<?> clazz = null;
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorTestCase.java
new file mode 100644
index 0000000..85eb452
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/ReflectionPropertyAccessorTestCase.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+import org.apache.directmemory.lightning.internal.beans.ReflectionPropertyAccessorFactory;
+import org.apache.directmemory.lightning.metadata.ArrayPropertyAccessor;
+import org.junit.Test;
+
+public class ReflectionPropertyAccessorTestCase
+{
+
+    @Test
+    public void testUnsafeBooleanArray()
+        throws Exception
+    {
+        class BooleanArrayTest
+        {
+
+            private boolean[] array = new boolean[10];
+        }
+
+        Field field = BooleanArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, BooleanArrayTest.class );
+
+        BooleanArrayTest test = new BooleanArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i % 2 == 0 ? true : false;
+        }
+
+        BooleanArrayTest result = new BooleanArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            boolean value = propertyAccessor.readBoolean( test.array, i );
+            propertyAccessor.writeBoolean( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeByteArray()
+        throws Exception
+    {
+        class ByteArrayTest
+        {
+
+            private byte[] array = new byte[10];
+        }
+
+        Field field = ByteArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, ByteArrayTest.class );
+
+        ByteArrayTest test = new ByteArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (byte) ( i + 1 );
+        }
+
+        ByteArrayTest result = new ByteArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            byte value = propertyAccessor.readByte( test.array, i );
+            propertyAccessor.writeByte( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeShortArray()
+        throws Exception
+    {
+        class ShortArrayTest
+        {
+
+            private short[] array = new short[10];
+        }
+
+        Field field = ShortArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, ShortArrayTest.class );
+
+        ShortArrayTest test = new ShortArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (short) ( i + 1 );
+        }
+
+        ShortArrayTest result = new ShortArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            short value = propertyAccessor.readShort( test.array, i );
+            propertyAccessor.writeShort( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeIntArray()
+        throws Exception
+    {
+        class IntArrayTest
+        {
+
+            private int[] array = new int[10];
+        }
+
+        Field field = IntArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, IntArrayTest.class );
+
+        IntArrayTest test = new IntArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1;
+        }
+
+        IntArrayTest result = new IntArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            int value = propertyAccessor.readInt( test.array, i );
+            propertyAccessor.writeInt( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeLongArray()
+        throws Exception
+    {
+        class LongArrayTest
+        {
+
+            private long[] array = new long[10];
+        }
+
+        Field field = LongArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, LongArrayTest.class );
+
+        LongArrayTest test = new LongArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1;
+        }
+
+        LongArrayTest result = new LongArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            long value = propertyAccessor.readLong( test.array, i );
+            propertyAccessor.writeLong( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeFloatArray()
+        throws Exception
+    {
+        class FloatArrayTest
+        {
+
+            private float[] array = new float[10];
+        }
+
+        Field field = FloatArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, FloatArrayTest.class );
+
+        FloatArrayTest test = new FloatArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (float) ( i + 1. );
+        }
+
+        FloatArrayTest result = new FloatArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            float value = propertyAccessor.readFloat( test.array, i );
+            propertyAccessor.writeFloat( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeDoubleArray()
+        throws Exception
+    {
+        class DoubleArrayTest
+        {
+
+            private double[] array = new double[10];
+        }
+
+        Field field = DoubleArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, DoubleArrayTest.class );
+
+        DoubleArrayTest test = new DoubleArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1.;
+        }
+
+        DoubleArrayTest result = new DoubleArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            double value = propertyAccessor.readDouble( test.array, i );
+            propertyAccessor.writeDouble( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeObjectArray()
+        throws Exception
+    {
+        class ObjectArrayTest
+        {
+
+            private String[] array = new String[10];
+        }
+
+        Field field = ObjectArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new ReflectionPropertyAccessorFactory().fieldAccess( field, ObjectArrayTest.class );
+
+        ObjectArrayTest test = new ObjectArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = "Hello" + i;
+        }
+
+        ObjectArrayTest result = new ObjectArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            Object value = propertyAccessor.readObject( test.array, i );
+            propertyAccessor.writeObject( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/UnsafePropertyAccessorTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/UnsafePropertyAccessorTestCase.java
new file mode 100644
index 0000000..10e0ff9
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/beans/UnsafePropertyAccessorTestCase.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.beans;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+import org.apache.directmemory.lightning.internal.beans.SunUnsafePropertyAccessorFactory;
+import org.apache.directmemory.lightning.metadata.ArrayPropertyAccessor;
+import org.junit.Test;
+
+public class UnsafePropertyAccessorTestCase
+{
+
+    @Test
+    public void testUnsafeBooleanArray()
+        throws Exception
+    {
+        class BooleanArrayTest
+        {
+
+            private boolean[] array = new boolean[10];
+        }
+
+        Field field = BooleanArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, BooleanArrayTest.class );
+
+        BooleanArrayTest test = new BooleanArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i % 2 == 0 ? true : false;
+        }
+
+        BooleanArrayTest result = new BooleanArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            boolean value = propertyAccessor.readBoolean( test.array, i );
+            propertyAccessor.writeBoolean( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeByteArray()
+        throws Exception
+    {
+        class ByteArrayTest
+        {
+
+            private byte[] array = new byte[10];
+        }
+
+        Field field = ByteArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, ByteArrayTest.class );
+
+        ByteArrayTest test = new ByteArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (byte) ( i + 1 );
+        }
+
+        ByteArrayTest result = new ByteArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            byte value = propertyAccessor.readByte( test.array, i );
+            propertyAccessor.writeByte( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeShortArray()
+        throws Exception
+    {
+        class ShortArrayTest
+        {
+
+            private short[] array = new short[10];
+        }
+
+        Field field = ShortArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, ShortArrayTest.class );
+
+        ShortArrayTest test = new ShortArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (short) ( i + 1 );
+        }
+
+        ShortArrayTest result = new ShortArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            short value = propertyAccessor.readShort( test.array, i );
+            propertyAccessor.writeShort( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeIntArray()
+        throws Exception
+    {
+        class IntArrayTest
+        {
+
+            private int[] array = new int[10];
+        }
+
+        Field field = IntArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, IntArrayTest.class );
+
+        IntArrayTest test = new IntArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1;
+        }
+
+        IntArrayTest result = new IntArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            int value = propertyAccessor.readInt( test.array, i );
+            propertyAccessor.writeInt( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeLongArray()
+        throws Exception
+    {
+        class LongArrayTest
+        {
+
+            private long[] array = new long[10];
+        }
+
+        Field field = LongArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, LongArrayTest.class );
+
+        LongArrayTest test = new LongArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1;
+        }
+
+        LongArrayTest result = new LongArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            long value = propertyAccessor.readLong( test.array, i );
+            propertyAccessor.writeLong( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeFloatArray()
+        throws Exception
+    {
+        class FloatArrayTest
+        {
+
+            private float[] array = new float[10];
+        }
+
+        Field field = FloatArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, FloatArrayTest.class );
+
+        FloatArrayTest test = new FloatArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = (float) ( i + 1. );
+        }
+
+        FloatArrayTest result = new FloatArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            float value = propertyAccessor.readFloat( test.array, i );
+            propertyAccessor.writeFloat( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeDoubleArray()
+        throws Exception
+    {
+        class DoubleArrayTest
+        {
+
+            private double[] array = new double[10];
+        }
+
+        Field field = DoubleArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, DoubleArrayTest.class );
+
+        DoubleArrayTest test = new DoubleArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = i + 1.;
+        }
+
+        DoubleArrayTest result = new DoubleArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            double value = propertyAccessor.readDouble( test.array, i );
+            propertyAccessor.writeDouble( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+
+    @Test
+    public void testUnsafeObjectArray()
+        throws Exception
+    {
+        class ObjectArrayTest
+        {
+
+            private String[] array = new String[10];
+        }
+
+        Field field = ObjectArrayTest.class.getDeclaredField( "array" );
+        ArrayPropertyAccessor propertyAccessor =
+            (ArrayPropertyAccessor) new SunUnsafePropertyAccessorFactory().fieldAccess( field, ObjectArrayTest.class );
+
+        ObjectArrayTest test = new ObjectArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            test.array[i] = "Hello" + i;
+        }
+
+        ObjectArrayTest result = new ObjectArrayTest();
+        for ( int i = 0; i < 10; i++ )
+        {
+            Object value = propertyAccessor.readObject( test.array, i );
+            propertyAccessor.writeObject( result.array, i, value );
+        }
+
+        Arrays.equals( test.array, result.array );
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ArrayMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ArrayMarshallerTestCase.java
new file mode 100644
index 0000000..92136b3
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ArrayMarshallerTestCase.java
@@ -0,0 +1,929 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Random;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.io.SerializerInputStream;
+import org.apache.directmemory.lightning.io.SerializerOutputStream;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class ArrayMarshallerTestCase
+{
+
+    private static final Random RANDOM = new Random( -System.nanoTime() );
+
+    @Test
+    public void testBooleanArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                      {
+
+                                                                                                          @Override
+                                                                                                          protected void configure()
+                                                                                                          {
+                                                                                                              serialize(
+                                                                                                                         BooleanArray.class ).attributes();
+                                                                                                          }
+                                                                                                      } ).build();
+
+        BooleanArray test = new BooleanArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (boolean[]) array )[index] = RANDOM.nextBoolean();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        BooleanArray result = (BooleanArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testByteArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( ByteArray.class ).attributes();
+            }
+        } );
+
+        ByteArray test = new ByteArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (byte[]) array )[index] = (byte) ( RANDOM.nextInt( 256 ) - 127 );
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        ByteArray result = (ByteArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testCharArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( CharArray.class ).attributes();
+            }
+        } );
+
+        CharArray test = new CharArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (char[]) array )[index] = (char) ( RANDOM.nextInt( 256 ) - 127 );
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        CharArray result = (CharArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testShortArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( ShortArray.class ).attributes();
+            }
+        } );
+
+        ShortArray test = new ShortArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (short[]) array )[index] = (short) ( RANDOM.nextInt( 256 ) - 127 );
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        ShortArray result = (ShortArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testIntArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( IntArray.class ).attributes();
+            }
+        } );
+
+        IntArray test = new IntArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (int[]) array )[index] = RANDOM.nextInt();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        IntArray result = (IntArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testLongArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( LongArray.class ).attributes();
+            }
+        } );
+
+        LongArray test = new LongArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (long[]) array )[index] = RANDOM.nextLong();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        LongArray result = (LongArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testFloatArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( FloatArray.class ).attributes();
+            }
+        } );
+
+        FloatArray test = new FloatArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (float[]) array )[index] = RANDOM.nextFloat();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        FloatArray result = (FloatArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testDoubleArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( DoubleArray.class ).attributes();
+            }
+        } );
+
+        DoubleArray test = new DoubleArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (double[]) array )[index] = RANDOM.nextDouble();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        DoubleArray result = (DoubleArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testObjectArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer = Lightning.createSerializer( new AbstractSerializerDefinition()
+        {
+
+            @Override
+            protected void configure()
+            {
+                serialize( ObjectArray.class ).attributes();
+            }
+        } );
+
+        ObjectArray test = new ObjectArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (Object[]) array )[index] = "Hello-" + RANDOM.nextInt();
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        ObjectArray result = (ObjectArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    @Test
+    public void testDeepObjectArrayMarshalling()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                      {
+
+                                                                                                          @Override
+                                                                                                          protected void configure()
+                                                                                                          {
+                                                                                                              serialize(
+                                                                                                                         DeepObjectArray.class ).attributes();
+                                                                                                          }
+                                                                                                      } ).build();
+
+        DeepObjectArray test = new DeepObjectArray();
+        fillArray( new Predicate()
+        {
+
+            @Override
+            public void execute( Object array, int index )
+            {
+                ( (ObjectArray[]) array )[index] = new ObjectArray();
+                fillArray( new Predicate()
+                {
+
+                    @Override
+                    public void execute( Object array, int index )
+                    {
+                        ( (Object[]) array )[index] = "Hello-" + RANDOM.nextInt();
+                    }
+                }, ( (ObjectArray[]) array )[index].array );
+            }
+        }, test.array );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        SerializerOutputStream out = new SerializerOutputStream( baos, serializer );
+
+        out.writeObject( test );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        SerializerInputStream in = new SerializerInputStream( bais, serializer );
+
+        DeepObjectArray result = (DeepObjectArray) in.readObject();
+
+        assertNotNull( result );
+        assertEquals( test, result );
+    }
+
+    private static void fillArray( Predicate predicate, Object array )
+    {
+        for ( int i = 0; i < 10; i++ )
+        {
+            predicate.execute( array, i );
+        }
+    }
+
+    private static interface Predicate
+    {
+
+        void execute( Object array, int index );
+    }
+
+    public static class BooleanArray
+    {
+
+        @Attribute
+        private boolean[] array = new boolean[10];
+
+        public boolean[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( boolean[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            BooleanArray other = (BooleanArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "BooleanArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class ByteArray
+    {
+
+        @Attribute
+        private byte[] array = new byte[10];
+
+        public byte[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( byte[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ByteArray other = (ByteArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ByteArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class CharArray
+    {
+
+        @Attribute
+        private char[] array = new char[10];
+
+        public char[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( char[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            CharArray other = (CharArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "CharArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class ShortArray
+    {
+
+        @Attribute
+        private short[] array = new short[10];
+
+        public short[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( short[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ShortArray other = (ShortArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ShortArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class IntArray
+    {
+
+        @Attribute
+        private int[] array = new int[10];
+
+        public int[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( int[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            IntArray other = (IntArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "IntArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class LongArray
+    {
+
+        @Attribute
+        private long[] array = new long[10];
+
+        public long[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( long[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            LongArray other = (LongArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "LongArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class FloatArray
+    {
+
+        @Attribute
+        private float[] array = new float[10];
+
+        public float[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( float[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            FloatArray other = (FloatArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "FloatArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class DoubleArray
+    {
+
+        @Attribute
+        private double[] array = new double[10];
+
+        public double[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( double[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            DoubleArray other = (DoubleArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "DoubleArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class ObjectArray
+    {
+
+        @Attribute
+        private String[] array = new String[10];
+
+        public String[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( String[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ObjectArray other = (ObjectArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ObjectArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+
+    public static class DeepObjectArray
+    {
+
+        @Attribute
+        private ObjectArray[] array = new ObjectArray[10];
+
+        public ObjectArray[] getArray()
+        {
+            return array;
+        }
+
+        public void setArray( ObjectArray[] array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Arrays.hashCode( array );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            DeepObjectArray other = (DeepObjectArray) obj;
+            if ( !Arrays.equals( array, other.array ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "DeepObjectArray [array=" + Arrays.toString( array ) + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshallerTestCase.java
new file mode 100644
index 0000000..1ddef48
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigDecimalMarshallerTestCase.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.math.BigDecimal;
+import java.util.Random;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class BigDecimalMarshallerTestCase
+{
+
+    @Test
+    public void testBigInteger()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     BigDecimalHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Random random = new Random( -System.nanoTime() );
+
+        BigDecimalHolder value = new BigDecimalHolder();
+        value.setValue1( BigDecimal.valueOf( random.nextLong() ).multiply( BigDecimal.valueOf( random.nextLong() ) ) );
+        value.setValue2( null );
+        value.setValue3( BigDecimal.valueOf( random.nextLong() ).subtract( BigDecimal.valueOf( random.nextLong() ) ) );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new BigDecimalHolder();
+        value.setValue1( BigDecimal.valueOf( random.nextLong() ).min( BigDecimal.valueOf( random.nextLong() ) ) );
+        value.setValue2( BigDecimal.valueOf( random.nextLong() ).divideToIntegralValue( BigDecimal.valueOf( random.nextLong() ) ) );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new BigDecimalHolder();
+        value.setValue1( null );
+        value.setValue2( BigDecimal.valueOf( random.nextLong() ).max( BigDecimal.valueOf( random.nextLong() ) ) );
+        value.setValue3( BigDecimal.valueOf( random.nextLong() ).add( BigDecimal.valueOf( random.nextLong() ) ) );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class BigDecimalHolder
+    {
+
+        @Attribute
+        private BigDecimal value1;
+
+        @Attribute
+        private BigDecimal value2;
+
+        @Attribute
+        private BigDecimal value3;
+
+        public BigDecimal getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( BigDecimal value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public BigDecimal getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( BigDecimal value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public BigDecimal getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( BigDecimal value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            BigDecimalHolder other = (BigDecimalHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "BigIntegerHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshallerTestCase.java
new file mode 100644
index 0000000..540666a
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BigIntegerMarshallerTestCase.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.math.BigInteger;
+import java.util.Random;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class BigIntegerMarshallerTestCase
+{
+
+    @Test
+    public void testBigInteger()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     BigIntegerHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Random random = new Random( -System.nanoTime() );
+
+        BigIntegerHolder value = new BigIntegerHolder();
+        value.setValue1( BigInteger.valueOf( random.nextLong() ).multiply( BigInteger.valueOf( random.nextLong() ) ) );
+        value.setValue2( null );
+        value.setValue3( BigInteger.valueOf( random.nextLong() ).subtract( BigInteger.valueOf( random.nextLong() ) ) );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new BigIntegerHolder();
+        value.setValue1( BigInteger.valueOf( random.nextLong() ).or( BigInteger.valueOf( random.nextLong() ) ) );
+        value.setValue2( BigInteger.valueOf( random.nextLong() ).divide( BigInteger.valueOf( random.nextLong() ) ) );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new BigIntegerHolder();
+        value.setValue1( null );
+        value.setValue2( BigInteger.valueOf( random.nextLong() ).and( BigInteger.valueOf( random.nextLong() ) ) );
+        value.setValue3( BigInteger.valueOf( random.nextLong() ).add( BigInteger.valueOf( random.nextLong() ) ) );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class BigIntegerHolder
+    {
+
+        @Attribute
+        private BigInteger value1;
+
+        @Attribute
+        private BigInteger value2;
+
+        @Attribute
+        private BigInteger value3;
+
+        public BigInteger getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( BigInteger value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public BigInteger getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( BigInteger value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public BigInteger getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( BigInteger value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            BigIntegerHolder other = (BigIntegerHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "BigIntegerHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshallerTestCase.java
new file mode 100644
index 0000000..c7d15ac
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/BooleanMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class BooleanMarshallerTestCase
+{
+
+    @Test
+    public void testBooleanPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( true );
+        value.setValue2( false );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( false );
+        value.setValue2( true );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testBooleanWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( true );
+        value.setValue2( null );
+        value.setValue3( false );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( false );
+        value.setValue2( true );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( true );
+        value.setValue3( false );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private boolean value1;
+
+        @Attribute
+        private boolean value2;
+
+        public boolean isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( boolean value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public boolean isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( boolean value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( value1 ? 1231 : 1237 );
+            result = prime * result + ( value2 ? 1231 : 1237 );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Boolean value1;
+
+        @Attribute
+        private Boolean value2;
+
+        @Attribute
+        private Boolean value3;
+
+        public Boolean getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Boolean value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Boolean getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Boolean value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Boolean getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Boolean value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshallerTestCase.java
new file mode 100644
index 0000000..a564941
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ByteMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class ByteMarshallerTestCase
+{
+
+    @Test
+    public void testBytePrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( (byte) 0 );
+        value.setValue2( Byte.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( (byte) -10 );
+        value.setValue2( (byte) 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testByteWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Byte.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( (byte) 34 );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( (byte) 0 );
+        value.setValue2( Byte.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( (byte) -1 );
+        value.setValue3( Byte.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private byte value1;
+
+        @Attribute
+        private byte value2;
+
+        public byte isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( byte value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public byte isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( byte value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + value1;
+            result = prime * result + value2;
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Byte value1;
+
+        @Attribute
+        private Byte value2;
+
+        @Attribute
+        private Byte value3;
+
+        public Byte getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Byte value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Byte getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Byte value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Byte getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Byte value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshallerTestCase.java
new file mode 100644
index 0000000..309d56e
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/CharacterMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class CharacterMarshallerTestCase
+{
+
+    @Test
+    public void testCharacterPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( (char) 0 );
+        value.setValue2( Character.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( (char) -10 );
+        value.setValue2( (char) 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testCharacterWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Character.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( (char) 34 );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( (char) 0 );
+        value.setValue2( Character.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( (char) -1 );
+        value.setValue3( Character.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private char value1;
+
+        @Attribute
+        private char value2;
+
+        public char isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( char value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public char isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( char value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + value1;
+            result = prime * result + value2;
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Character value1;
+
+        @Attribute
+        private Character value2;
+
+        @Attribute
+        private Character value3;
+
+        public Character getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Character value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Character getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Character value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Character getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Character value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshallerTestCase.java
new file mode 100644
index 0000000..d20b09c
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/DoubleMarshallerTestCase.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class DoubleMarshallerTestCase
+{
+
+    @Test
+    public void testDoublePrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( 0 );
+        value.setValue2( Double.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( -10 );
+        value.setValue2( 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testDoubleWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Double.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( 34D );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( 0D );
+        value.setValue2( Double.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( -1D );
+        value.setValue3( Double.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private double value1;
+
+        @Attribute
+        private double value2;
+
+        public double isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( double value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public double isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( double value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            long temp;
+            temp = Double.doubleToLongBits( value1 );
+            result = prime * result + (int) ( temp ^ ( temp >>> 32 ) );
+            temp = Double.doubleToLongBits( value2 );
+            result = prime * result + (int) ( temp ^ ( temp >>> 32 ) );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( Double.doubleToLongBits( value1 ) != Double.doubleToLongBits( other.value1 ) )
+                return false;
+            if ( Double.doubleToLongBits( value2 ) != Double.doubleToLongBits( other.value2 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Double value1;
+
+        @Attribute
+        private Double value2;
+
+        @Attribute
+        private Double value3;
+
+        public Double getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Double value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Double getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Double value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Double getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Double value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshallerTestCase.java
new file mode 100644
index 0000000..9ea3ea2
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/FloatMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class FloatMarshallerTestCase
+{
+
+    @Test
+    public void testFloatPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( 0 );
+        value.setValue2( Float.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( -10 );
+        value.setValue2( 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testFloatWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Float.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( 34F );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( 0F );
+        value.setValue2( Float.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( -1F );
+        value.setValue3( Float.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private float value1;
+
+        @Attribute
+        private float value2;
+
+        public float isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( float value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public float isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( float value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + Float.floatToIntBits( value1 );
+            result = prime * result + Float.floatToIntBits( value2 );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( Float.floatToIntBits( value1 ) != Float.floatToIntBits( other.value1 ) )
+                return false;
+            if ( Float.floatToIntBits( value2 ) != Float.floatToIntBits( other.value2 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Float value1;
+
+        @Attribute
+        private Float value2;
+
+        @Attribute
+        private Float value3;
+
+        public Float getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Float value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Float getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Float value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Float getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Float value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshallerTestCase.java
new file mode 100644
index 0000000..cbeb815
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/IntegerMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class IntegerMarshallerTestCase
+{
+
+    @Test
+    public void testIntegerPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( 0 );
+        value.setValue2( Integer.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( (short) -10 );
+        value.setValue2( (short) 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testIntegerWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Integer.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( 34 );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( 0 );
+        value.setValue2( Integer.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( -1 );
+        value.setValue3( Integer.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private int value1;
+
+        @Attribute
+        private int value2;
+
+        public int isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( int value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public int isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( int value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + value1;
+            result = prime * result + value2;
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Integer value1;
+
+        @Attribute
+        private Integer value2;
+
+        @Attribute
+        private Integer value3;
+
+        public Integer getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Integer value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Integer getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Integer value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Integer getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Integer value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshallerTestCase.java
new file mode 100644
index 0000000..f9f8672
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ListMarshallerTestCase.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class ListMarshallerTestCase
+{
+
+    @Test
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public void testNoGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     NoGenericTypeList.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        List list = new ArrayList();
+        list.add( "Foo" );
+        list.add( 20 );
+        list.add( null );
+        list.add( BigInteger.TEN );
+
+        NoGenericTypeList value = new NoGenericTypeList();
+        value.setList( list );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testSimpleGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     SimpleGenericTypeList.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        List<String> list = new ArrayList<String>();
+        list.add( "Foo" );
+        list.add( "Bar" );
+        list.add( null );
+        list.add( "Rhabarbar" );
+
+        SimpleGenericTypeList value = new SimpleGenericTypeList();
+        value.setList( list );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testComplexGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     ComplexGenericTypeList.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        List<List<String>> list = new ArrayList<List<String>>();
+
+        List<String> list1 = new ArrayList<String>();
+        list1.add( "Foo" );
+        list1.add( "Bar" );
+        list1.add( null );
+        list1.add( "Rhabarbar" );
+
+        List<String> list2 = new ArrayList<String>();
+        list2.add( null );
+        list2.add( "Rhabarbar" );
+        list2.add( "Foo" );
+        list2.add( "Bar" );
+
+        list.add( list1 );
+        list.add( list2 );
+
+        ComplexGenericTypeList value = new ComplexGenericTypeList();
+        value.setList( list );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public static class NoGenericTypeList
+    {
+
+        @Attribute
+        private List list;
+
+        public List getList()
+        {
+            return list;
+        }
+
+        public void setList( List list )
+        {
+            this.list = list;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( list == null ) ? 0 : list.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            NoGenericTypeList other = (NoGenericTypeList) obj;
+            if ( list == null )
+            {
+                if ( other.list != null )
+                    return false;
+            }
+            else if ( !list.equals( other.list ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "NoGenericTypeList [list=" + list + "]";
+        }
+    }
+
+    public static class SimpleGenericTypeList
+    {
+
+        @Attribute
+        private List<String> list;
+
+        public List<String> getList()
+        {
+            return list;
+        }
+
+        public void setList( List<String> list )
+        {
+            this.list = list;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( list == null ) ? 0 : list.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            SimpleGenericTypeList other = (SimpleGenericTypeList) obj;
+            if ( list == null )
+            {
+                if ( other.list != null )
+                    return false;
+            }
+            else if ( !list.equals( other.list ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "SimpleGenericTypeList [list=" + list + "]";
+        }
+    }
+
+    public static class ComplexGenericTypeList
+    {
+
+        @Attribute
+        private List<List<String>> list;
+
+        public List<List<String>> getList()
+        {
+            return list;
+        }
+
+        public void setList( List<List<String>> list )
+        {
+            this.list = list;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( list == null ) ? 0 : list.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ComplexGenericTypeList other = (ComplexGenericTypeList) obj;
+            if ( list == null )
+            {
+                if ( other.list != null )
+                    return false;
+            }
+            else if ( !list.equals( other.list ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ComplexGenericTypeList [list=" + list + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshallerTestCase.java
new file mode 100644
index 0000000..be33b3c
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/LongMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class LongMarshallerTestCase
+{
+
+    @Test
+    public void testLongPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( 0 );
+        value.setValue2( Long.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( -10 );
+        value.setValue2( 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testLongWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Long.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( 34L );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( 0L );
+        value.setValue2( Long.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( -1L );
+        value.setValue3( Long.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private long value1;
+
+        @Attribute
+        private long value2;
+
+        public long isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( long value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public long isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( long value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + (int) ( value1 ^ ( value1 >>> 32 ) );
+            result = prime * result + (int) ( value2 ^ ( value2 >>> 32 ) );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Long value1;
+
+        @Attribute
+        private Long value2;
+
+        @Attribute
+        private Long value3;
+
+        public Long getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Long value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Long getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Long value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Long getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Long value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshallerTestCase.java
new file mode 100644
index 0000000..da3b546
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/MapMarshallerTestCase.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class MapMarshallerTestCase
+{
+
+    @Test
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public void testNoGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     NoGenericTypeMap.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Map map = new HashMap();
+        map.put( "Foo", 20 );
+        map.put( 21, "foo" );
+        map.put( "bar", null );
+        map.put( 44, BigInteger.TEN );
+
+        NoGenericTypeMap value = new NoGenericTypeMap();
+        value.setMap( map );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testSimpleGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     SimpleGenericTypeMap.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Map<String, Integer> map = new HashMap<String, Integer>();
+        map.put( "Foo", 21 );
+        map.put( "Bar", Integer.MAX_VALUE );
+        map.put( "Rhabarbar", null );
+
+        SimpleGenericTypeMap value = new SimpleGenericTypeMap();
+        value.setMap( map );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testComplexGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     ComplexGenericTypeSet.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Set<Set<String>> set = new HashSet<Set<String>>();
+
+        Set<String> set1 = new HashSet<String>();
+        set1.add( "Foo" );
+        set1.add( "Bar" );
+        set1.add( null );
+        set1.add( "Rhabarbar" );
+
+        Set<String> set2 = new HashSet<String>();
+        set2.add( null );
+        set2.add( "Rhabarbar" );
+        set2.add( "Foo" );
+        set2.add( "Bar" );
+
+        set.add( set1 );
+        set.add( set2 );
+
+        ComplexGenericTypeSet value = new ComplexGenericTypeSet();
+        value.setSet( set );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public static class NoGenericTypeMap
+    {
+
+        @Attribute
+        private Map map;
+
+        public Map getmap()
+        {
+            return map;
+        }
+
+        public void setMap( Map map )
+        {
+            this.map = map;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( map == null ) ? 0 : map.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            NoGenericTypeMap other = (NoGenericTypeMap) obj;
+            if ( map == null )
+            {
+                if ( other.map != null )
+                    return false;
+            }
+            else if ( !map.equals( other.map ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "NoGenericTypeMap [map=" + map + "]";
+        }
+    }
+
+    public static class SimpleGenericTypeMap
+    {
+
+        @Attribute
+        private Map<String, Integer> map;
+
+        public Map<String, Integer> getMap()
+        {
+            return map;
+        }
+
+        public void setMap( Map<String, Integer> map )
+        {
+            this.map = map;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( map == null ) ? 0 : map.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            SimpleGenericTypeMap other = (SimpleGenericTypeMap) obj;
+            if ( map == null )
+            {
+                if ( other.map != null )
+                    return false;
+            }
+            else if ( !map.equals( other.map ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "SimpleGenericTypeMap [map=" + map + "]";
+        }
+    }
+
+    public static class ComplexGenericTypeSet
+    {
+
+        @Attribute
+        private Set<Set<String>> set;
+
+        public Set<Set<String>> getSet()
+        {
+            return set;
+        }
+
+        public void setSet( Set<Set<String>> set )
+        {
+            this.set = set;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( set == null ) ? 0 : set.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ComplexGenericTypeSet other = (ComplexGenericTypeSet) obj;
+            if ( set == null )
+            {
+                if ( other.set != null )
+                    return false;
+            }
+            else if ( !set.equals( other.set ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ComplexGenericTypeSet [set=" + set + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshallerTestCase.java
new file mode 100644
index 0000000..aa24909
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/SetMarshallerTestCase.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SetMarshallerTestCase
+{
+
+    @Test
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public void testNoGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     NoGenericTypeSet.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Set set = new HashSet();
+        set.add( "Foo" );
+        set.add( 20 );
+        set.add( null );
+        set.add( BigInteger.TEN );
+
+        NoGenericTypeSet value = new NoGenericTypeSet();
+        value.setSet( set );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testSimpleGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     SimpleGenericTypeSet.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Set<String> set = new HashSet<String>();
+        set.add( "Foo" );
+        set.add( "Bar" );
+        set.add( null );
+        set.add( "Rhabarbar" );
+
+        SimpleGenericTypeSet value = new SimpleGenericTypeSet();
+        value.setSet( set );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testComplexGenericTypeList()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     ComplexGenericTypeSet.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        Set<Set<String>> set = new HashSet<Set<String>>();
+
+        Set<String> set1 = new HashSet<String>();
+        set1.add( "Foo" );
+        set1.add( "Bar" );
+        set1.add( null );
+        set1.add( "Rhabarbar" );
+
+        Set<String> set2 = new HashSet<String>();
+        set2.add( null );
+        set2.add( "Rhabarbar" );
+        set2.add( "Foo" );
+        set2.add( "Bar" );
+
+        set.add( set1 );
+        set.add( set2 );
+
+        ComplexGenericTypeSet value = new ComplexGenericTypeSet();
+        value.setSet( set );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public static class NoGenericTypeSet
+    {
+
+        @Attribute
+        private Set set;
+
+        public Set getSet()
+        {
+            return set;
+        }
+
+        public void setSet( Set set )
+        {
+            this.set = set;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( set == null ) ? 0 : set.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            NoGenericTypeSet other = (NoGenericTypeSet) obj;
+            if ( set == null )
+            {
+                if ( other.set != null )
+                    return false;
+            }
+            else if ( !set.equals( other.set ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "NoGenericTypeSet [set=" + set + "]";
+        }
+    }
+
+    public static class SimpleGenericTypeSet
+    {
+
+        @Attribute
+        private Set<String> set;
+
+        public Set<String> getSet()
+        {
+            return set;
+        }
+
+        public void setSet( Set<String> set )
+        {
+            this.set = set;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( set == null ) ? 0 : set.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            SimpleGenericTypeSet other = (SimpleGenericTypeSet) obj;
+            if ( set == null )
+            {
+                if ( other.set != null )
+                    return false;
+            }
+            else if ( !set.equals( other.set ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "SimpleGenericTypeSet [set=" + set + "]";
+        }
+    }
+
+    public static class ComplexGenericTypeSet
+    {
+
+        @Attribute
+        private Set<Set<String>> set;
+
+        public Set<Set<String>> getSet()
+        {
+            return set;
+        }
+
+        public void setSet( Set<Set<String>> set )
+        {
+            this.set = set;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( set == null ) ? 0 : set.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            ComplexGenericTypeSet other = (ComplexGenericTypeSet) obj;
+            if ( set == null )
+            {
+                if ( other.set != null )
+                    return false;
+            }
+            else if ( !set.equals( other.set ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "ComplexGenericTypeSet [set=" + set + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshallerTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshallerTestCase.java
new file mode 100644
index 0000000..e15fd9a
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/marshaller/ShortMarshallerTestCase.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.marshaller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.internal.util.DebugLogger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.junit.Test;
+
+public class ShortMarshallerTestCase
+{
+
+    @Test
+    public void testShortPrimitive()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     PrimitiveHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        PrimitiveHolder value = new PrimitiveHolder();
+        value.setValue1( (short) 0 );
+        value.setValue2( Short.MAX_VALUE );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new PrimitiveHolder();
+        value.setValue1( (short) -10 );
+        value.setValue2( (short) 20 );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    @Test
+    public void testShortWrapper()
+        throws Exception
+    {
+        Serializer serializer =
+            Lightning.newBuilder().logger( new DebugLogger() ).debugCacheDirectory( new File( "target" ) ).serializerDefinitions( new AbstractSerializerDefinition()
+                                                                                                                                  {
+
+                                                                                                                                      @Override
+                                                                                                                                      protected void configure()
+                                                                                                                                      {
+                                                                                                                                          serialize(
+                                                                                                                                                     WrapperHolder.class ).attributes();
+                                                                                                                                      }
+                                                                                                                                  } ).build();
+
+        WrapperHolder value = new WrapperHolder();
+        value.setValue1( Short.MAX_VALUE );
+        value.setValue2( null );
+        value.setValue3( (short) 34 );
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
+        Object result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( (short) 0 );
+        value.setValue2( Short.MIN_VALUE );
+        value.setValue3( null );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+
+        value = new WrapperHolder();
+        value.setValue1( null );
+        value.setValue2( (short) -1 );
+        value.setValue3( Short.MAX_VALUE );
+
+        baos = new ByteArrayOutputStream();
+        serializer.serialize( value, baos );
+
+        bais = new ByteArrayInputStream( baos.toByteArray() );
+        result = serializer.deserialize( bais );
+
+        assertNotNull( result );
+        assertEquals( value, result );
+    }
+
+    public static class PrimitiveHolder
+    {
+
+        @Attribute
+        private short value1;
+
+        @Attribute
+        private short value2;
+
+        public short isValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( short value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public short isValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( short value2 )
+        {
+            this.value2 = value2;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + value1;
+            result = prime * result + value2;
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            PrimitiveHolder other = (PrimitiveHolder) obj;
+            if ( value1 != other.value1 )
+                return false;
+            if ( value2 != other.value2 )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "PrimitiveHolder [value1=" + value1 + ", value2=" + value2 + "]";
+        }
+    }
+
+    public static class WrapperHolder
+    {
+
+        @Attribute
+        private Short value1;
+
+        @Attribute
+        private Short value2;
+
+        @Attribute
+        private Short value3;
+
+        public Short getValue1()
+        {
+            return value1;
+        }
+
+        public void setValue1( Short value1 )
+        {
+            this.value1 = value1;
+        }
+
+        public Short getValue2()
+        {
+            return value2;
+        }
+
+        public void setValue2( Short value2 )
+        {
+            this.value2 = value2;
+        }
+
+        public Short getValue3()
+        {
+            return value3;
+        }
+
+        public void setValue3( Short value3 )
+        {
+            this.value3 = value3;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ( ( value1 == null ) ? 0 : value1.hashCode() );
+            result = prime * result + ( ( value2 == null ) ? 0 : value2.hashCode() );
+            result = prime * result + ( ( value3 == null ) ? 0 : value3.hashCode() );
+            return result;
+        }
+
+        @Override
+        public boolean equals( Object obj )
+        {
+            if ( this == obj )
+                return true;
+            if ( obj == null )
+                return false;
+            if ( getClass() != obj.getClass() )
+                return false;
+            WrapperHolder other = (WrapperHolder) obj;
+            if ( value1 == null )
+            {
+                if ( other.value1 != null )
+                    return false;
+            }
+            else if ( !value1.equals( other.value1 ) )
+                return false;
+            if ( value2 == null )
+            {
+                if ( other.value2 != null )
+                    return false;
+            }
+            else if ( !value2.equals( other.value2 ) )
+                return false;
+            if ( value3 == null )
+            {
+                if ( other.value3 != null )
+                    return false;
+            }
+            else if ( !value3.equals( other.value3 ) )
+                return false;
+            return true;
+        }
+
+        @Override
+        public String toString()
+        {
+            return "WrapperHolder [value1=" + value1 + ", value2=" + value2 + ", value3=" + value3 + "]";
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/BeanUtilTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/BeanUtilTestCase.java
new file mode 100644
index 0000000..b755332
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/BeanUtilTestCase.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.directmemory.lightning.internal.util.BeanUtil;
+import org.junit.Test;
+
+public class BeanUtilTestCase
+{
+
+    @Test
+    public void testPropertyNameCreation()
+        throws Exception
+    {
+        String methodName = "isDefined";
+        String result = BeanUtil.buildPropertyName( methodName );
+        assertEquals( "defined", result );
+
+        methodName = "getDefined";
+        result = BeanUtil.buildPropertyName( methodName );
+        assertEquals( "defined", result );
+
+        methodName = "setDefined";
+        result = BeanUtil.buildPropertyName( methodName );
+        assertEquals( "defined", result );
+
+        methodName = "doneDefined";
+        result = BeanUtil.buildPropertyName( methodName );
+        assertEquals( "doneDefined", result );
+    }
+
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/DebugLogger.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/DebugLogger.java
new file mode 100644
index 0000000..16c6e8e
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/DebugLogger.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import java.io.PrintStream;
+
+import org.apache.directmemory.lightning.logging.LogLevel;
+import org.apache.directmemory.lightning.logging.LoggerAdapter;
+
+public class DebugLogger
+    extends LoggerAdapter
+{
+
+    @Override
+    public boolean isLogLevelEnabled( LogLevel logLevel )
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isTraceEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isDebugEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isInfoEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isWarnEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isErrorEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public boolean isFatalEnabled()
+    {
+        return true;
+    }
+
+    @Override
+    public void trace( String message )
+    {
+        log( LogLevel.Trace, message, null );
+    }
+
+    @Override
+    public void trace( String message, Throwable throwable )
+    {
+        log( LogLevel.Trace, message, throwable );
+    }
+
+    @Override
+    public void debug( String message )
+    {
+        log( LogLevel.Debug, message, null );
+    }
+
+    @Override
+    public void debug( String message, Throwable throwable )
+    {
+        log( LogLevel.Debug, message, throwable );
+    }
+
+    @Override
+    public void info( String message )
+    {
+        log( LogLevel.Info, message, null );
+    }
+
+    @Override
+    public void info( String message, Throwable throwable )
+    {
+        log( LogLevel.Info, message, throwable );
+    }
+
+    @Override
+    public void warn( String message )
+    {
+        log( LogLevel.Warn, message, null );
+    }
+
+    @Override
+    public void warn( String message, Throwable throwable )
+    {
+        log( LogLevel.Warn, message, throwable );
+    }
+
+    @Override
+    public void error( String message )
+    {
+        log( LogLevel.Error, message, null );
+    }
+
+    @Override
+    public void error( String message, Throwable throwable )
+    {
+        log( LogLevel.Error, message, throwable );
+    }
+
+    @Override
+    public void fatal( String message )
+    {
+        log( LogLevel.Fatal, message, null );
+    }
+
+    @Override
+    public void fatal( String message, Throwable throwable )
+    {
+        log( LogLevel.Fatal, message, throwable );
+    }
+
+    private void log( LogLevel logLevel, String message, Throwable throwable )
+    {
+        PrintStream stream;
+        if ( throwable != null )
+        {
+            stream = System.err;
+        }
+        else
+        {
+            stream = System.out;
+        }
+
+        stream.println( getName() + " - " + logLevel.name() + ": " + message );
+        if ( throwable != null )
+        {
+            throwable.printStackTrace();
+        }
+    }
+}
diff --git a/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/StringUtilTestCase.java b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/StringUtilTestCase.java
new file mode 100644
index 0000000..7cfe90d
--- /dev/null
+++ b/lightning-core/src/test/java/org/apache/directmemory/lightning/internal/util/StringUtilTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.internal.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.directmemory.lightning.internal.util.StringUtil;
+import org.junit.Test;
+
+public class StringUtilTestCase
+{
+
+    @Test
+    public void testLowerCamelCase()
+        throws Exception
+    {
+        String value = "That is impossible";
+        String result = StringUtil.toLowerCamelCase( value );
+        assertEquals( "thatIsImpossible", result );
+
+        value = "that is impossible";
+        result = StringUtil.toLowerCamelCase( value );
+        assertEquals( "thatIsImpossible", result );
+
+        value = "that   is impossible";
+        result = StringUtil.toLowerCamelCase( value );
+        assertEquals( "thatIsImpossible", result );
+
+        value = "that-is impossible";
+        result = StringUtil.toLowerCamelCase( value );
+        assertEquals( "thatIsImpossible", result );
+
+        value = "that_is impossible";
+        result = StringUtil.toLowerCamelCase( value );
+        assertEquals( "thatIsImpossible", result );
+    }
+
+    @Test
+    public void testUpperCamelCase()
+        throws Exception
+    {
+        String value = "That is impossible";
+        String result = StringUtil.toUpperCamelCase( value );
+        assertEquals( "ThatIsImpossible", result );
+
+        value = "that is impossible";
+        result = StringUtil.toUpperCamelCase( value );
+        assertEquals( "ThatIsImpossible", result );
+
+        value = "that   is impossible";
+        result = StringUtil.toUpperCamelCase( value );
+        assertEquals( "ThatIsImpossible", result );
+
+        value = "that-is impossible";
+        result = StringUtil.toUpperCamelCase( value );
+        assertEquals( "ThatIsImpossible", result );
+
+        value = "that_is impossible";
+        result = StringUtil.toUpperCamelCase( value );
+        assertEquals( "ThatIsImpossible", result );
+    }
+
+}
diff --git a/lightning-integration/lightning-integration-jgroups/pom.xml b/lightning-integration/lightning-integration-jgroups/pom.xml
new file mode 100644
index 0000000..a35912d
--- /dev/null
+++ b/lightning-integration/lightning-integration-jgroups/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-integration-jgroups</artifactId>
+  <name>Lightning: JGroups Integration</name>
+
+  <parent>
+    <artifactId>lightning-integration</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-api</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jgroups</groupId>
+      <artifactId>jgroups</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningClusterException.java b/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningClusterException.java
new file mode 100644
index 0000000..7b1986a
--- /dev/null
+++ b/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningClusterException.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.jgroups;
+
+@SuppressWarnings( "serial" )
+public class LightningClusterException
+    extends RuntimeException
+{
+
+    public LightningClusterException()
+    {
+        super();
+    }
+
+    public LightningClusterException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public LightningClusterException( String message )
+    {
+        super( message );
+    }
+
+    public LightningClusterException( Throwable cause )
+    {
+        super( cause );
+    }
+}
diff --git a/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningJGroupsMembershipListener.java b/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningJGroupsMembershipListener.java
new file mode 100644
index 0000000..aa13605
--- /dev/null
+++ b/lightning-integration/lightning-integration-jgroups/src/main/java/org/apache/directmemory/lightning/jgroups/LightningJGroupsMembershipListener.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.jgroups;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.exceptions.ClassDefinitionInconsistentException;
+import org.apache.directmemory.lightning.metadata.ClassDefinitionContainer;
+import org.jgroups.Address;
+import org.jgroups.JChannel;
+import org.jgroups.MergeView;
+import org.jgroups.Message;
+import org.jgroups.ReceiverAdapter;
+import org.jgroups.View;
+import org.jgroups.util.Util;
+
+public class LightningJGroupsMembershipListener
+    extends ReceiverAdapter
+{
+
+    private final List<Address> lastMembersView = new ArrayList<Address>();
+
+    private final ExecutorService executorService;
+
+    private final Serializer serializer;
+
+    private final JChannel channel;
+
+    public LightningJGroupsMembershipListener( JChannel channel, Serializer serializer, ExecutorService executorService )
+    {
+
+        this.channel = channel;
+        this.serializer = serializer;
+        this.executorService = executorService;
+    }
+
+    @Override
+    public void viewAccepted( View view )
+    {
+        Runnable task;
+        if ( view instanceof MergeView )
+        {
+            task = handleSplitBrainMerge( view );
+        }
+        else
+        {
+            task = handleMemberJoin( view );
+        }
+
+        if ( task != null )
+        {
+            executorService.submit( task );
+        }
+    }
+
+    @Override
+    public void receive( Message msg )
+    {
+        // If we received a ClassDefinitionContainer handle it otherwise just
+        // ignore the message
+        if ( msg.getObject() instanceof ClassDefinitionContainer )
+        {
+            ClassDefinitionContainer container = (ClassDefinitionContainer) msg.getObject();
+            try
+            {
+                serializer.setClassDefinitionContainer( container );
+            }
+            catch ( ClassDefinitionInconsistentException e )
+            {
+                channel.disconnect();
+                throw new LightningClusterException( "Class checksums are not consistent, channel disconnected", e );
+            }
+        }
+    }
+
+    private Runnable handleMemberJoin( View view )
+    {
+        List<Address> members = view.getMembers();
+
+        // Quote from JGroups documentation:
+        // *Note that the first member of a view is the coordinator (the one who
+        // emits new views).*
+        Address coordinator = members.get( 0 );
+
+        if ( channel.getAddress().equals( coordinator ) )
+        {
+            final ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+            final List<Address> receivers = findNewMembers( view );
+
+            try
+            {
+                final byte[] byteBuffer = Util.objectToByteBuffer( container );
+
+                return new Runnable()
+                {
+
+                    @Override
+                    public void run()
+                    {
+                        for ( Address receiver : receivers )
+                        {
+                            try
+                            {
+                                channel.send( receiver, byteBuffer );
+                            }
+                            catch ( Exception e )
+                            {
+                                throw new LightningClusterException(
+                                                                     "Could not send ClassDefinitionContainer to address "
+                                                                         + receiver, e );
+                            }
+                        }
+                    }
+                };
+            }
+            catch ( Exception e )
+            {
+                throw new LightningClusterException( "Could not serialize ClassDefinitionContainer", e );
+            }
+        }
+
+        return null;
+    }
+
+    private Runnable handleSplitBrainMerge( View view )
+    {
+        final List<Address> members = new ArrayList<Address>( view.getMembers() );
+
+        // Quote from JGroups documentation:
+        // *Note that the first member of a view is the coordinator (the one who
+        // emits new views).*
+        Address coordinator = members.get( 0 );
+
+        if ( channel.getAddress().equals( coordinator ) )
+        {
+            final ClassDefinitionContainer container = serializer.getClassDefinitionContainer();
+
+            try
+            {
+                final byte[] byteBuffer = Util.objectToByteBuffer( container );
+
+                return new Runnable()
+                {
+
+                    @Override
+                    public void run()
+                    {
+                        for ( int i = 1; i < members.size(); i++ )
+                        {
+                            Address receiver = members.get( i );
+                            if ( receiver == null )
+                            {
+                                continue;
+                            }
+
+                            try
+                            {
+                                channel.send( receiver, byteBuffer );
+                            }
+                            catch ( Exception e )
+                            {
+                                throw new LightningClusterException(
+                                                                     "Could not send ClassDefinitionContainer to address "
+                                                                         + receiver, e );
+                            }
+                        }
+                    }
+                };
+            }
+            catch ( Exception e )
+            {
+                throw new LightningClusterException( "Could not serialize ClassDefinitionContainer", e );
+            }
+        }
+
+        return null;
+    }
+
+    private List<Address> findNewMembers( View view )
+    {
+        List<Address> newMembers = new ArrayList<Address>();
+        for ( Address member : view.getMembers() )
+        {
+            if ( !lastMembersView.contains( member ) )
+            {
+                newMembers.add( member );
+            }
+        }
+        return newMembers;
+    }
+}
diff --git a/lightning-integration/lightning-integration-spring/pom.xml b/lightning-integration/lightning-integration-spring/pom.xml
new file mode 100644
index 0000000..f491763
--- /dev/null
+++ b/lightning-integration/lightning-integration-spring/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-integration-spring</artifactId>
+  <name>Lightning: Spring Integration</name>
+
+  <parent>
+    <artifactId>lightning-integration</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-api</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-beans</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/LightningFactoryBean.java b/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/LightningFactoryBean.java
new file mode 100644
index 0000000..ad72526
--- /dev/null
+++ b/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/LightningFactoryBean.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.spring;
+
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directmemory.lightning.ClassComparisonStrategy;
+import org.apache.directmemory.lightning.Lightning;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+
+public class LightningFactoryBean
+    implements FactoryBean, InitializingBean
+{
+
+    private Serializer singletonSerializer;
+
+    private boolean prototype = false;
+
+    private List<SerializerDefinition> serializerDefinitions = new ArrayList<SerializerDefinition>();
+
+    private ClassComparisonStrategy classComparisonStrategy = ClassComparisonStrategy.LightningChecksum;
+
+    private Class<? extends Annotation> attributesAnnotation = Attribute.class;
+
+    private SerializationStrategy serializationStrategy = SerializationStrategy.SpeedOptimized;
+
+    private Logger logger = new SpringLoggingAdapter();
+
+    private File debugCacheDirectory = null;
+
+    @Override
+    public Object getObject()
+        throws Exception
+    {
+        if ( isSingleton() )
+        {
+            return singletonSerializer;
+        }
+
+        return Lightning.newBuilder().classComparisonStrategy( classComparisonStrategy ).debugCacheDirectory( debugCacheDirectory ).describesAttributs( attributesAnnotation ).logger( logger ).serializationStrategy( serializationStrategy ).serializerDefinitions( serializerDefinitions ).build();
+    }
+
+    @Override
+    public Class<?> getObjectType()
+    {
+        return Serializer.class;
+    }
+
+    @Override
+    public boolean isSingleton()
+    {
+        return !prototype;
+    }
+
+    @Override
+    public void afterPropertiesSet()
+        throws Exception
+    {
+        if ( isSingleton() )
+        {
+            synchronized ( this )
+            {
+                singletonSerializer =
+                    Lightning.newBuilder().classComparisonStrategy( classComparisonStrategy ).debugCacheDirectory( debugCacheDirectory ).describesAttributs( attributesAnnotation ).logger( logger ).serializationStrategy( serializationStrategy ).serializerDefinitions( serializerDefinitions ).build();
+            }
+        }
+    }
+
+    public void setPrototype( boolean prototype )
+    {
+        this.prototype = prototype;
+    }
+
+    public boolean getPrototype()
+    {
+        return prototype;
+    }
+
+    public List<SerializerDefinition> getSerializerDefinitions()
+    {
+        return serializerDefinitions;
+    }
+
+    public void setSerializerDefinitions( List<SerializerDefinition> serializerDefinitions )
+    {
+        this.serializerDefinitions = serializerDefinitions;
+    }
+
+    public ClassComparisonStrategy getClassComparisonStrategy()
+    {
+        return classComparisonStrategy;
+    }
+
+    public void setClassComparisonStrategy( ClassComparisonStrategy classComparisonStrategy )
+    {
+        this.classComparisonStrategy = classComparisonStrategy;
+    }
+
+    public File getDebugCacheDirectory()
+    {
+        return debugCacheDirectory;
+    }
+
+    public void setDebugCacheDirectory( File debugCacheDirectory )
+    {
+        this.debugCacheDirectory = debugCacheDirectory;
+    }
+
+    public Class<? extends Annotation> getAttributesAnnotation()
+    {
+        return attributesAnnotation;
+    }
+
+    public void setAttributesAnnotation( Class<? extends Annotation> attributesAnnotation )
+    {
+        this.attributesAnnotation = attributesAnnotation;
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public void setLogger( Logger logger )
+    {
+        this.logger = logger;
+    }
+
+    public SerializationStrategy getSerializationStrategy()
+    {
+        return serializationStrategy;
+    }
+
+    public void setSerializationStrategy( SerializationStrategy serializationStrategy )
+    {
+        this.serializationStrategy = serializationStrategy;
+    }
+}
diff --git a/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/SpringLoggingAdapter.java b/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/SpringLoggingAdapter.java
new file mode 100644
index 0000000..0c45909
--- /dev/null
+++ b/lightning-integration/lightning-integration-spring/src/main/java/org/apache/directmemory/lightning/spring/SpringLoggingAdapter.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.spring;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.directmemory.lightning.logging.LogLevel;
+import org.apache.directmemory.lightning.logging.Logger;
+
+public class SpringLoggingAdapter
+    implements Logger
+{
+
+    private final Log logger;
+
+    private final String name;
+
+    public SpringLoggingAdapter()
+    {
+        this( SpringLoggingAdapter.class );
+    }
+
+    public SpringLoggingAdapter( Class<?> clazz )
+    {
+        this.logger = LogFactory.getLog( clazz );
+        this.name = clazz.getCanonicalName();
+    }
+
+    public SpringLoggingAdapter( String name )
+    {
+        this.logger = LogFactory.getLog( name );
+        this.name = name;
+    }
+
+    @Override
+    public Logger getChildLogger( Class<?> clazz )
+    {
+        return new SpringLoggingAdapter( clazz );
+    }
+
+    @Override
+    public Logger getChildLogger( String name )
+    {
+        return new SpringLoggingAdapter( name );
+    }
+
+    @Override
+    public String getName()
+    {
+        return name;
+    }
+
+    @Override
+    public boolean isLogLevelEnabled( LogLevel logLevel )
+    {
+        switch ( logLevel )
+        {
+            case Debug:
+                return isDebugEnabled();
+            case Error:
+                return isErrorEnabled();
+            case Fatal:
+                return isFatalEnabled();
+            case Info:
+                return isInfoEnabled();
+            case Trace:
+                return isTraceEnabled();
+            case Warn:
+                return isWarnEnabled();
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isTraceEnabled()
+    {
+        return logger.isTraceEnabled();
+    }
+
+    @Override
+    public boolean isDebugEnabled()
+    {
+        return logger.isDebugEnabled();
+    }
+
+    @Override
+    public boolean isInfoEnabled()
+    {
+        return logger.isInfoEnabled();
+    }
+
+    @Override
+    public boolean isWarnEnabled()
+    {
+        return logger.isWarnEnabled();
+    }
+
+    @Override
+    public boolean isErrorEnabled()
+    {
+        return logger.isErrorEnabled();
+    }
+
+    @Override
+    public boolean isFatalEnabled()
+    {
+        return logger.isFatalEnabled();
+    }
+
+    @Override
+    public void trace( String message )
+    {
+        trace( message, null );
+    }
+
+    @Override
+    public void trace( String message, Throwable throwable )
+    {
+        logger.trace( message, throwable );
+    }
+
+    @Override
+    public void debug( String message )
+    {
+        debug( message, null );
+    }
+
+    @Override
+    public void debug( String message, Throwable throwable )
+    {
+        logger.debug( message, throwable );
+    }
+
+    @Override
+    public void info( String message )
+    {
+        info( message, null );
+    }
+
+    @Override
+    public void info( String message, Throwable throwable )
+    {
+        logger.info( message, throwable );
+    }
+
+    @Override
+    public void warn( String message )
+    {
+        warn( message, null );
+    }
+
+    @Override
+    public void warn( String message, Throwable throwable )
+    {
+        logger.warn( message, throwable );
+    }
+
+    @Override
+    public void error( String message )
+    {
+        error( message, null );
+    }
+
+    @Override
+    public void error( String message, Throwable throwable )
+    {
+        logger.error( message, throwable );
+    }
+
+    @Override
+    public void fatal( String message )
+    {
+        fatal( message, null );
+    }
+
+    @Override
+    public void fatal( String message, Throwable throwable )
+    {
+        logger.fatal( message, throwable );
+    }
+}
diff --git a/lightning-integration/pom.xml b/lightning-integration/pom.xml
new file mode 100644
index 0000000..8d6e7c1
--- /dev/null
+++ b/lightning-integration/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-integration</artifactId>
+  <packaging>pom</packaging>
+  <name>Lightning: Integration Reactor</name>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <modules>
+    <module>lightning-integration-jgroups</module>
+    <module>lightning-integration-spring</module>
+  </modules>
+</project>
diff --git a/lightning-maven-eclipse-helper-feature/build.properties b/lightning-maven-eclipse-helper-feature/build.properties
new file mode 100644
index 0000000..93b06a6
--- /dev/null
+++ b/lightning-maven-eclipse-helper-feature/build.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+bin.includes = feature.xml,\
+               feature.properties
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper-feature/feature.properties b/lightning-maven-eclipse-helper-feature/feature.properties
new file mode 100644
index 0000000..c28f59e
--- /dev/null
+++ b/lightning-maven-eclipse-helper-feature/feature.properties
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# "featureName" property - name of the feature
+featureName=m2e connector for lightning-maven-eclipse-helper-plugin
+
+# "providerName" property - name of the company that provides the feature
+providerName=Apache Software Foundation
+
+# "updateSiteName" property - label for the update site
+#updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=m2e connector for lightning-maven-eclipse-helper-plugin
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright= 
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=http://www.apache.org/licenses/LICENSE-2.0.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+\n\ 
+\n\ Licensed to the Apache Software Foundation (ASF) under one
+\n\ or more contributor license agreements.  See the NOTICE file
+\n\ distributed with this work for additional information
+\n\ regarding copyright ownership.  The ASF licenses this file
+\n\ to you under the Apache License, Version 2.0 (the
+\n\ "License"); you may not use this file except in compliance
+\n\ with the License.  You may obtain a copy of the License at
+\n\ 
+\n\   http://www.apache.org/licenses/LICENSE-2.0
+\n\ 
+\n\ Unless required by applicable law or agreed to in writing,
+\n\ software distributed under the License is distributed on an
+\n\ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+\n\ KIND, either express or implied.  See the License for the
+\n\ specific language governing permissions and limitations
+\n\ under the License.
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper-feature/feature.xml b/lightning-maven-eclipse-helper-feature/feature.xml
new file mode 100644
index 0000000..92a1259
--- /dev/null
+++ b/lightning-maven-eclipse-helper-feature/feature.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<feature
+    id="lightning-maven-eclipse-helper-feature"
+    label="%featureName"
+    version="0.0.1.qualifier"
+    provider-name="%providerName"
+    plugin="lightning-maven-eclipse-helper">
+
+  <description>%description</description>
+
+  <copyright>%copyright</copyright>
+
+  <license url="%licenseURL">%license</license>
+   
+  <plugin
+    id="lightning-maven-eclipse-helper"
+    download-size="0"
+    install-size="0"
+    version="0.0.0"
+    unpack="false"/>
+</feature>
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper-feature/pom.xml b/lightning-maven-eclipse-helper-feature/pom.xml
new file mode 100644
index 0000000..efbd33c
--- /dev/null
+++ b/lightning-maven-eclipse-helper-feature/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-maven-eclipse-helper-feature</artifactId>
+  <name>Lightning: Maven Eclipse Helper Feature</name>
+  <packaging>eclipse-feature</packaging>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-maven-plugin</artifactId>
+        <version>0.14.0</version>
+        <extensions>true</extensions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>target-platform-configuration</artifactId>
+        <version>0.14.0</version>
+        <configuration>
+          <resolver>p2</resolver>
+          <ignoreTychoRepositories>true</ignoreTychoRepositories>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>eclipse</id>
+      <url>http://download.eclipse.org/releases/indigo</url>
+      <layout>p2</layout>
+    </pluginRepository>
+    <pluginRepository>
+      <id>m2e</id>
+      <url>http://repository.sonatype.org/content/repositories/forge-sites/m2e/1.1.0/N/LATEST/</url>
+      <layout>p2</layout>
+    </pluginRepository>
+    <pluginRepository>
+      <id>rso</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+    </pluginRepository>
+  </pluginRepositories>
+  <repositories>
+    <repository>
+      <id>eclipse</id>
+      <url>http://download.eclipse.org/releases/indigo</url>
+      <layout>p2</layout>
+    </repository>
+    <repository>
+      <id>m2e</id>
+      <url>http://repository.sonatype.org/content/repositories/forge-sites/m2e/1.1.0/N/LATEST/</url>
+      <layout>p2</layout>
+    </repository>
+    <repository>
+      <id>rso</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+    </repository>
+  </repositories>
+</project>
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper/META-INF/MANIFEST.MF b/lightning-maven-eclipse-helper/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..3353eb8
--- /dev/null
+++ b/lightning-maven-eclipse-helper/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: m2e connector for lightning-maven-plugin
+Bundle-SymbolicName: lightning-maven-eclipse-helper;singleton:=true
+Bundle-Version: 0.0.1.qualifier
+Bundle-Vendor: Noctarius
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,
+ JavaSE-1.6
+Require-Bundle: org.eclipse.m2e.jdt;bundle-version="[1.1.0,1.2.0)",
+ org.eclipse.m2e.core;bundle-version="[1.1.0,1.2.0)"
diff --git a/lightning-maven-eclipse-helper/build.properties b/lightning-maven-eclipse-helper/build.properties
new file mode 100644
index 0000000..3fdd888
--- /dev/null
+++ b/lightning-maven-eclipse-helper/build.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+bin.includes = META-INF/,\
+               plugin.xml,\
+               lifecycle-mapping-metadata.xml
+jars.compile.order = 
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper/lifecycle-mapping-metadata.xml b/lightning-maven-eclipse-helper/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..f7d2160
--- /dev/null
+++ b/lightning-maven-eclipse-helper/lifecycle-mapping-metadata.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<lifecycleMappingMetadata>
+  <pluginExecutions>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <groupId>org.apache.directmemory.lightning</groupId>
+        <artifactId>lightning-maven-plugin</artifactId>
+        <goals>
+          <goal>generate</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnIncremental>true</runOnIncremental>
+          <runOnConfiguration>true</runOnConfiguration>
+        </execute>
+      </action>
+    </pluginExecution>
+  </pluginExecutions>
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper/plugin.xml b/lightning-maven-eclipse-helper/plugin.xml
new file mode 100644
index 0000000..5550f5c
--- /dev/null
+++ b/lightning-maven-eclipse-helper/plugin.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<plugin>
+  <extension
+    point="org.eclipse.m2e.core.lifecycleMappingMetadataSource">
+  </extension>
+</plugin>
\ No newline at end of file
diff --git a/lightning-maven-eclipse-helper/pom.xml b/lightning-maven-eclipse-helper/pom.xml
new file mode 100644
index 0000000..5312ed7
--- /dev/null
+++ b/lightning-maven-eclipse-helper/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-maven-eclipse-helper</artifactId>
+  <name>Lightning: Maven Eclipse Helper</name>
+  <packaging>eclipse-plugin</packaging>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-maven-plugin</artifactId>
+        <version>0.14.0</version>
+        <extensions>true</extensions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>target-platform-configuration</artifactId>
+        <version>0.14.0</version>
+        <configuration>
+          <resolver>p2</resolver>
+          <ignoreTychoRepositories>true</ignoreTychoRepositories>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <pluginRepositories>
+    <pluginRepository>
+      <id>eclipse</id>
+      <url>http://download.eclipse.org/releases/indigo</url>
+      <layout>p2</layout>
+    </pluginRepository>
+    <pluginRepository>
+      <id>m2e</id>
+      <url>http://repository.sonatype.org/content/repositories/forge-sites/m2e/1.1.0/N/LATEST/</url>
+      <layout>p2</layout>
+    </pluginRepository>
+    <pluginRepository>
+      <id>rso</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+    </pluginRepository>
+  </pluginRepositories>
+  <repositories>
+    <repository>
+      <id>eclipse</id>
+      <url>http://download.eclipse.org/releases/indigo</url>
+      <layout>p2</layout>
+    </repository>
+    <repository>
+      <id>m2e</id>
+      <url>http://repository.sonatype.org/content/repositories/forge-sites/m2e/1.1.0/N/LATEST/</url>
+      <layout>p2</layout>
+    </repository>
+    <repository>
+      <id>rso</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+    </repository>
+  </repositories>
+</project>
\ No newline at end of file
diff --git a/lightning-maven-integration-test/pom.xml b/lightning-maven-integration-test/pom.xml
new file mode 100644
index 0000000..e2ad728
--- /dev/null
+++ b/lightning-maven-integration-test/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-maven-integration-test</artifactId>
+  <name>Lightning: Maven Integration Test</name>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-api</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.directmemory.lightning</groupId>
+        <artifactId>lightning-maven-plugin</artifactId>
+        <version>${project.version}</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate</goal>
+            </goals>
+            <phase>process-classes</phase>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/Foo.java b/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/Foo.java
new file mode 100644
index 0000000..20ef0d5
--- /dev/null
+++ b/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/Foo.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven.integration;
+
+import org.apache.directmemory.lightning.metadata.Attribute;
+
+public class Foo
+{
+
+    @Attribute
+    private String foo;
+
+    @Attribute
+    private int bar;
+
+    public String getFoo()
+    {
+        return foo;
+    }
+
+    public void setFoo( String foo )
+    {
+        this.foo = foo;
+    }
+
+    public int getBar()
+    {
+        return bar;
+    }
+
+    public void setBar( int bar )
+    {
+        this.bar = bar;
+    }
+}
diff --git a/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/FooSerializerDefinition.java b/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/FooSerializerDefinition.java
new file mode 100644
index 0000000..3d48946
--- /dev/null
+++ b/lightning-maven-integration-test/src/main/java/org/apache/directmemory/lightning/maven/integration/FooSerializerDefinition.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven.integration;
+
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+
+public class FooSerializerDefinition
+    extends AbstractSerializerDefinition
+{
+
+    @Override
+    protected void configure()
+    {
+        serialize( Foo.class ).attributes();
+    }
+}
diff --git a/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/MavenGeneratorTestCase.java b/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/MavenGeneratorTestCase.java
new file mode 100644
index 0000000..22fe2e9
--- /dev/null
+++ b/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/MavenGeneratorTestCase.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven.integration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.nio.charset.Charset;
+
+import org.junit.Test;
+
+public class MavenGeneratorTestCase
+{
+
+    @Test
+    public void testGeneration()
+        throws Exception
+    {
+        File target = new File( "target/classes" );
+        assertTrue( recursiveSearchClassFile( "FooLightningGeneratedMarshaller.class", target ) );
+
+        File testfile = new File( getClass().getClassLoader().getResource( "generated.java.out" ).toURI() );
+        File generatedFile =
+            new File(
+                      "target/generated-sources/lightning/org/apache/directmemory/lightning/maven/integration/FooLightningGeneratedMarshaller.java" );
+        String expected = SupportUtil.readAllText( testfile, Charset.forName( "UTF-8" ) );
+        String result = SupportUtil.readAllText( generatedFile, Charset.forName( "UTF-8" ) );
+        assertEquals( expected, result );
+    }
+
+    private boolean recursiveSearchClassFile( String classFile, File path )
+    {
+        if ( path.isFile() && path.getName().equals( classFile ) )
+        {
+            return true;
+        }
+
+        if ( path.isDirectory() )
+        {
+            for ( File childPath : path.listFiles() )
+            {
+                if ( recursiveSearchClassFile( classFile, childPath ) )
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/SupportUtil.java b/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/SupportUtil.java
new file mode 100644
index 0000000..4b97d52
--- /dev/null
+++ b/lightning-maven-integration-test/src/test/java/org/apache/directmemory/lightning/maven/integration/SupportUtil.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven.integration;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class SupportUtil
+{
+
+    private SupportUtil()
+    {
+    }
+
+    public static List<File> recursiveGetAllJavaSources( File file, ArrayList<File> list, FileFilter fileFilter )
+    {
+        if ( file.isDirectory() )
+        {
+            for ( File f : file.listFiles( fileFilter ) )
+            {
+                recursiveGetAllJavaSources( f, list, fileFilter );
+            }
+        }
+        else
+        {
+            list.add( file );
+        }
+        return list;
+    }
+
+    public static String readAllText( File file, Charset charset )
+    {
+        try
+        {
+            StringBuilder sb = new StringBuilder();
+            LineNumberReader reader = new LineNumberReader( new FileReader( file ) );
+            String line = null;
+            while ( ( line = reader.readLine() ) != null )
+            {
+                sb.append( line );
+            }
+            return sb.toString();
+        }
+        catch ( IOException e )
+        {
+            return null;
+        }
+    }
+}
diff --git a/lightning-maven-integration-test/src/test/resources/generated.java.out b/lightning-maven-integration-test/src/test/resources/generated.java.out
new file mode 100644
index 0000000..47a9847
--- /dev/null
+++ b/lightning-maven-integration-test/src/test/resources/generated.java.out
@@ -0,0 +1,91 @@
+
+package org.apache.directmemory.lightning.maven.integration;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.internal.generator.AbstractGeneratedMarshaller;
+import org.apache.directmemory.lightning.metadata.ValuePropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public final class FooLightningGeneratedMarshaller extends AbstractGeneratedMarshaller {
+
+	private final PropertyDescriptor DESCRIPTOR_BAR_LIGHTNING;
+	private final Marshaller MARSHALLER_BAR_LIGHTNING;
+	private final ValuePropertyAccessor ACCESSOR_BAR_LIGHTNING;
+	private final PropertyDescriptor DESCRIPTOR_FOO_LIGHTNING;
+	private final Marshaller MARSHALLER_FOO_LIGHTNING;
+	private final ValuePropertyAccessor ACCESSOR_FOO_LIGHTNING;
+
+	public FooLightningGeneratedMarshaller (Class<?> marshalledType, Map<Class<?>, Marshaller> marshallers,
+		ClassDescriptorAwareSerializer serializer, ObjectInstantiatorFactory objectInstantiatorFactory,
+		List<PropertyDescriptor> propertyDescriptors) {
+		
+		super(marshalledType, marshallers, serializer, objectInstantiatorFactory);
+		DESCRIPTOR_BAR_LIGHTNING = propertyDescriptors.get(0);
+		
+		PropertyDescriptor bar = findPropertyDescriptor("bar", propertyDescriptors);
+		Marshaller barMarshaller = bar.getMarshaller();
+		if (barMarshaller == null) {
+			barMarshaller = findMarshaller(bar);
+		}
+		MARSHALLER_BAR_LIGHTNING = barMarshaller;
+
+		ACCESSOR_BAR_LIGHTNING = (ValuePropertyAccessor) getPropertyAccessor("bar");
+		DESCRIPTOR_FOO_LIGHTNING = propertyDescriptors.get(1);
+		
+		PropertyDescriptor foo = findPropertyDescriptor("foo", propertyDescriptors);
+		Marshaller fooMarshaller = foo.getMarshaller();
+		if (fooMarshaller == null) {
+			fooMarshaller = findMarshaller(foo);
+		}
+		MARSHALLER_FOO_LIGHTNING = fooMarshaller;
+
+		ACCESSOR_FOO_LIGHTNING = (ValuePropertyAccessor) getPropertyAccessor("foo");
+	}
+	
+	public void marshall(Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput, SerializationContext serializationContext) throws IOException {
+		if (isAlreadyMarshalled(value, propertyDescriptor.getType(), dataOutput, serializationContext)) {
+			return;
+		}
+
+		ValuePropertyAccessor barPropertyAccessor = this.ACCESSOR_BAR_LIGHTNING;
+		PropertyDescriptor barPropertyDescriptor = this.DESCRIPTOR_BAR_LIGHTNING;
+		this.MARSHALLER_BAR_LIGHTNING.marshall(Integer.valueOf(barPropertyAccessor.readInt(value)), barPropertyDescriptor, dataOutput, serializationContext);
+
+		ValuePropertyAccessor fooPropertyAccessor = this.ACCESSOR_FOO_LIGHTNING;
+		PropertyDescriptor fooPropertyDescriptor = this.DESCRIPTOR_FOO_LIGHTNING;
+		this.MARSHALLER_FOO_LIGHTNING.marshall(fooPropertyAccessor.readObject(value), fooPropertyDescriptor, dataOutput, serializationContext);
+
+	}
+	
+	public <V> V unmarshall(V instance, PropertyDescriptor propertyDescriptor, DataInput dataInput, SerializationContext serializationContext) throws IOException {
+		ValuePropertyAccessor barPropertyAccessor = this.ACCESSOR_BAR_LIGHTNING;
+		PropertyDescriptor barPropertyDescriptor = this.DESCRIPTOR_BAR_LIGHTNING;
+		Object barValue = this.MARSHALLER_BAR_LIGHTNING.unmarshall(barPropertyDescriptor, dataInput, serializationContext);
+		barPropertyAccessor.writeInt(instance, ((Integer) barValue).intValue());
+
+		ValuePropertyAccessor fooPropertyAccessor = this.ACCESSOR_FOO_LIGHTNING;
+		PropertyDescriptor fooPropertyDescriptor = this.DESCRIPTOR_FOO_LIGHTNING;
+		Object fooValue = this.MARSHALLER_FOO_LIGHTNING.unmarshall(fooPropertyDescriptor, dataInput, serializationContext);
+		fooPropertyAccessor.writeObject(instance, fooValue);
+
+		return instance;
+	}
+	
+	private PropertyDescriptor findPropertyDescriptor(String propertyName, List<PropertyDescriptor> propertyDescriptors) {
+		for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+			if (propertyDescriptor.getPropertyName().equals(propertyName)) {
+				return propertyDescriptor;
+			}
+		}
+		return null;
+	}
+}
diff --git a/lightning-maven-plugin/pom.xml b/lightning-maven-plugin/pom.xml
new file mode 100644
index 0000000..c8615a6
--- /dev/null
+++ b/lightning-maven-plugin/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>lightning-maven-plugin</artifactId>
+  <name>Lightning: Maven Plugin</name>
+  <packaging>maven-plugin</packaging>
+
+  <parent>
+    <artifactId>lightning-reactor</artifactId>
+    <groupId>org.apache.directmemory.lightning</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-api</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>lightning-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-model</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-compiler-api</artifactId>
+      <version>1.8.1</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.codehaus.plexus</groupId>
+          <artifactId>plexus-component-api</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-compiler-manager</artifactId>
+      <version>1.8.1</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.codehaus.plexus</groupId>
+          <artifactId>plexus-component-api</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-compiler-javac</artifactId>
+      <version>1.8.1</version>
+      <scope>runtime</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.codehaus.plexus</groupId>
+          <artifactId>plexus-component-api</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven.plugin-testing</groupId>
+      <artifactId>maven-plugin-testing-harness</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+  </build>
+</project>
\ No newline at end of file
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/AbstractCompilerMojo.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/AbstractCompilerMojo.java
new file mode 100644
index 0000000..e2502cb
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/AbstractCompilerMojo.java
@@ -0,0 +1,786 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.toolchain.Toolchain;
+import org.apache.maven.toolchain.ToolchainManager;
+import org.codehaus.plexus.compiler.Compiler;
+import org.codehaus.plexus.compiler.CompilerConfiguration;
+import org.codehaus.plexus.compiler.CompilerError;
+import org.codehaus.plexus.compiler.CompilerException;
+import org.codehaus.plexus.compiler.CompilerOutputStyle;
+import org.codehaus.plexus.compiler.manager.CompilerManager;
+import org.codehaus.plexus.compiler.manager.NoSuchCompilerException;
+import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
+import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
+import org.codehaus.plexus.compiler.util.scan.mapping.SingleTargetSourceMapping;
+import org.codehaus.plexus.compiler.util.scan.mapping.SourceMapping;
+import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * TODO: At least one step could be optimized, currently the plugin will do two scans of all the source code if the
+ * compiler has to have the entire set of sources. This is currently the case for at least the C# compiler and most
+ * likely all the other .NET compilers too.
+ * 
+ * @author others
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id$
+ * @since 2.0
+ */
+public abstract class AbstractCompilerMojo
+    extends AbstractMojo
+{
+
+    // ----------------------------------------------------------------------
+    // Configurables
+    // ----------------------------------------------------------------------
+
+    /**
+     * Indicates whether the build will continue even if there are compilation errors; defaults to true.
+     * 
+     * @parameter expression="${maven.compiler.failOnError}" default-value="true"
+     * @since 2.0.2
+     */
+    private boolean failOnError = true;
+
+    /**
+     * Set to true to include debugging information in the compiled class files.
+     * 
+     * @parameter expression="${maven.compiler.debug}" default-value="true"
+     */
+    private boolean debug = true;
+
+    /**
+     * Set to true to show messages about what the compiler is doing.
+     * 
+     * @parameter expression="${maven.compiler.verbose}" default-value="false"
+     */
+    private boolean verbose;
+
+    /**
+     * Sets whether to show source locations where deprecated APIs are used.
+     * 
+     * @parameter expression="${maven.compiler.showDeprecation}" default-value="false"
+     */
+    private boolean showDeprecation;
+
+    /**
+     * Set to true to optimize the compiled code using the compiler's optimization methods.
+     * 
+     * @parameter expression="${maven.compiler.optimize}" default-value="false"
+     */
+    private boolean optimize;
+
+    /**
+     * Set to true to show compilation warnings.
+     * 
+     * @parameter expression="${maven.compiler.showWarnings}" default-value="false"
+     */
+    private boolean showWarnings;
+
+    /**
+     * The -source argument for the Java compiler.
+     * 
+     * @parameter expression="${maven.compiler.source}" default-value="1.5"
+     */
+    protected String source;
+
+    /**
+     * The -target argument for the Java compiler.
+     * 
+     * @parameter expression="${maven.compiler.target}" default-value="1.5"
+     */
+    protected String target;
+
+    /**
+     * The -encoding argument for the Java compiler.
+     * 
+     * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
+     */
+    protected String encoding;
+
+    /**
+     * Sets the granularity in milliseconds of the last modification date for testing whether a source needs
+     * recompilation.
+     * 
+     * @parameter expression="${lastModGranularityMs}" default-value="0"
+     */
+    private int staleMillis;
+
+    /**
+     * The compiler id of the compiler to use. See this <a href="non-javac-compilers.html">guide</a> for more
+     * information.
+     * 
+     * @parameter expression="${maven.compiler.compilerId}" default-value="javac"
+     */
+    private String compilerId;
+
+    /**
+     * Version of the compiler to use, ex. "1.3", "1.5", if fork is set to true.
+     * 
+     * @parameter expression="${maven.compiler.compilerVersion}"
+     */
+    private String compilerVersion;
+
+    /**
+     * Allows running the compiler in a separate process. If "false" it uses the built in compiler, while if "true" it
+     * will use an executable.
+     * 
+     * @parameter expression="${maven.compiler.fork}" default-value="false"
+     */
+    private boolean fork;
+
+    /**
+     * Initial size, in megabytes, of the memory allocation pool, ex. "64", "64m" if fork is set to true.
+     * 
+     * @parameter expression="${maven.compiler.meminitial}"
+     * @since 2.0.1
+     */
+    private String meminitial;
+
+    /**
+     * Sets the maximum size, in megabytes, of the memory allocation pool, ex. "128", "128m" if fork is set to true.
+     * 
+     * @parameter expression="${maven.compiler.maxmem}"
+     * @since 2.0.1
+     */
+    private String maxmem;
+
+    /**
+     * Sets the executable of the compiler to use when fork is true.
+     * 
+     * @parameter expression="${maven.compiler.executable}"
+     */
+    private String executable;
+
+    /**
+     * <p>
+     * Sets whether annotation processing is performed or not. Only applies to JDK 1.6+ If not set, both compilation and
+     * annotation processing are performed at the same time.
+     * </p>
+     * <p>
+     * Allowed values are: none - no annotation processing is performed. only - only annotation processing is done, no
+     * compilation.
+     * </p>
+     * 
+     * @parameter
+     * @since 2.2
+     */
+    private String proc;
+
+    /**
+     * <p>
+     * Names of annotation processors to run. Only applies to JDK 1.6+ If not set, the default annotation processors
+     * discovery process applies.
+     * </p>
+     * 
+     * @parameter
+     * @since 2.2
+     */
+    private String[] annotationProcessors;
+
+    /**
+     * <p>
+     * Sets the arguments to be passed to the compiler (prepending a dash) if fork is set to true.
+     * </p>
+     * <p>
+     * This is because the list of valid arguments passed to a Java compiler varies based on the compiler version.
+     * </p>
+     * 
+     * @parameter
+     * @since 2.0.1
+     */
+    protected Map<String, String> compilerArguments;
+
+    /**
+     * <p>
+     * Sets the unformatted argument string to be passed to the compiler if fork is set to true.
+     * </p>
+     * <p>
+     * This is because the list of valid arguments passed to a Java compiler varies based on the compiler version.
+     * </p>
+     * 
+     * @parameter
+     */
+    protected String compilerArgument;
+
+    /**
+     * Sets the name of the output file when compiling a set of sources to a single file.
+     * 
+     * @parameter expression="${project.build.finalName}"
+     */
+    private String outputFileName;
+
+    /**
+     * Keyword list to be appended to the -g command-line switch. Legal values are none or a comma-separated list of the
+     * following keywords: lines, vars, and source. If debuglevel is not specified, by default, nothing will be appended
+     * to -g. If debug is not turned on, this attribute will be ignored.
+     * 
+     * @parameter expression="${maven.compiler.debuglevel}"
+     * @since 2.1
+     */
+    private String debuglevel;
+
+    /** @component */
+    private ToolchainManager toolchainManager;
+
+    // ----------------------------------------------------------------------
+    // Read-only parameters
+    // ----------------------------------------------------------------------
+
+    /**
+     * The directory to run the compiler from if fork is true.
+     * 
+     * @parameter default-value="${basedir}"
+     * @required
+     * @readonly
+     */
+    private File basedir;
+
+    /**
+     * The target directory of the compiler if fork is true.
+     * 
+     * @parameter default-value="${project.build.directory}"
+     * @required
+     * @readonly
+     */
+    private File buildDirectory;
+
+    /**
+     * Plexus compiler manager.
+     * 
+     * @component
+     */
+    private CompilerManager compilerManager;
+
+    /**
+     * The current build session instance. This is used for toolchain manager API calls.
+     * 
+     * @parameter default-value="${session}"
+     * @required
+     * @readonly
+     */
+    private MavenSession session;
+
+    protected abstract SourceInclusionScanner getSourceInclusionScanner( int staleMillis );
+
+    protected abstract SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding );
+
+    protected abstract List<String> getClasspathElements();
+
+    protected abstract List<String> getCompileSourceRoots();
+
+    protected abstract File getOutputDirectory();
+
+    protected abstract String getSource();
+
+    protected abstract String getTarget();
+
+    protected abstract String getCompilerArgument();
+
+    protected abstract Map<String, String> getCompilerArguments();
+
+    protected abstract File getGeneratedSourcesDirectory();
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public void execute()
+        throws MojoExecutionException, CompilationFailureException
+    {
+        // ----------------------------------------------------------------------
+        // Look up the compiler. This is done before other code than can
+        // cause the mojo to return before the lookup is done possibly resulting
+        // in misconfigured POMs still building.
+        // ----------------------------------------------------------------------
+
+        Compiler compiler;
+
+        getLog().debug( "Using compiler '" + compilerId + "'." );
+
+        try
+        {
+            compiler = compilerManager.getCompiler( compilerId );
+        }
+        catch ( NoSuchCompilerException e )
+        {
+            throw new MojoExecutionException( "No such compiler '" + e.getCompilerId() + "'." );
+        }
+
+        // -----------toolchains start here ----------------------------------
+        // use the compilerId as identifier for toolchains as well.
+        Toolchain tc = getToolchain();
+        if ( tc != null )
+        {
+            getLog().info( "Toolchain in compiler-plugin: " + tc );
+            if ( executable != null )
+            {
+                getLog().warn( "Toolchains are ignored, 'executable' parameter is set to " + executable );
+            }
+            else
+            {
+                fork = true;
+                // TODO somehow shaky dependency between compilerId and tool
+                // executable.
+                executable = tc.findTool( compilerId );
+            }
+        }
+        // ----------------------------------------------------------------------
+        //
+        // ----------------------------------------------------------------------
+
+        List<String> compileSourceRoots = removeEmptyCompileSourceRoots( getCompileSourceRoots() );
+
+        if ( compileSourceRoots.isEmpty() )
+        {
+            getLog().info( "No sources to compile" );
+
+            return;
+        }
+
+        if ( getLog().isDebugEnabled() )
+        {
+            getLog().debug( "Source directories: " + compileSourceRoots.toString().replace( ',', '\n' ) );
+            getLog().debug( "Classpath: " + getClasspathElements().toString().replace( ',', '\n' ) );
+            getLog().debug( "Output directory: " + getOutputDirectory() );
+        }
+
+        // ----------------------------------------------------------------------
+        // Create the compiler configuration
+        // ----------------------------------------------------------------------
+
+        CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
+
+        compilerConfiguration.setOutputLocation( getOutputDirectory().getAbsolutePath() );
+
+        compilerConfiguration.setClasspathEntries( getClasspathElements() );
+
+        compilerConfiguration.setSourceLocations( compileSourceRoots );
+
+        compilerConfiguration.setOptimize( optimize );
+
+        compilerConfiguration.setDebug( debug );
+
+        if ( debug && StringUtils.isNotEmpty( debuglevel ) )
+        {
+            String[] split = StringUtils.split( debuglevel, "," );
+            for ( int i = 0; i < split.length; i++ )
+            {
+                if ( !( split[i].equalsIgnoreCase( "none" ) || split[i].equalsIgnoreCase( "lines" )
+                    || split[i].equalsIgnoreCase( "vars" ) || split[i].equalsIgnoreCase( "source" ) ) )
+                {
+                    throw new IllegalArgumentException( "The specified debug level: '" + split[i]
+                        + "' is unsupported. " + "Legal values are 'none', 'lines', 'vars', and 'source'." );
+                }
+            }
+            compilerConfiguration.setDebugLevel( debuglevel );
+        }
+
+        compilerConfiguration.setVerbose( verbose );
+
+        compilerConfiguration.setShowWarnings( showWarnings );
+
+        compilerConfiguration.setShowDeprecation( showDeprecation );
+
+        compilerConfiguration.setSourceVersion( getSource() );
+
+        compilerConfiguration.setTargetVersion( getTarget() );
+
+        compilerConfiguration.setProc( proc );
+
+        compilerConfiguration.setGeneratedSourcesDirectory( getGeneratedSourcesDirectory() );
+
+        compilerConfiguration.setAnnotationProcessors( annotationProcessors );
+
+        compilerConfiguration.setSourceEncoding( encoding );
+
+        Map<String, String> effectiveCompilerArguments = getCompilerArguments();
+
+        String effectiveCompilerArgument = getCompilerArgument();
+
+        if ( ( effectiveCompilerArguments != null ) || ( effectiveCompilerArgument != null ) )
+        {
+            LinkedHashMap<String, String> cplrArgsCopy = new LinkedHashMap<String, String>();
+            if ( effectiveCompilerArguments != null )
+            {
+                for ( Map.Entry<String, String> me : effectiveCompilerArguments.entrySet() )
+                {
+                    String key = me.getKey();
+                    String value = me.getValue();
+                    if ( !key.startsWith( "-" ) )
+                    {
+                        key = "-" + key;
+                    }
+                    cplrArgsCopy.put( key, value );
+                }
+            }
+            if ( !StringUtils.isEmpty( effectiveCompilerArgument ) )
+            {
+                cplrArgsCopy.put( effectiveCompilerArgument, null );
+            }
+            compilerConfiguration.setCustomCompilerArguments( cplrArgsCopy );
+        }
+
+        compilerConfiguration.setFork( fork );
+
+        if ( fork )
+        {
+            if ( !StringUtils.isEmpty( meminitial ) )
+            {
+                String value = getMemoryValue( meminitial );
+
+                if ( value != null )
+                {
+                    compilerConfiguration.setMeminitial( value );
+                }
+                else
+                {
+                    getLog().info( "Invalid value for meminitial '" + meminitial + "'. Ignoring this option." );
+                }
+            }
+
+            if ( !StringUtils.isEmpty( maxmem ) )
+            {
+                String value = getMemoryValue( maxmem );
+
+                if ( value != null )
+                {
+                    compilerConfiguration.setMaxmem( value );
+                }
+                else
+                {
+                    getLog().info( "Invalid value for maxmem '" + maxmem + "'. Ignoring this option." );
+                }
+            }
+        }
+
+        compilerConfiguration.setExecutable( executable );
+
+        compilerConfiguration.setWorkingDirectory( basedir );
+
+        compilerConfiguration.setCompilerVersion( compilerVersion );
+
+        compilerConfiguration.setBuildDirectory( buildDirectory );
+
+        compilerConfiguration.setOutputFileName( outputFileName );
+
+        // TODO: have an option to always compile (without need to clean)
+        Set<File> staleSources;
+
+        boolean canUpdateTarget;
+
+        try
+        {
+            staleSources =
+                computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( staleMillis ) );
+
+            canUpdateTarget = compiler.canUpdateTarget( compilerConfiguration );
+
+            if ( compiler.getCompilerOutputStyle().equals( CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
+                && !canUpdateTarget )
+            {
+                getLog().info( "RESCANNING!" );
+                // TODO: This second scan for source files is sub-optimal
+                String inputFileEnding = compiler.getInputFileEnding( compilerConfiguration );
+
+                Set<File> sources =
+                    computeStaleSources( compilerConfiguration, compiler, getSourceInclusionScanner( inputFileEnding ) );
+
+                compilerConfiguration.setSourceFiles( sources );
+            }
+            else
+            {
+                compilerConfiguration.setSourceFiles( staleSources );
+            }
+        }
+        catch ( CompilerException e )
+        {
+            throw new MojoExecutionException( "Error while computing stale sources.", e );
+        }
+
+        if ( staleSources.isEmpty() )
+        {
+            getLog().info( "Nothing to compile - all classes are up to date" );
+
+            return;
+        }
+
+        // ----------------------------------------------------------------------
+        // Dump configuration
+        // ----------------------------------------------------------------------
+
+        if ( getLog().isDebugEnabled() )
+        {
+            getLog().debug( "Classpath:" );
+
+            for ( String s : getClasspathElements() )
+            {
+                getLog().debug( " " + s );
+            }
+
+            getLog().debug( "Source roots:" );
+
+            for ( String root : getCompileSourceRoots() )
+            {
+                getLog().debug( " " + root );
+            }
+
+            try
+            {
+                if ( fork )
+                {
+                    if ( compilerConfiguration.getExecutable() != null )
+                    {
+                        getLog().debug( "Excutable: " );
+                        getLog().debug( " " + compilerConfiguration.getExecutable() );
+                    }
+                }
+
+                String[] cl = compiler.createCommandLine( compilerConfiguration );
+                if ( cl != null && cl.length > 0 )
+                {
+                    StringBuffer sb = new StringBuffer();
+                    sb.append( cl[0] );
+                    for ( int i = 1; i < cl.length; i++ )
+                    {
+                        sb.append( " " );
+                        sb.append( cl[i] );
+                    }
+                    getLog().debug( "Command line options:" );
+                    getLog().debug( sb );
+                }
+            }
+            catch ( CompilerException ce )
+            {
+                getLog().debug( ce );
+            }
+        }
+
+        // ----------------------------------------------------------------------
+        // Compile!
+        // ----------------------------------------------------------------------
+
+        if ( StringUtils.isEmpty( compilerConfiguration.getSourceEncoding() ) )
+        {
+            getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
+                               + ", i.e. build is platform dependent!" );
+        }
+
+        List<CompilerError> messages;
+
+        try
+        {
+            messages = compiler.compile( compilerConfiguration );
+        }
+        catch ( Exception e )
+        {
+            // TODO: don't catch Exception
+            throw new MojoExecutionException( "Fatal error compiling", e );
+        }
+
+        List<CompilerError> warnings = new ArrayList<CompilerError>();
+        List<CompilerError> errors = new ArrayList<CompilerError>();
+        if ( messages != null )
+        {
+            for ( CompilerError message : messages )
+            {
+                if ( message.isError() )
+                {
+                    errors.add( message );
+                }
+                else
+                {
+                    warnings.add( message );
+                }
+            }
+        }
+
+        if ( failOnError && !errors.isEmpty() )
+        {
+            if ( !warnings.isEmpty() )
+            {
+                getLog().info( "-------------------------------------------------------------" );
+                getLog().warn( "COMPILATION WARNING : " );
+                getLog().info( "-------------------------------------------------------------" );
+                for ( CompilerError warning : warnings )
+                {
+                    getLog().warn( warning.toString() );
+                }
+                getLog().info( warnings.size() + ( ( warnings.size() > 1 ) ? " warnings " : " warning" ) );
+                getLog().info( "-------------------------------------------------------------" );
+            }
+
+            getLog().info( "-------------------------------------------------------------" );
+            getLog().error( "COMPILATION ERROR : " );
+            getLog().info( "-------------------------------------------------------------" );
+
+            for ( CompilerError error : errors )
+            {
+                getLog().error( error.toString() );
+            }
+            getLog().info( errors.size() + ( ( errors.size() > 1 ) ? " errors " : " error" ) );
+            getLog().info( "-------------------------------------------------------------" );
+
+            throw new CompilationFailureException( errors );
+        }
+        else
+        {
+            for ( CompilerError message : messages )
+            {
+                getLog().warn( message.toString() );
+            }
+        }
+    }
+
+    private String getMemoryValue( String setting )
+    {
+        String value = null;
+
+        // Allow '128' or '128m'
+        if ( isDigits( setting ) )
+        {
+            value = setting + "m";
+        }
+        else
+        {
+            if ( ( isDigits( setting.substring( 0, setting.length() - 1 ) ) )
+                && ( setting.toLowerCase().endsWith( "m" ) ) )
+            {
+                value = setting;
+            }
+        }
+        return value;
+    }
+
+    // TODO remove the part with ToolchainManager lookup once we depend on
+    // 3.0.9 (have it as prerequisite). Define as regular component field then.
+    private Toolchain getToolchain()
+    {
+        Toolchain tc = null;
+        if ( toolchainManager != null )
+        {
+            tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
+        }
+        return tc;
+    }
+
+    private boolean isDigits( String string )
+    {
+        for ( int i = 0; i < string.length(); i++ )
+        {
+            if ( !Character.isDigit( string.charAt( i ) ) )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    private Set<File> computeStaleSources( CompilerConfiguration compilerConfiguration, Compiler compiler,
+                                           SourceInclusionScanner scanner )
+        throws MojoExecutionException, CompilerException
+    {
+        CompilerOutputStyle outputStyle = compiler.getCompilerOutputStyle();
+
+        SourceMapping mapping;
+
+        File outputDirectory;
+
+        if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE )
+        {
+            mapping =
+                new SuffixMapping( compiler.getInputFileEnding( compilerConfiguration ),
+                                   compiler.getOutputFileEnding( compilerConfiguration ) );
+
+            outputDirectory = getOutputDirectory();
+        }
+        else if ( outputStyle == CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES )
+        {
+            mapping =
+                new SingleTargetSourceMapping( compiler.getInputFileEnding( compilerConfiguration ),
+                                               compiler.getOutputFile( compilerConfiguration ) );
+
+            outputDirectory = buildDirectory;
+        }
+        else
+        {
+            throw new MojoExecutionException( "Unknown compiler output style: '" + outputStyle + "'." );
+        }
+
+        scanner.addSourceMapping( mapping );
+
+        Set<File> staleSources = new HashSet<File>();
+
+        for ( String sourceRoot : getCompileSourceRoots() )
+        {
+            File rootFile = new File( sourceRoot );
+
+            if ( !rootFile.isDirectory() )
+            {
+                continue;
+            }
+
+            try
+            {
+                staleSources.addAll( scanner.getIncludedSources( rootFile, outputDirectory ) );
+            }
+            catch ( InclusionScanException e )
+            {
+                throw new MojoExecutionException( "Error scanning source root: \'" + sourceRoot + "\' "
+                    + "for stale files to recompile.", e );
+            }
+        }
+
+        return staleSources;
+    }
+
+    /**
+     * @todo also in ant plugin. This should be resolved at some point so that it does not need to be calculated
+     *       continuously - or should the plugins accept empty source roots as is?
+     */
+    private static List<String> removeEmptyCompileSourceRoots( List<String> compileSourceRootsList )
+    {
+        List<String> newCompileSourceRootsList = new ArrayList<String>();
+        if ( compileSourceRootsList != null )
+        {
+            // copy as I may be modifying it
+            for ( String srcDir : compileSourceRootsList )
+            {
+                if ( !newCompileSourceRootsList.contains( srcDir ) && new File( srcDir ).exists() )
+                {
+                    newCompileSourceRootsList.add( srcDir );
+                }
+            }
+        }
+        return newCompileSourceRootsList;
+    }
+}
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/CompilationFailureException.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/CompilationFailureException.java
new file mode 100644
index 0000000..5e08b7c
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/CompilationFailureException.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.compiler.CompilerError;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id$
+ * @since 2.0
+ */
+@SuppressWarnings( "serial" )
+public class CompilationFailureException
+    extends MojoFailureException
+{
+
+    private static final String LS = System.getProperty( "line.separator" );
+
+    public CompilationFailureException( List<CompilerError> messages )
+    {
+        super( null, shortMessage( messages ), longMessage( messages ) );
+    }
+
+    public static String longMessage( List<CompilerError> messages )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        if ( messages != null )
+        {
+            for ( CompilerError compilerError : messages )
+            {
+                sb.append( compilerError ).append( LS );
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Short message will have the error message if there's only one, useful for errors forking the compiler
+     * 
+     * @param messages
+     * @return the short error message
+     * @since 2.0.2
+     */
+    public static String shortMessage( List<CompilerError> messages )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append( "Compilation failure" );
+
+        if ( messages.size() == 1 )
+        {
+            sb.append( LS );
+
+            CompilerError compilerError = messages.get( 0 );
+
+            sb.append( compilerError ).append( LS );
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/LightningGeneratorMojo.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/LightningGeneratorMojo.java
new file mode 100644
index 0000000..cb24af4
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/LightningGeneratorMojo.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.tools.SimpleJavaFileObject;
+
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.Serializer;
+import org.apache.directmemory.lightning.base.AbstractSerializerDefinition;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.logging.LogLevel;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner;
+import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner;
+import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner;
+
+/**
+ * Generates sourcecode of native marshallers for Lightning {@link Serializer} by exploring all source
+ * {@link SerializerDefinition} files.
+ * 
+ * @goal generate
+ * @lifecycle process-classes
+ * @phase process-classes
+ * @execute phase="process-classes"
+ * @execute goal="process-classes:generate"
+ * @requiresDependencyResolution compile
+ * @requiresProject true
+ * @threadSafe true
+ */
+public class LightningGeneratorMojo
+    extends AbstractCompilerMojo
+{
+
+    /**
+     * The current build session instance. This is used for toolchain manager API calls.
+     * 
+     * @parameter default-value="${session}"
+     * @required
+     * @readonly
+     */
+    private MavenSession session;
+
+    /**
+     * The java generated-source directory.
+     * 
+     * @parameter default-value= "${project.build.directory}/generated-sources/lightning"
+     */
+    private File generatedSourceDirectory;
+
+    /**
+     * The directory where compiled classes resist.
+     * 
+     * @parameter default-value="${project.build.directory}/classes"
+     */
+    private File targetBuildDirectory;
+
+    /**
+     * Project classpath.
+     * 
+     * @parameter default-value="${project.compileClasspathElements}"
+     * @required
+     * @readonly
+     */
+    private List<String> classpathElements;
+
+    /**
+     * The generator strategy.
+     * 
+     * @parameter default-value="speed"
+     */
+    private String strategy;
+
+    @Override
+    public void execute()
+        throws MojoExecutionException, CompilationFailureException
+    {
+        if ( encoding == null )
+        {
+            encoding = "UTF-8";
+        }
+
+        SerializationStrategy serializationStrategy =
+            "size".equalsIgnoreCase( strategy ) ? SerializationStrategy.SizeOptimized
+                            : SerializationStrategy.SpeedOptimized;
+
+        MavenLoggerAdapter logger = new MavenLoggerAdapter( LightningGeneratorMojo.class.getCanonicalName() );
+        getLog().info( "Searching in path " + targetBuildDirectory.getAbsolutePath() );
+        List<File> files =
+            SupportUtil.recursiveGetAllJavaSources( targetBuildDirectory, new ArrayList<File>(), fileFilter );
+
+        List<URL> urlClasspathElements = new ArrayList<URL>();
+        if ( getClasspathElements() != null )
+        {
+            for ( String classpathElement : getClasspathElements() )
+            {
+                try
+                {
+                    URL url = new File( classpathElement ).toURI().toURL();
+                    urlClasspathElements.add( url );
+                }
+                catch ( Exception e )
+                {
+                    // Intentionally left blank
+                }
+            }
+        }
+        ClassLoader classLoader =
+            new URLClassLoader( urlClasspathElements.toArray( new URL[urlClasspathElements.size()] ),
+                                getClass().getClassLoader() );
+
+        for ( File file : files )
+        {
+            try
+            {
+                String className = file.getAbsolutePath().replace( targetBuildDirectory.getAbsolutePath(), "" );
+                if ( className.startsWith( "/" ) || className.startsWith( "\\" ) )
+                {
+                    className = className.substring( 1 );
+                }
+
+                className = className.replace( ".class", "" ).replace( "/", "." ).replace( "\\", "." );
+
+                getLog().debug( "Trying class " + className );
+                Class<?> clazz = classLoader.loadClass( className );
+                if ( AbstractSerializerDefinition.class.isAssignableFrom( clazz ) )
+                {
+                    getLog().debug( "Found SerializerDefinition in class " + className );
+
+                    AbstractSerializerDefinition definition = (AbstractSerializerDefinition) clazz.newInstance();
+
+                    SerializerDefinitionAnalyser analyser = new SerializerDefinitionAnalyser( logger );
+                    analyser.analyse( definition );
+                    analyser.build( generatedSourceDirectory, serializationStrategy, encoding );
+                }
+            }
+            catch ( Exception e )
+            {
+                logger.error( "Could not generate Lightning source for file " + file.getName(), e );
+            }
+        }
+
+        super.execute();
+
+        // session.getCurrentProject().addCompileSourceRoot(generatedSourceDirectory.getAbsolutePath());
+    }
+
+    @Override
+    protected SourceInclusionScanner getSourceInclusionScanner( int staleMillis )
+    {
+        return new StaleSourceScanner( staleMillis );
+    }
+
+    @Override
+    protected SourceInclusionScanner getSourceInclusionScanner( String inputFileEnding )
+    {
+        return new SimpleSourceInclusionScanner( Collections.singleton( "**/*.java" ), Collections.EMPTY_SET );
+    }
+
+    @Override
+    protected List<String> getClasspathElements()
+    {
+        return classpathElements;
+    }
+
+    @Override
+    protected List<String> getCompileSourceRoots()
+    {
+        return Collections.singletonList( generatedSourceDirectory.getAbsolutePath() );
+    }
+
+    @Override
+    protected File getOutputDirectory()
+    {
+        return targetBuildDirectory;
+    }
+
+    @Override
+    protected String getSource()
+    {
+        return source;
+    }
+
+    @Override
+    protected String getTarget()
+    {
+        return target;
+    }
+
+    @Override
+    protected String getCompilerArgument()
+    {
+        return compilerArgument;
+    }
+
+    @Override
+    protected Map<String, String> getCompilerArguments()
+    {
+        return compilerArguments;
+    }
+
+    @Override
+    protected File getGeneratedSourcesDirectory()
+    {
+        return generatedSourceDirectory;
+    }
+
+    private final FileFilter fileFilter = new FileFilter()
+    {
+
+        @Override
+        public boolean accept( File file )
+        {
+            return file.isDirectory() || file.getName().endsWith( ".class" );
+        }
+    };
+
+    private class FileObject
+        extends SimpleJavaFileObject
+    {
+
+        private final Charset charset;
+
+        private final File file;
+
+        private FileObject( File file, Charset charset )
+        {
+            super( file.toURI(), Kind.SOURCE );
+            this.charset = charset;
+            this.file = file;
+        }
+
+        @Override
+        public CharSequence getCharContent( boolean ignoreEncodingErrors )
+            throws IOException
+        {
+            return SupportUtil.readAllText( file, charset );
+        }
+    }
+
+    private class MavenLoggerAdapter
+        implements Logger
+    {
+
+        private final String name;
+
+        private MavenLoggerAdapter( String name )
+        {
+            this.name = name;
+        }
+
+        @Override
+        public Logger getChildLogger( Class<?> clazz )
+        {
+            return getChildLogger( clazz.getCanonicalName() );
+        }
+
+        @Override
+        public Logger getChildLogger( String name )
+        {
+            return new MavenLoggerAdapter( name );
+        }
+
+        @Override
+        public String getName()
+        {
+            return name;
+        }
+
+        @Override
+        public boolean isLogLevelEnabled( LogLevel logLevel )
+        {
+            if ( logLevel == LogLevel.Debug )
+            {
+                return getLog().isDebugEnabled();
+            }
+
+            if ( logLevel == LogLevel.Error )
+            {
+                return getLog().isErrorEnabled();
+            }
+
+            if ( logLevel == LogLevel.Fatal )
+            {
+                return getLog().isErrorEnabled();
+            }
+
+            if ( logLevel == LogLevel.Trace )
+            {
+                return getLog().isDebugEnabled();
+            }
+
+            if ( logLevel == LogLevel.Warn )
+            {
+                return getLog().isWarnEnabled();
+            }
+
+            return getLog().isInfoEnabled();
+        }
+
+        @Override
+        public boolean isTraceEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Trace );
+        }
+
+        @Override
+        public boolean isDebugEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Debug );
+        }
+
+        @Override
+        public boolean isInfoEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Info );
+        }
+
+        @Override
+        public boolean isWarnEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Warn );
+        }
+
+        @Override
+        public boolean isErrorEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Error );
+        }
+
+        @Override
+        public boolean isFatalEnabled()
+        {
+            return isLogLevelEnabled( LogLevel.Fatal );
+        }
+
+        @Override
+        public void trace( String message )
+        {
+            trace( message, null );
+        }
+
+        @Override
+        public void trace( String message, Throwable throwable )
+        {
+            debug( message, throwable );
+        }
+
+        @Override
+        public void debug( String message )
+        {
+            debug( message, null );
+        }
+
+        @Override
+        public void debug( String message, Throwable throwable )
+        {
+            getLog().debug( message, throwable );
+        }
+
+        @Override
+        public void info( String message )
+        {
+            info( message, null );
+        }
+
+        @Override
+        public void info( String message, Throwable throwable )
+        {
+            getLog().info( message, throwable );
+        }
+
+        @Override
+        public void warn( String message )
+        {
+            warn( message, null );
+        }
+
+        @Override
+        public void warn( String message, Throwable throwable )
+        {
+            getLog().warn( message, throwable );
+        }
+
+        @Override
+        public void error( String message )
+        {
+            error( message, null );
+        }
+
+        @Override
+        public void error( String message, Throwable throwable )
+        {
+            getLog().error( message, throwable );
+        }
+
+        @Override
+        public void fatal( String message )
+        {
+            fatal( message, null );
+        }
+
+        @Override
+        public void fatal( String message, Throwable throwable )
+        {
+            error( message, throwable );
+        }
+    }
+}
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SerializerDefinitionAnalyser.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SerializerDefinitionAnalyser.java
new file mode 100644
index 0000000..956b764
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SerializerDefinitionAnalyser.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.MarshallerStrategy;
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.configuration.SerializerDefinition;
+import org.apache.directmemory.lightning.generator.DefinitionBuildingContext;
+import org.apache.directmemory.lightning.generator.DefinitionVisitor;
+import org.apache.directmemory.lightning.generator.PropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.InternalClassDescriptor;
+import org.apache.directmemory.lightning.internal.InternalDefinitionBuildingContext;
+import org.apache.directmemory.lightning.internal.InternalMarshallerStrategy;
+import org.apache.directmemory.lightning.internal.beans.InternalPropertyDescriptorFactory;
+import org.apache.directmemory.lightning.internal.util.ClassUtil;
+import org.apache.directmemory.lightning.internal.util.TypeUtil;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.Attribute;
+import org.apache.directmemory.lightning.metadata.ClassDefinition;
+import org.apache.directmemory.lightning.metadata.ClassDescriptor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public class SerializerDefinitionAnalyser
+{
+
+    private final Logger logger;
+
+    private final Map<Class<?>, InternalClassDescriptor> classDescriptors =
+        new HashMap<Class<?>, InternalClassDescriptor>();
+
+    private final List<SerializerDefinition> serializerDefinitions = new ArrayList<SerializerDefinition>();
+
+    private final Map<Class<?>, Marshaller> marshallers = new HashMap<Class<?>, Marshaller>();
+
+    private Class<? extends Annotation> attributeAnnotation = Placeholder.class;
+
+    private final DefinitionVisitor definitionVisitor = new GeneratorDefinitionVisitor();
+
+    public SerializerDefinitionAnalyser( Logger logger )
+    {
+        this.logger = logger;
+    }
+
+    public void analyse( SerializerDefinition serializerDefinition )
+    {
+        PropertyDescriptorFactory propertyDescriptorFactory = new InternalPropertyDescriptorFactory( logger );
+        MarshallerStrategy marshallerStrategy = new InternalMarshallerStrategy();
+        DefinitionBuildingContext definitionBuildingContext =
+            new InternalDefinitionBuildingContext( marshallerStrategy, propertyDescriptorFactory );
+
+        serializerDefinition.configure( definitionBuildingContext, null );
+        serializerDefinition.acceptVisitor( definitionVisitor );
+    }
+
+    public List<File> build( File outputFolder, SerializationStrategy serializationStrategy, String encoding )
+    {
+        Charset charset = Charset.forName( encoding );
+
+        List<ClassDefinition> classDefinitions = new ArrayList<ClassDefinition>();
+        for ( InternalClassDescriptor classDescriptor : classDescriptors.values() )
+        {
+            classDefinitions.add( classDescriptor.build( ClassUtil.CLASS_DESCRIPTORS ).getClassDefinition() );
+        }
+
+        List<File> files = new ArrayList<File>();
+        for ( ClassDescriptor classDescriptor : classDescriptors.values() )
+        {
+            if ( classDescriptor instanceof InternalClassDescriptor && classDescriptor.getMarshaller() == null )
+            {
+                try
+                {
+                    SourceMarshallerGenerator generator = new SourceMarshallerGenerator( charset, logger );
+                    File sourceFile =
+                        generator.generateMarshaller( classDescriptor.getType(),
+                                                      classDescriptor.getPropertyDescriptors(), serializationStrategy,
+                                                      outputFolder );
+
+                    files.add( sourceFile );
+                }
+                catch ( IOException e )
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return files;
+    }
+
+    public List<SerializerDefinition> getVisitedSerializerDefinitions()
+    {
+        return serializerDefinitions;
+    }
+
+    private InternalClassDescriptor findClassDescriptor( Class<?> type )
+    {
+        InternalClassDescriptor classDescriptor = classDescriptors.get( type );
+        if ( classDescriptor == null )
+        {
+            classDescriptor = new InternalClassDescriptor( type, logger );
+            classDescriptors.put( type, classDescriptor );
+        }
+
+        return classDescriptor;
+    }
+
+    private class GeneratorDefinitionVisitor
+        implements DefinitionVisitor
+    {
+
+        private final Stack<Class<? extends Annotation>> attributeAnnotation = new Stack<Class<? extends Annotation>>();
+
+        @Override
+        public void visitSerializerDefinition( SerializerDefinition serializerDefinition )
+        {
+            // If at top level definition just add the base annotation
+            if ( attributeAnnotation.size() == 0 )
+            {
+                if ( SerializerDefinitionAnalyser.this.attributeAnnotation == null )
+                {
+                    attributeAnnotation.push( Attribute.class );
+                }
+                else
+                {
+                    attributeAnnotation.push( SerializerDefinitionAnalyser.this.attributeAnnotation );
+                }
+            }
+            else
+            {
+                Class<? extends Annotation> annotation = attributeAnnotation.peek();
+                attributeAnnotation.push( annotation );
+            }
+
+            // Save visited SerializerDefinition
+            serializerDefinitions.add( serializerDefinition );
+        }
+
+        @Override
+        public void visitAttributeAnnotation( Class<? extends Annotation> attributeAnnotation )
+        {
+            // Remove last element and replace it with the real annotation to
+            // use right from that moment
+            this.attributeAnnotation.pop();
+            this.attributeAnnotation.push( attributeAnnotation );
+        }
+
+        @Override
+        public void visitClassDefine( Type type, Marshaller marshaller )
+        {
+            Class<?> rawType = TypeUtil.getBaseType( type );
+            InternalClassDescriptor classDescriptor = findClassDescriptor( rawType );
+            classDescriptor.setMarshaller( marshaller );
+
+            marshallers.put( rawType, marshaller );
+        }
+
+        @Override
+        public void visitAnnotatedAttribute( PropertyDescriptor propertyDescriptor, Marshaller marshaller )
+        {
+            InternalClassDescriptor classDescriptor = findClassDescriptor( propertyDescriptor.getDefinedClass() );
+
+            if ( logger.isTraceEnabled() )
+            {
+                logger.trace( "Found property " + propertyDescriptor.getName() + " ("
+                    + propertyDescriptor.getInternalSignature() + ") on type "
+                    + propertyDescriptor.getDefinedClass().getCanonicalName() );
+            }
+
+            classDescriptor.push( propertyDescriptor );
+        }
+
+        @Override
+        public void visitPropertyDescriptor( PropertyDescriptor propertyDescriptor, Marshaller marshaller )
+        {
+            InternalClassDescriptor classDescriptor = findClassDescriptor( propertyDescriptor.getDefinedClass() );
+
+            if ( logger.isTraceEnabled() )
+            {
+                logger.trace( "Found property " + propertyDescriptor.getName() + " ("
+                    + propertyDescriptor.getInternalSignature() + ") on type "
+                    + propertyDescriptor.getDefinedClass().getCanonicalName() );
+            }
+
+            classDescriptor.push( propertyDescriptor );
+        }
+
+        @Override
+        public void visitFinalizeSerializerDefinition( SerializerDefinition serializerDefinition )
+        {
+            // Clean this level up
+            this.attributeAnnotation.pop();
+        }
+    }
+
+    public static @interface Placeholder
+    {
+    }
+}
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SourceMarshallerGenerator.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SourceMarshallerGenerator.java
new file mode 100644
index 0000000..92cdeb4
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SourceMarshallerGenerator.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.directmemory.lightning.SerializationStrategy;
+import org.apache.directmemory.lightning.logging.Logger;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+
+public class SourceMarshallerGenerator
+{
+
+    private final VelocityEngine engine;
+
+    private final Template marshallerTemplate;
+
+    private final Charset charset;
+
+    private final Logger logger;
+
+    public SourceMarshallerGenerator( Charset charset, Logger logger )
+        throws IOException
+    {
+        this.charset = charset;
+        this.logger = logger;
+
+        Properties properties = new Properties();
+        InputStream stream = getClass().getClassLoader().getResourceAsStream( "velocity.properties" );
+        properties.load( stream );
+        engine = new VelocityEngine( properties );
+
+        engine.init();
+        marshallerTemplate = engine.getTemplate( "marshaller.vm", "UTF-8" );
+    }
+
+    public File generateMarshaller( Class<?> type, List<PropertyDescriptor> propertyDescriptors,
+                                    SerializationStrategy serializationStrategy, File outputFolder )
+        throws IOException
+    {
+
+        // Copy properties and sort them by name
+        List<PropertyDescriptor> propertyDescriptorsCopy = new ArrayList<PropertyDescriptor>( propertyDescriptors );
+        Collections.sort( propertyDescriptorsCopy );
+
+        String packageName = type.getPackage() != null ? type.getPackage().getName() : "lightning";
+        String className = type.getName().replace( packageName + ".", "" ) + "LightningGeneratedMarshaller";
+
+        File packageFolder = new File( outputFolder, packageName.replace( ".", "/" ) );
+        if ( !packageFolder.exists() )
+        {
+            packageFolder.mkdirs();
+        }
+
+        File outputFile = new File( packageFolder, className + ".java" );
+
+        logger.info( "Generating source :" + outputFile.getAbsolutePath() );
+
+        FileOutputStream stream = new FileOutputStream( outputFile );
+        OutputStreamWriter writer = new OutputStreamWriter( stream, charset );
+
+        VelocityContext context = new VelocityContext();
+
+        context.put( "support", new Support() );
+        context.put( "packageName", packageName );
+        context.put( "className", className );
+        context.put( "properties", propertyDescriptorsCopy );
+        context.put( "strategy", serializationStrategy.name() );
+
+        marshallerTemplate.merge( context, writer );
+
+        writer.flush();
+        writer.close();
+
+        return outputFile;
+    }
+
+    public static class Support
+    {
+
+        public String toFinalFieldName( String prefix, PropertyDescriptor propertyDescriptor )
+        {
+            return new StringBuilder( prefix.toUpperCase() ).append( "_" ).append( propertyDescriptor.getPropertyName().toUpperCase() ).append( "_LIGHTNING" ).toString();
+        }
+
+        public String generateWriter( PropertyDescriptor propertyDescriptor, String instanceName )
+        {
+            StringBuilder sb =
+                new StringBuilder( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor.write" );
+            Class<?> type = propertyDescriptor.getType();
+            if ( type == boolean.class )
+            {
+                sb.append( "Boolean(" ).append( instanceName ).append( ", ((Boolean) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").booleanValue())" );
+            }
+            else if ( type == byte.class )
+            {
+                sb.append( "Byte(" ).append( instanceName ).append( ", ((Byte) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").byteValue())" );
+            }
+            else if ( type == char.class )
+            {
+                sb.append( "Char(" ).append( instanceName ).append( ", ((Character) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").charValue())" );
+            }
+            else if ( type == short.class )
+            {
+                sb.append( "Short(" ).append( instanceName ).append( ", ((Short) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").shortValue())" );
+            }
+            else if ( type == int.class )
+            {
+                sb.append( "Int(" ).append( instanceName ).append( ", ((Integer) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").intValue())" );
+            }
+            else if ( type == long.class )
+            {
+                sb.append( "Long(" ).append( instanceName ).append( ", ((Long) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").longValue())" );
+            }
+            else if ( type == float.class )
+            {
+                sb.append( "Float(" ).append( instanceName ).append( ", ((Float) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").floatValue())" );
+            }
+            else if ( type == double.class )
+            {
+                sb.append( "Double(" ).append( instanceName ).append( ", ((Double) " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ").doubleValue())" );
+            }
+            else
+            {
+                sb.append( "Object(" ).append( instanceName ).append( ", " ).append( propertyDescriptor.getPropertyName() ).append( "Value" ).append( ")" );
+            }
+
+            return sb.append( ";" ).toString();
+        }
+
+        public String generateReader( PropertyDescriptor propertyDescriptor )
+        {
+            StringBuilder sb = new StringBuilder();
+            Class<?> type = propertyDescriptor.getType();
+            if ( type == boolean.class )
+            {
+                sb.append( "Boolean.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readBoolean(" );
+            }
+            else if ( type == byte.class )
+            {
+                sb.append( "Byte.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readByte(" );
+            }
+            else if ( type == char.class )
+            {
+                sb.append( "Character.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readChar(" );
+            }
+            else if ( type == short.class )
+            {
+                sb.append( "Short.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readShort(" );
+            }
+            else if ( type == int.class )
+            {
+                sb.append( "Integer.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readInt(" );
+            }
+            else if ( type == long.class )
+            {
+                sb.append( "Long.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readLong(" );
+            }
+            else if ( type == float.class )
+            {
+                sb.append( "Float.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readFloat(" );
+            }
+            else if ( type == double.class )
+            {
+                sb.append( "Double.valueOf(" ).append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readDouble(" );
+            }
+            else
+            {
+                sb.append( propertyDescriptor.getPropertyName() ).append( "PropertyAccessor" ).append( ".readObject(" );
+            }
+
+            sb.append( "value)" );
+
+            if ( type.isPrimitive() )
+            {
+                sb.append( ")" );
+            }
+
+            return sb.toString();
+        }
+    }
+}
diff --git a/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SupportUtil.java b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SupportUtil.java
new file mode 100644
index 0000000..f6cd05f
--- /dev/null
+++ b/lightning-maven-plugin/src/main/java/org/apache/directmemory/lightning/maven/SupportUtil.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class SupportUtil
+{
+
+    private SupportUtil()
+    {
+    }
+
+    public static List<File> recursiveGetAllJavaSources( File file, ArrayList<File> list, FileFilter fileFilter )
+    {
+        if ( file.isDirectory() )
+        {
+            for ( File f : file.listFiles( fileFilter ) )
+            {
+                recursiveGetAllJavaSources( f, list, fileFilter );
+            }
+        }
+        else
+        {
+            list.add( file );
+        }
+        return list;
+    }
+
+    public static String readAllText( File file, Charset charset )
+    {
+        try
+        {
+            StringBuilder sb = new StringBuilder();
+            LineNumberReader reader = new LineNumberReader( new FileReader( file ) );
+            String line = null;
+            while ( ( line = reader.readLine() ) != null )
+            {
+                sb.append( line );
+            }
+            return sb.toString();
+        }
+        catch ( IOException e )
+        {
+            return null;
+        }
+    }
+}
diff --git a/lightning-maven-plugin/src/main/resources/marshaller.vm b/lightning-maven-plugin/src/main/resources/marshaller.vm
new file mode 100644
index 0000000..b5a60de
--- /dev/null
+++ b/lightning-maven-plugin/src/main/resources/marshaller.vm
@@ -0,0 +1,96 @@
+#**
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*#
+package ${packageName};
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.directmemory.lightning.Marshaller;
+import org.apache.directmemory.lightning.SerializationContext;
+import org.apache.directmemory.lightning.instantiator.ObjectInstantiatorFactory;
+import org.apache.directmemory.lightning.internal.ClassDescriptorAwareSerializer;
+import org.apache.directmemory.lightning.internal.generator.AbstractGeneratedMarshaller;
+import org.apache.directmemory.lightning.metadata.ValuePropertyAccessor;
+import org.apache.directmemory.lightning.metadata.PropertyDescriptor;
+
+public final class ${className} extends AbstractGeneratedMarshaller {
+
+#foreach( $property in ${properties} )
+	private final PropertyDescriptor ${support.toFinalFieldName("descriptor", $property)};
+	private final Marshaller ${support.toFinalFieldName("marshaller", $property)};
+	private final ValuePropertyAccessor ${support.toFinalFieldName("accessor", $property)};
+#end
+
+	public ${className} (Class<?> marshalledType, Map<Class<?>, Marshaller> marshallers,
+		ClassDescriptorAwareSerializer serializer, ObjectInstantiatorFactory objectInstantiatorFactory,
+		List<PropertyDescriptor> propertyDescriptors) {
+		
+		super(marshalledType, marshallers, serializer, objectInstantiatorFactory);
+#set( $index = 0)
+#foreach( $property in ${properties} )
+		${support.toFinalFieldName("descriptor", $property)} = propertyDescriptors.get(${index});
+		
+		PropertyDescriptor ${property.propertyName} = findPropertyDescriptor("${property.propertyName}", propertyDescriptors);
+		Marshaller ${property.propertyName}Marshaller = ${property.propertyName}.getMarshaller();
+		if (${property.propertyName}Marshaller == null) {
+			${property.propertyName}Marshaller = findMarshaller(${property.propertyName});
+		}
+		${support.toFinalFieldName("marshaller", $property)} = ${property.propertyName}Marshaller;
+
+		${support.toFinalFieldName("accessor", $property)} = (ValuePropertyAccessor) getPropertyAccessor("${property.propertyName}");
+#set( $index = $index + 1)
+#end	
+	}
+	
+	public void marshall(Object value, PropertyDescriptor propertyDescriptor, DataOutput dataOutput, SerializationContext serializationContext) throws IOException {
+		if (isAlreadyMarshalled(value, propertyDescriptor.getType(), dataOutput, serializationContext)) {
+			return;
+		}
+
+#foreach( $property in ${properties} )
+		ValuePropertyAccessor ${property.propertyName}PropertyAccessor = this.${support.toFinalFieldName("accessor", $property)};
+		PropertyDescriptor ${property.propertyName}PropertyDescriptor = this.${support.toFinalFieldName("descriptor", $property)};
+		this.${support.toFinalFieldName("marshaller", $property)}.marshall(${support.generateReader($property)}, ${property.propertyName}PropertyDescriptor, dataOutput, serializationContext);
+
+#end
+	}
+	
+	public <V> V unmarshall(V instance, PropertyDescriptor propertyDescriptor, DataInput dataInput, SerializationContext serializationContext) throws IOException {
+#foreach( $property in ${properties} )
+		ValuePropertyAccessor ${property.propertyName}PropertyAccessor = this.${support.toFinalFieldName("accessor", $property)};
+		PropertyDescriptor ${property.propertyName}PropertyDescriptor = this.${support.toFinalFieldName("descriptor", $property)};
+		Object ${property.propertyName}Value = this.${support.toFinalFieldName("marshaller", $property)}.unmarshall(${property.propertyName}PropertyDescriptor, dataInput, serializationContext);
+		${support.generateWriter($property, "instance")}
+
+#end
+		return instance;
+	}
+	
+	private PropertyDescriptor findPropertyDescriptor(String propertyName, List<PropertyDescriptor> propertyDescriptors) {
+		for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+			if (propertyDescriptor.getPropertyName().equals(propertyName)) {
+				return propertyDescriptor;
+			}
+		}
+		return null;
+	}
+}
diff --git a/lightning-maven-plugin/src/main/resources/velocity.properties b/lightning-maven-plugin/src/main/resources/velocity.properties
new file mode 100644
index 0000000..6d187e9
--- /dev/null
+++ b/lightning-maven-plugin/src/main/resources/velocity.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+runtime.log=target/velocity.log
+resource.loader = class
+class.resource.loader.description = Velocity Classpath Loader
+class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
\ No newline at end of file
diff --git a/lightning-maven-plugin/src/test/java/org/apache/directmemory/lightning/maven/GeneratorTestCase.java b/lightning-maven-plugin/src/test/java/org/apache/directmemory/lightning/maven/GeneratorTestCase.java
new file mode 100644
index 0000000..b564afe
--- /dev/null
+++ b/lightning-maven-plugin/src/test/java/org/apache/directmemory/lightning/maven/GeneratorTestCase.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.directmemory.lightning.maven;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.directmemory.lightning.maven.LightningGeneratorMojo;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.junit.Test;
+
+public class GeneratorTestCase
+    extends AbstractMojoTestCase
+{
+
+    @Test
+    public void testGeneration()
+        throws Exception
+    {
+        URL url = getClass().getClassLoader().getResource( "generate-pom.xml" );
+        LightningGeneratorMojo mojo = (LightningGeneratorMojo) lookupMojo( "generate", new File( url.toURI() ) );
+        mojo.execute();
+    }
+}
diff --git a/lightning-maven-plugin/src/test/resources/generate-pom.xml b/lightning-maven-plugin/src/test/resources/generate-pom.xml
new file mode 100644
index 0000000..99d18f6
--- /dev/null
+++ b/lightning-maven-plugin/src/test/resources/generate-pom.xml
@@ -0,0 +1,50 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>test</artifactId>
+  <version>0</version>
+  <name>test</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.directmemory.lightning</groupId>
+        <artifactId>lightning-maven-plugin</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <executions>
+          <execution>
+            <goals>
+              generate
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <generatedSourceDirectory>target/test-generate</generatedSourceDirectory>
+          <targetBuildDirectory>target/test-classes</targetBuildDirectory>
+          <compilerId>javac</compilerId>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..02da73d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,461 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.directmemory.lightning</groupId>
+  <artifactId>lightning-reactor</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>Lightning: Reactor</name>
+  <description>Lightning fast Java Serialization</description>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>lightning-core</module>
+    <module>lightning-maven-plugin</module>
+    <module>lightning-api</module>
+    <module>lightning-maven-integration-test</module>
+    <module>lightning-maven-eclipse-helper</module>
+    <module>lightning-maven-eclipse-helper-feature</module>
+    <module>lightning-integration</module>
+  </modules>
+
+  <distributionManagement>
+    <repository>
+      <id>sonatype-nexus-staging</id>
+      <name>Nexus Release Repository</name>
+      <url>http://oss.sonatype.org/service/local/staging/deploy/maven2/
+			</url>
+    </repository>
+    <snapshotRepository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>http://oss.sonatype.org/content/repositories/snapshots</url>
+    </snapshotRepository>
+  </distributionManagement>
+
+  <developers>
+    <developer>
+      <id>noctarius</id>
+      <name>Christoph Engelbert</name>
+      <roles>
+        <role>Committer</role>
+      </roles>
+    </developer>
+  </developers>
+
+  <licenses>
+    <license>
+      <name>Apache License Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+    </license>
+  </licenses>
+
+  <issueManagement>
+    <system>GitHub Issue Tracker</system>
+    <url>https://github.com/noctarius/Lightning/issues</url>
+  </issueManagement>
+
+  <scm>
+    <connection>scm:git:http://github.com/Lightning/Lightning</connection>
+    <developerConnection>scm:git:https://github.com/Lightning/Lightning</developerConnection>
+    <url>http://github.com/Lightning/Lightning</url>
+  </scm>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+    <maven.version>[3.0.3,)</maven.version>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- Core dependencies -->
+      <dependency>
+        <groupId>org.ow2.asm</groupId>
+        <artifactId>asm</artifactId>
+        <version>4.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.googlecode</groupId>
+        <artifactId>reflectasm</artifactId>
+        <version>1.01</version>
+        <exclusions>
+          <exclusion>
+            <groupId>asm</groupId>
+            <artifactId>asm</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.9</version>
+        <scope>test</scope>
+      </dependency>
+      <!-- Core dependencies -->
+
+      <!-- Integration dependencies -->
+      <dependency>
+        <groupId>org.jgroups</groupId>
+        <artifactId>jgroups</artifactId>
+        <version>3.0.4.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-beans</artifactId>
+        <version>2.5.6</version>
+      </dependency>
+      <!-- Integration dependencies -->
+
+      <!-- Maven plugin dependencies -->
+      <dependency>
+        <groupId>org.apache.velocity</groupId>
+        <artifactId>velocity</artifactId>
+        <version>1.7</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-plugin-api</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-model</artifactId>
+        <version>${maven.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-core</artifactId>
+        <version>${maven.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-settings</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-settings-builder</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-repository-metadata</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-model-builder</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-aether-provider</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.sonatype.aether</groupId>
+            <artifactId>aether-impl</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.sonatype.aether</groupId>
+            <artifactId>aether-api</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.sonatype.aether</groupId>
+            <artifactId>aether-util</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.sonatype.sisu</groupId>
+            <artifactId>sisu-inject-plexus</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-interpolation</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-classworlds</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-component-annotations</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.sonatype.plexus</groupId>
+            <artifactId>plexus-sec-dispatcher</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.maven.plugin-testing</groupId>
+        <artifactId>maven-plugin-testing-harness</artifactId>
+        <version>2.0-alpha-1</version>
+        <scope>test</scope>
+      </dependency>
+      <!-- Maven plugin dependencies -->
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-release-plugin</artifactId>
+        <version>2.1</version>
+        <configuration>
+          <autoVersionSubmodules>true</autoVersionSubmodules>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.3.2</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.5</version>
+        <configuration>
+          <encoding>UTF-8</encoding>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <version>2.1.2</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>2.8.1</version>
+        <configuration>
+          <excludePackageNames>*.internal*</excludePackageNames>
+          <detectJavaApiLink>true</detectJavaApiLink>
+          <detectLinks>true</detectLinks>
+          <source>1.6</source>
+          <links>
+            <link>http://docs.oracle.com/javase/6/docs/api/</link>
+          </links>
+        </configuration>
+        <executions>
+          <execution>
+            <id>package-javadoc</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>changelog-maven-plugin</artifactId>
+        <version>2.0-beta-1</version>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>2.4.0</version>
+        <configuration>
+          <effort>Max</effort>
+          <threshold>Low</threshold>
+          <xmlOutput>true</xmlOutput>
+          <failOnError>false</failOnError>
+          <findbugsXmlOutput>true</findbugsXmlOutput>
+        </configuration>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>rat-maven-plugin</artifactId>
+        <version>1.0-alpha-3</version>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+            <configuration>
+              <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
+              <licenseMatchers>
+                <classNames>
+                  <className>rat.analysis.license.ApacheSoftwareLicense20</className>
+                </classNames>
+              </licenseMatchers>
+              <includes>
+                <include>pom.xml</include>
+                <include>src/**</include>
+              </includes>
+              <excludes>
+                <exclude>src/**/bundle/**</exclude>
+                <exclude>src/**/jrockit/**</exclude>
+                <exclude>src/**/generated.java.out</exclude>
+                <exclude>META-INF/MANIFEST.MF</exclude>
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <resources>
+      <resource>
+        <targetPath>target/classes</targetPath>
+        <directory>${basedir}</directory>
+        <includes>
+          <include>*.txt</include>
+        </includes>
+      </resource>
+    </resources>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.sonatype.plugins</groupId>
+                    <artifactId>jarjar-maven-plugin</artifactId>
+                    <versionRange>[1.4,)</versionRange>
+                    <goals>
+                      <goal>jarjar</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore></ignore>
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.4</version>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>2.4.0</version>
+      </plugin>
+    </plugins>
+  </reporting>
+
+  <profiles>
+    <profile>
+      <id>release-sign-artifacts</id>
+      <activation>
+        <property>
+          <name>performRelease</name>
+          <value>true</value>
+        </property>
+      </activation>
+      <modules>
+        <module>lightning-core</module>
+        <module>lightning-maven-plugin</module>
+        <module>lightning-api</module>
+        <module>lightning-maven-integration-test</module>
+        <module>lightning-integration</module>
+      </modules>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <version>1.4</version>
+            <executions>
+              <execution>
+                <id>sign-artifacts</id>
+                <phase>verify</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>sign-artifacts</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <version>1.4</version>
+            <executions>
+              <execution>
+                <id>sign-artifacts</id>
+                <phase>verify</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
\ No newline at end of file