trying new codec idea, apated HTTP codec for using it
diff --git a/codec/pom.xml b/codec/pom.xml
new file mode 100644
index 0000000..2ed93ad
--- /dev/null
+++ b/codec/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.mina</groupId>
+    <artifactId>mina-parent</artifactId>
+    <version>3.0.0-M1-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>mina-codec</artifactId>
+  <name>Apache MINA Codec ${project.version}</name>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <symbolicName>${project.groupId}.codec</symbolicName>
+    <exportedPackage>${project.groupId}</exportedPackage>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.logging.log4j.adapters</groupId>
+      <artifactId>slf4j-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
+
diff --git a/codec/src/main/java/org/apache/mina/codec/ProtocolDecoder.java b/codec/src/main/java/org/apache/mina/codec/ProtocolDecoder.java
new file mode 100644
index 0000000..8c4ffdd
--- /dev/null
+++ b/codec/src/main/java/org/apache/mina/codec/ProtocolDecoder.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.mina.codec;
+
+/**
+ * Decodes binary or protocol-specific data into higher-level message objects.
+ * 
+ * Should be state-full, and have one instance per new session.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public interface ProtocolDecoder<INPUT, OUTPUT> {
+
+    /**
+     * Decode binary or protocol-specific content of type <code>INPUT</code> into higher-level protocol message objects,
+     * of type OUTPUT
+     * 
+     * @param input the received message to decode
+     * @return the decoded messages or <code>null</code> if nothing was decoded
+     * @throws ProtocolDecoderException if something wrong happen during decoding (e.g. : a malformed input message)
+     */
+    OUTPUT[] decode(INPUT input) throws ProtocolDecoderException;
+
+    /**
+     * Finish decoding, for example if the decoder accumulated some unused input, it should discard it, or throw an
+     * Exception
+     */
+    void finishDecode();
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java b/codec/src/main/java/org/apache/mina/codec/ProtocolDecoderException.java
similarity index 61%
copy from core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
copy to codec/src/main/java/org/apache/mina/codec/ProtocolDecoderException.java
index 6bbc55e..e098b27 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
+++ b/codec/src/main/java/org/apache/mina/codec/ProtocolDecoderException.java
@@ -17,23 +17,29 @@
  *  under the License.
  *
  */
-package org.apache.mina.filter.codec;
-
-import java.nio.ByteBuffer;
-
-import org.apache.mina.api.IoSession;
+package org.apache.mina.codec;
 
 /**
- * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other protocol level construction.
+ * Exception thrown by a {@link ProtocolDecoder} if something wrong happen during decoding.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * 
  */
-public interface ProtocolEncoder<INPUT /* message type */, OUTPUT> {
+@SuppressWarnings("serial")
+public class ProtocolDecoderException extends Exception {
 
-    /**
-     * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type <code>OUTPUT</code>.
-     */
-	OUTPUT encode(IoSession session, INPUT message);
+    public ProtocolDecoderException() {
+        super();
+    }
 
+    public ProtocolDecoderException(String message) {
+        super(message);
+    }
+
+    public ProtocolDecoderException(Throwable cause) {
+        super(cause);
+    }
+
+    public ProtocolDecoderException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java b/codec/src/main/java/org/apache/mina/codec/ProtocolEncoder.java
similarity index 80%
rename from core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
rename to codec/src/main/java/org/apache/mina/codec/ProtocolEncoder.java
index 6bbc55e..f439f51 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
+++ b/codec/src/main/java/org/apache/mina/codec/ProtocolEncoder.java
@@ -17,14 +17,13 @@
  *  under the License.
  *
  */
-package org.apache.mina.filter.codec;
+package org.apache.mina.codec;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.api.IoSession;
-
 /**
- * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other protocol level construction.
+ * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other
+ * protocol level construction.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -32,8 +31,9 @@
 public interface ProtocolEncoder<INPUT /* message type */, OUTPUT> {
 
     /**
-     * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type <code>OUTPUT</code>.
+     * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type
+     * <code>OUTPUT</code>.
      */
-	OUTPUT encode(IoSession session, INPUT message);
+    OUTPUT encode(INPUT message);
 
 }
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index fb85ba1..7e75056 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -38,6 +38,13 @@
 
   <dependencies>
     <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mina-codec</artifactId>
+      <version>${project.version}</version>
+      <type>bundle</type>
+    </dependency>
+
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java
index 7406b41..1f72812 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java
+++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java
@@ -20,6 +20,8 @@
 package org.apache.mina.filter.codec;
 
 import org.apache.mina.api.IoSession;
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolEncoder;
 
 /**
  * Provides {@link ProtocolEncoder} and {@link ProtocolDecoder} which translates
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java
index 2938cf3..e7970c0 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java
+++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java
@@ -22,6 +22,9 @@
 import org.apache.mina.api.AbstractIoFilter;
 import org.apache.mina.api.IoFilter;
 import org.apache.mina.api.IoSession;
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolDecoderException;
+import org.apache.mina.codec.ProtocolEncoder;
 import org.apache.mina.filterchain.ReadFilterChainController;
 import org.apache.mina.filterchain.WriteFilterChainController;
 import org.apache.mina.session.AttributeKey;
@@ -36,7 +39,7 @@
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
-public class ProtocolCodecFilter<MESSAGE,ENCODED> extends AbstractIoFilter {
+public class ProtocolCodecFilter<MESSAGE, ENCODED> extends AbstractIoFilter {
     /** A logger for this class */
     private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolCodecFilter.class);
 
@@ -44,16 +47,16 @@
 
     /** key for session attribute holding the encoder */
     @SuppressWarnings("rawtypes")
-	private final AttributeKey<ProtocolEncoder> ENCODER = new AttributeKey<ProtocolEncoder>(ProtocolEncoder.class,
+    private final AttributeKey<ProtocolEncoder> ENCODER = new AttributeKey<ProtocolEncoder>(ProtocolEncoder.class,
             "internal_encoder");
 
     /** key for session attribute holding the decoder */
     @SuppressWarnings("rawtypes")
-	private final AttributeKey<ProtocolDecoder> DECODER = new AttributeKey<ProtocolDecoder>(ProtocolDecoder.class,
+    private final AttributeKey<ProtocolDecoder> DECODER = new AttributeKey<ProtocolDecoder>(ProtocolDecoder.class,
             "internal_decoder");
 
     /** The factory responsible for creating the encoder and decoder */
-    private final ProtocolCodecFactory<MESSAGE,ENCODED> factory;
+    private final ProtocolCodecFactory<MESSAGE, ENCODED> factory;
 
     /**
      * 
@@ -61,7 +64,7 @@
      * 
      * @param factory The associated factory
      */
-    public ProtocolCodecFilter(final ProtocolCodecFactory<MESSAGE,ENCODED> factory) {
+    public ProtocolCodecFilter(final ProtocolCodecFactory<MESSAGE, ENCODED> factory) {
         if (factory == null) {
             throw new IllegalArgumentException("factory");
         }
@@ -71,44 +74,14 @@
 
     /**
      * Creates a new instance of ProtocolCodecFilter, without any factory. The encoder/decoder factory will be created
-     * as an inner class, using the two parameters (encoder and decoder).
-     * 
-     * @param encoder The class responsible for encoding the message
-     * @param decoder The class responsible for decoding the message
-     */
-    public ProtocolCodecFilter(final ProtocolEncoder<MESSAGE,ENCODED> encoder, final ProtocolDecoder<ENCODED,MESSAGE> decoder) {
-        if (encoder == null) {
-            throw new IllegalArgumentException("encoder");
-        }
-
-        if (decoder == null) {
-            throw new IllegalArgumentException("decoder");
-        }
-
-        // Create the inner Factory based on the two parameters
-        this.factory = new ProtocolCodecFactory<MESSAGE,ENCODED>() {
-            @Override
-            public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) {
-                return encoder;
-            }
-
-            @Override
-            public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) {
-                return decoder;
-            }
-        };
-    }
-
-    /**
-     * Creates a new instance of ProtocolCodecFilter, without any factory. The encoder/decoder factory will be created
      * as an anonymous class, using the two parameters (encoder and decoder), which are class names. Instances for those
      * classes will be created in this constructor.
      * 
      * @param encoderClass The class responsible for encoding the message
      * @param decoderClass The class responsible for decoding the message
      */
-    public ProtocolCodecFilter(final Class<? extends ProtocolEncoder<MESSAGE,ENCODED>> encoderClass,
-            final Class<? extends ProtocolDecoder<ENCODED,MESSAGE>> decoderClass) {
+    public ProtocolCodecFilter(final Class<? extends ProtocolEncoder<MESSAGE, ENCODED>> encoderClass,
+            final Class<? extends ProtocolDecoder<ENCODED, MESSAGE>> decoderClass) {
         Assert.assertNotNull(encoderClass, "Encoder Class");
         Assert.assertNotNull(decoderClass, "Decoder Class");
 
@@ -124,7 +97,7 @@
             throw new IllegalArgumentException("decoderClass doesn't have a public default constructor.");
         }
 
-        final ProtocolEncoder<MESSAGE,ENCODED> encoder;
+        final ProtocolEncoder<MESSAGE, ENCODED> encoder;
 
         try {
             encoder = encoderClass.newInstance();
@@ -132,7 +105,7 @@
             throw new IllegalArgumentException("encoderClass cannot be initialized");
         }
 
-        final ProtocolDecoder<ENCODED,MESSAGE> decoder;
+        final ProtocolDecoder<ENCODED, MESSAGE> decoder;
 
         try {
             decoder = decoderClass.newInstance();
@@ -141,14 +114,14 @@
         }
 
         // Create the inner factory based on the two parameters.
-        this.factory = new ProtocolCodecFactory<MESSAGE,ENCODED>() {
+        this.factory = new ProtocolCodecFactory<MESSAGE, ENCODED>() {
             @Override
-            public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) {
+            public ProtocolEncoder<MESSAGE, ENCODED> getEncoder(final IoSession session) {
                 return encoder;
             }
 
             @Override
-            public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) {
+            public ProtocolDecoder<ENCODED, MESSAGE> getDecoder(final IoSession session) {
                 return decoder;
             }
         };
@@ -160,7 +133,7 @@
      * @param session The associated session we will get the encoder from
      * @return The encoder instance, if any
      */
-    public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) {
+    public ProtocolEncoder<MESSAGE, ENCODED> getEncoder(final IoSession session) {
         return factory.getEncoder(session);
     }
 
@@ -170,7 +143,7 @@
      * @param session The associated session we will get the decoder from
      * @return The decoder instance, if any
      */
-    public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) {
+    public ProtocolDecoder<ENCODED, MESSAGE> getDecoder(final IoSession session) {
         return factory.getDecoder(session);
     }
 
@@ -184,31 +157,38 @@
      *      break;
      * </code>
      */
+    @SuppressWarnings("unchecked")
     @Override
-    public void messageReceived(final IoSession session, final Object in,
-            final ReadFilterChainController controller) {
+    public void messageReceived(final IoSession session, final Object in, final ReadFilterChainController controller) {
         LOGGER.debug("Processing a MESSAGE_RECEIVED for session {}", session);
 
-        final ProtocolDecoder<ENCODED,MESSAGE> decoder = getDecoder(session);
+        final ProtocolDecoder<ENCODED, MESSAGE> decoder = getDecoder(session);
 
         // Loop until the codec cannot decode more
-        MESSAGE msg;
-        while ( (msg = decoder.decode(session, (ENCODED)in)) != null) {
-            controller.callReadNextFilter(msg);
+        MESSAGE[] msg;
+        try {
+            while ((msg = decoder.decode((ENCODED) in)) != null) {
+                for (MESSAGE m : msg) {
+                    controller.callReadNextFilter(m);
+                }
+            }
+        } catch (ProtocolDecoderException e) {
+            LOGGER.debug("decoding exception : ", e);
         }
     }
 
     /**
      * {@inheritDoc}
      */
+    @SuppressWarnings("unchecked")
     @Override
     public void messageWriting(IoSession session, WriteRequest message, WriteFilterChainController controller) {
         LOGGER.debug("Processing a MESSAGE_WRITTING for session {}", session);
 
-        final ProtocolEncoder<MESSAGE,ENCODED> encoder = session.getAttribute(ENCODER, null);
-        ENCODED encoded = encoder.encode(session,(MESSAGE) message.getMessage());
+        final ProtocolEncoder<MESSAGE, ENCODED> encoder = session.getAttribute(ENCODER, null);
+        ENCODED encoded = encoder.encode((MESSAGE) message.getMessage());
         message.setMessage(encoded);
-        
+
         controller.callWriteNextFilter(message);
     }
 
@@ -219,9 +199,9 @@
     public void sessionOpened(final IoSession session) {
         // Initialize the encoder and decoder if we use a factory
         if (factory != null) {
-            final ProtocolEncoder<MESSAGE,ENCODED> encoder = factory.getEncoder(session);
+            final ProtocolEncoder<MESSAGE, ENCODED> encoder = factory.getEncoder(session);
             session.setAttribute(ENCODER, encoder);
-            final ProtocolDecoder<ENCODED,MESSAGE> decoder = factory.getDecoder(session);
+            final ProtocolDecoder<ENCODED, MESSAGE> decoder = factory.getDecoder(session);
             session.setAttribute(DECODER, decoder);
         }
     }
@@ -258,9 +238,10 @@
      * method.
      */
     private void disposeDecoder(final IoSession session) {
-        final ProtocolDecoder<ENCODED,MESSAGE> decoder = session.removeAttribute(DECODER);
+        @SuppressWarnings("unchecked")
+        final ProtocolDecoder<ENCODED, MESSAGE> decoder = session.removeAttribute(DECODER);
         try {
-            decoder.finishDecode(session);
+            decoder.finishDecode();
         } catch (final Throwable t) {
             LOGGER.warn("Failed to dispose: " + decoder.getClass().getName() + " (" + decoder + ')');
         }
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java
deleted file mode 100644
index 435f9d1..0000000
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  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.mina.filter.codec;
-
-import org.apache.mina.api.IoSession;
-
-/**
- * Decodes binary or protocol-specific data into higher-level message objects.
- *
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * 
- */
-public interface ProtocolDecoder<INPUT,OUTPUT> {
-
-	/**
-	 * Decode binary or protocol-specific content of type <code>INPUT</code> into higher-level protocol message objects, of type OUTPUT
-	 * @param session the session for this message 
-	 * @param input the received message to decode 
-	 * @return the decoded message or <code>null</code> if nothing was decoded
-	 */
-	OUTPUT decode(IoSession session, INPUT input);
-	
-	/**
-	 * Finish decoding, for example if the decoder accumulated some unused input, it should discard it, or throw an Exception
-	 */
-    void finishDecode(IoSession session);
-}
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/mina/filter/codec/ProtocolCodecFilterTest.java b/core/src/test/java/org/apache/mina/filter/codec/ProtocolCodecFilterTest.java
index d4de8ea..f70415f 100644
--- a/core/src/test/java/org/apache/mina/filter/codec/ProtocolCodecFilterTest.java
+++ b/core/src/test/java/org/apache/mina/filter/codec/ProtocolCodecFilterTest.java
@@ -18,21 +18,22 @@
  */
 package org.apache.mina.filter.codec;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
 
 import org.apache.mina.api.IoSession;
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolEncoder;
 import org.junit.Test;
 
 /**
  * Unit test for {@link ProtocolCodecFilter}
- *
+ * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class ProtocolCodecFilterTest {
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void constructor_args() {
         try {
@@ -45,24 +46,6 @@
         }
 
         try {
-            new ProtocolCodecFilter(null, mock(ProtocolDecoder.class));
-            fail();
-        } catch (IllegalArgumentException e) {
-            // happy
-        } catch (Exception e2) {
-            fail();
-        }
-
-        try {
-            new ProtocolCodecFilter(mock(ProtocolEncoder.class), null);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // happy
-        } catch (Exception e2) {
-            fail();
-        }
-
-        try {
             new ProtocolCodecFilter(null, ProtocolDecoder.class);
             fail();
         } catch (IllegalArgumentException e) {
@@ -81,6 +64,7 @@
         }
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Test
     public void codec_factory() {
         ProtocolEncoder encoder = mock(ProtocolEncoder.class);
@@ -93,10 +77,6 @@
         ProtocolCodecFilter codec = new ProtocolCodecFilter(factory);
         assertEquals(encoder, codec.getEncoder(null));
         assertEquals(decoder, codec.getDecoder(null));
-
-        codec = new ProtocolCodecFilter(encoder, decoder);
-        assertEquals(encoder, codec.getEncoder(null));
-        assertEquals(decoder, codec.getDecoder(null));
     }
 
 }
\ No newline at end of file
diff --git a/examples/src/main/java/org/apache/mina/examples/http/HttpTest.java b/examples/src/main/java/org/apache/mina/examples/http/HttpTest.java
index edec192..df6c020 100644
--- a/examples/src/main/java/org/apache/mina/examples/http/HttpTest.java
+++ b/examples/src/main/java/org/apache/mina/examples/http/HttpTest.java
@@ -28,13 +28,15 @@
 
 import org.apache.mina.api.AbstractIoFilter;
 import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.logging.LoggingFilter;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.filterchain.ReadFilterChainController;
 import org.apache.mina.http.DateUtil;
-import org.apache.mina.http.HttpServerCodec;
+import org.apache.mina.http.HttpServerDecoder;
+import org.apache.mina.http.HttpServerEncoder;
 import org.apache.mina.http.api.DefaultHttpResponse;
 import org.apache.mina.http.api.HttpEndOfContent;
 import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpPdu;
 import org.apache.mina.http.api.HttpRequest;
 import org.apache.mina.http.api.HttpStatus;
 import org.apache.mina.http.api.HttpVersion;
@@ -45,7 +47,8 @@
     public static void main(String[] args) throws Exception {
 
         NioTcpServer acceptor = new NioTcpServer();
-        acceptor.setFilters(new LoggingFilter("INCOMING"), new HttpServerCodec(), new LoggingFilter("DECODED"),
+        acceptor.setFilters(/* new LoggingFilter("INCOMING"), */new ProtocolCodecFilter<HttpPdu, ByteBuffer>(
+                HttpServerEncoder.class, HttpServerDecoder.class), /* new LoggingFilter("DECODED"), */
                 new DummyHttpSever());
 
         acceptor.getSessionConfig().setTcpNoDelay(true);
diff --git a/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java b/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
index b114a2f..71f095d 100644
--- a/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
+++ b/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
@@ -19,11 +19,13 @@
  */
 package org.apache.mina.http;
 
+import java.nio.ByteBuffer;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpPduEncodingVisitor;
 import org.apache.mina.http.api.HttpRequest;
 import org.apache.mina.http.api.HttpVersion;
 
@@ -44,61 +46,99 @@
         this.headers = Collections.unmodifiableMap(headers);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public HttpVersion getProtocolVersion() {
         return version;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String getContentType() {
         return headers.get("content-type");
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean isKeepAlive() {
-        // TODO Auto-generated method stub
+        // TODO check headers
         return false;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String getHeader(String name) {
         return headers.get(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean containsHeader(String name) {
         return headers.containsKey(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public Map<String, String> getHeaders() {
         return headers;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean containsParameter(String name) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String getParameter(String name) {
         // TODO Auto-generated method stub
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public Map<String, List<String>> getParameters() {
         // TODO Auto-generated method stub
         return null;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public HttpMethod getMethod() {
         return method;
     }
 
     @Override
+    public ByteBuffer encode(HttpPduEncodingVisitor visitor) {
+        return visitor.visit(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public String toString() {
         String result = "HTTP REQUEST METHOD: " + method + "\n";
         result += "VERSION: " + version + "\n";
@@ -116,4 +156,4 @@
          */
         return result;
     }
-}
+}
\ No newline at end of file
diff --git a/http/src/main/java/org/apache/mina/http/HttpServerCodec.java b/http/src/main/java/org/apache/mina/http/HttpServerCodec.java
deleted file mode 100644
index 706659f..0000000
--- a/http/src/main/java/org/apache/mina/http/HttpServerCodec.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  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.mina.http;
-
-import static org.apache.mina.session.AttributeKey.createKey;
-
-import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.codec.ProtocolDecoder;
-import org.apache.mina.filter.codec.ProtocolEncoder;
-import org.apache.mina.session.AttributeKey;
-
-public class HttpServerCodec extends ProtocolCodecFilter {
-
-    /** Key for decoder current state */
-    private static final AttributeKey<DecoderState> DECODER_STATE_ATT = createKey(DecoderState.class,
-            "internal_http.ds");
-
-    /** Key for the partial HTTP requests head */
-    private static final AttributeKey<String> PARTIAL_HEAD_ATT = createKey(String.class, "internal_http.ph");
-
-    private static ProtocolEncoder encoder = new HttpServerEncoder();
-
-    private static ProtocolDecoder decoder = new HttpServerDecoder();
-
-    public HttpServerCodec() {
-        super(encoder, decoder);
-    }
-
-    @Override
-    public void sessionOpened(final IoSession session) {
-        super.sessionOpened(session);
-        session.setAttribute(DECODER_STATE_ATT, DecoderState.NEW);
-    }
-
-    @Override
-    public void sessionClosed(final IoSession session) {
-        super.sessionClosed(session);
-        session.removeAttribute(DECODER_STATE_ATT);
-        session.removeAttribute(PARTIAL_HEAD_ATT);
-    }
-}
\ No newline at end of file
diff --git a/http/src/main/java/org/apache/mina/http/HttpServerDecoder.java b/http/src/main/java/org/apache/mina/http/HttpServerDecoder.java
index 8ec3874..0c4cf0f 100644
--- a/http/src/main/java/org/apache/mina/http/HttpServerDecoder.java
+++ b/http/src/main/java/org/apache/mina/http/HttpServerDecoder.java
@@ -19,36 +19,29 @@
  */
 package org.apache.mina.http;
 
-import static org.apache.mina.session.AttributeKey.createKey;
-
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 
-import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolDecoder;
-import org.apache.mina.filterchain.ReadFilterChainController;
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolDecoderException;
+import org.apache.mina.http.api.HttpContentChunk;
 import org.apache.mina.http.api.HttpEndOfContent;
 import org.apache.mina.http.api.HttpMethod;
+import org.apache.mina.http.api.HttpPdu;
 import org.apache.mina.http.api.HttpVersion;
-import org.apache.mina.session.AttributeKey;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class HttpServerDecoder implements ProtocolDecoder {
-    private static final Logger LOG = LoggerFactory.getLogger(HttpServerCodec.class);
-
-    /** Key for decoder current state */
-    private static final AttributeKey<DecoderState> DECODER_STATE_ATT = createKey(DecoderState.class,
-            "internal_http.ds");
-
-    /** Key for the partial HTTP requests head */
-    private static final AttributeKey<ByteBuffer> PARTIAL_HEAD_ATT = createKey(ByteBuffer.class, "internal_http.ph");
-
-    /** Key for the number of bytes remaining to read for completing the body */
-    private static final AttributeKey<Integer> BODY_REMAINING_BYTES = createKey(Integer.class, "internal_http.brb");
+/**
+ * In charge of decoding received bytes into HTTP message.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class HttpServerDecoder implements ProtocolDecoder<ByteBuffer, HttpPdu> {
+    private static final Logger LOG = LoggerFactory.getLogger(HttpServerDecoder.class);
 
     /** Regex to parse HttpRequest Request Line */
     public static final Pattern REQUEST_LINE_PATTERN = Pattern.compile(" ");
@@ -74,17 +67,23 @@
     /** Regex to split cookie header following RFC6265 Section 5.4 */
     public static final Pattern COOKIE_SEPARATOR_PATTERN = Pattern.compile(";");
 
-    @Override
-    public Object decode(IoSession session, ByteBuffer msg, ReadFilterChainController controller) {
-        DecoderState state = session.getAttribute(DECODER_STATE_ATT, null);
+    /** State of the decoder */
+    private DecoderState state = DecoderState.NEW;
 
+    /** The previously received buffer, not totally decoded */
+    private ByteBuffer partial;
+
+    /** Number of bytes remaining to read for completing the body */
+    private int remainingBytes;
+
+    @Override
+    public HttpPdu[] decode(ByteBuffer msg) throws ProtocolDecoderException {
+        LOG.debug("decode : {}", msg);
         switch (state) {
         case HEAD:
             LOG.debug("decoding HEAD");
-            // grab the stored a partial HEAD request
-            ByteBuffer oldBuffer = session.getAttribute(PARTIAL_HEAD_ATT, null);
             // concat the old buffer and the new incoming one
-            msg = ByteBuffer.allocate(oldBuffer.remaining() + msg.remaining()).put(oldBuffer).put(msg);
+            msg = ByteBuffer.allocate(partial.remaining() + msg.remaining()).put(partial).put(msg);
             msg.flip();
             // now let's decode like it was a new message
 
@@ -94,36 +93,27 @@
 
             if (rq == null) {
                 // we copy the incoming BB because it's going to be recycled by the inner IoProcessor for next reads
-                ByteBuffer partial = ByteBuffer.allocate(msg.remaining());
+                partial = ByteBuffer.allocate(msg.remaining());
                 partial.put(msg);
                 partial.flip();
-                // no request decoded, we accumulate
-                session.setAttribute(PARTIAL_HEAD_ATT, partial);
-                session.setAttribute(DECODER_STATE_ATT, DecoderState.HEAD);
             } else {
-                controller.callReadNextFilter(rq);
+                return new HttpPdu[] { rq };
             }
-
             return null;
-
         case BODY:
             LOG.debug("decoding BODY");
             int chunkSize = msg.remaining();
             // send the chunk of body
-            controller.callReadNextFilter(msg);
+            HttpContentChunk chunk = new HttpContentChunk(msg);
             // do we have reach end of body ?
-            int remaining = session.getAttribute(BODY_REMAINING_BYTES, null);
-            remaining -= chunkSize;
+            remainingBytes -= chunkSize;
 
-            if (remaining <= 0) {
+            if (remainingBytes <= 0) {
                 LOG.debug("end of HTTP body");
-                controller.callReadNextFilter(new HttpEndOfContent());
-                session.setAttribute(DECODER_STATE_ATT, DecoderState.NEW);
-                session.removeAttribute(BODY_REMAINING_BYTES);
-            } else {
-                session.setAttribute(BODY_REMAINING_BYTES, new Integer(remaining));
+                state = DecoderState.NEW;
+                remainingBytes = 0;
+                return new HttpPdu[] { chunk, new HttpEndOfContent() };
             }
-
             break;
 
         default:
@@ -133,15 +123,6 @@
         return null;
     }
 
-    @Override
-    public Object finishDecode(IoSession session) throws Exception {
-        return null;
-    }
-
-    @Override
-    public void dispose(IoSession session) throws Exception {
-    }
-
     private HttpRequestImpl parseHttpRequestHead(ByteBuffer buffer) {
         String raw = new String(buffer.array(), 0, buffer.limit(), Charset.forName("ISO-8859-1"));
         String[] headersAndBody = RAW_VALUE_PATTERN.split(raw, -1);
@@ -173,4 +154,9 @@
 
         return new HttpRequestImpl(version, method, requestedPath, generalHeaders);
     }
+
+    @Override
+    public void finishDecode() {
+
+    }
 }
diff --git a/http/src/main/java/org/apache/mina/http/HttpServerEncoder.java b/http/src/main/java/org/apache/mina/http/HttpServerEncoder.java
index caa631e..8101228 100644
--- a/http/src/main/java/org/apache/mina/http/HttpServerEncoder.java
+++ b/http/src/main/java/org/apache/mina/http/HttpServerEncoder.java
@@ -19,59 +19,66 @@
  */
 package org.apache.mina.http;
 
-
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.util.Map;
 
-import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolEncoder;
-import org.apache.mina.filterchain.WriteFilterChainController;
+import org.apache.mina.codec.ProtocolEncoder;
+import org.apache.mina.http.api.HttpContentChunk;
 import org.apache.mina.http.api.HttpEndOfContent;
+import org.apache.mina.http.api.HttpPdu;
+import org.apache.mina.http.api.HttpPduEncodingVisitor;
+import org.apache.mina.http.api.HttpRequest;
 import org.apache.mina.http.api.HttpResponse;
-import org.apache.mina.session.WriteRequest;
 
+/**
+ * In charge of encoding HTTP message into bytes.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class HttpServerEncoder implements ProtocolEncoder<HttpPdu, ByteBuffer> {
 
-public class HttpServerEncoder implements ProtocolEncoder
-{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ByteBuffer encode(HttpPdu message) {
+        return message.encode(visitor);
+    }
 
-    public Object encode( IoSession session, WriteRequest message, WriteFilterChainController controller )
-    {
-        if ( message.getOriginalMessage() instanceof HttpResponse )
-        {
-            HttpResponse msg = ( HttpResponse ) message;
-            StringBuilder sb = new StringBuilder( msg.getStatus().line() );
+    private HttpPduEncodingVisitor visitor = new HttpPduEncodingVisitor() {
 
-            for ( Map.Entry<String, String> header : msg.getHeaders().entrySet() )
-            {
-                sb.append( header.getKey() );
-                sb.append( ": " );
-                sb.append( header.getValue() );
-                sb.append( "\r\n" );
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ByteBuffer visit(HttpResponse msg) {
+            StringBuilder sb = new StringBuilder(msg.getStatus().line());
+
+            for (Map.Entry<String, String> header : msg.getHeaders().entrySet()) {
+                sb.append(header.getKey());
+                sb.append(": ");
+                sb.append(header.getValue());
+                sb.append("\r\n");
             }
-            sb.append( "\r\n" );
-            byte[] bytes = sb.toString().getBytes( Charset.forName( "UTF-8" ) );
-            message.setMessage( ByteBuffer.wrap( bytes ) );
-            controller.callWriteNextFilter( message );
+            sb.append("\r\n");
+            byte[] bytes = sb.toString().getBytes(Charset.forName("UTF-8"));
+            return ByteBuffer.wrap(bytes);
         }
-        else if ( message.getOriginalMessage() instanceof ByteBuffer )
-        {
-            controller.callWriteNextFilter( message );
+
+        @Override
+        public ByteBuffer visit(HttpContentChunk msg) {
+            return msg.getContent();
         }
-        else if ( message.getOriginalMessage() instanceof HttpEndOfContent )
-        {
-            // end of HTTP content
-            // keep alive ?
+
+        @Override
+        public ByteBuffer visit(HttpEndOfContent msg) {
             return null;
         }
 
-        return null;
-    }
-
-
-    @Override
-    public void dispose( IoSession session ) throws Exception
-    {
-        // TODO Auto-generated method stub
-    }
+        @Override
+        public ByteBuffer visit(HttpRequest msg) {
+            throw new IllegalStateException("cannot encode that on server side");
+        }
+    };
 }
diff --git a/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java b/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java
index d5c995b..403788b 100644
--- a/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java
+++ b/http/src/main/java/org/apache/mina/http/api/DefaultHttpResponse.java
@@ -19,8 +19,13 @@
  */
 package org.apache.mina.http.api;
 
+import java.nio.ByteBuffer;
 import java.util.Map;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public class DefaultHttpResponse implements HttpResponse {
 
     private final HttpVersion version;
@@ -35,42 +40,74 @@
         this.headers = headers;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public HttpVersion getProtocolVersion() {
         return version;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String getContentType() {
         return headers.get("content-type");
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean isKeepAlive() {
         // TODO check header and version for keep alive
         return false;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String getHeader(String name) {
         return headers.get(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public boolean containsHeader(String name) {
         return headers.containsKey(name);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public Map<String, String> getHeaders() {
         return headers;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public HttpStatus getStatus() {
         return status;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ByteBuffer encode(HttpPduEncodingVisitor visitor) {
+        return visitor.visit(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String toString() {
         String result = "HTTP RESPONSE STATUS: " + status + "\n";
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java b/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java
index 06761a6..c495bd2 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpContentChunk.java
@@ -20,9 +20,31 @@
 package org.apache.mina.http.api;
 
 import java.nio.ByteBuffer;
-import java.util.List;
 
-public interface HttpContentChunk {
+/**
+ * A chunk of an HTTP request or response. can be follwowed by another chunk or {@link HttpEndOfContent} marking the end
+ * of the content
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class HttpContentChunk implements HttpPdu {
 
-    List<ByteBuffer> getContent();
+    private ByteBuffer content;
+
+    public HttpContentChunk(ByteBuffer content) {
+        this.content = content;
+    }
+
+    /**
+     * The content of the chunk. A part of the HTTP message content.
+     */
+    public ByteBuffer getContent() {
+        return content;
+    }
+
+    @Override
+    public ByteBuffer encode(HttpPduEncodingVisitor visitor) {
+        return visitor.visit(this);
+    }
+
 }
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java b/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java
index 026cc39..6993f21 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpEndOfContent.java
@@ -19,8 +19,25 @@
  */
 package org.apache.mina.http.api;
 
-public class HttpEndOfContent {
+import java.nio.ByteBuffer;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class HttpEndOfContent implements HttpPdu {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ByteBuffer encode(HttpPduEncodingVisitor visitor) {
+        return visitor.visit(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String toString() {
         return "HttpEndOfContent";
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpMessage.java b/http/src/main/java/org/apache/mina/http/api/HttpMessage.java
index 85801eb..5fc5854 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpMessage.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpMessage.java
@@ -25,10 +25,10 @@
 /**
  * An HTTP message, the ancestor of HTTP request & response.
  * 
- * @author jvermillar
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
  */
-public interface HttpMessage {
+public interface HttpMessage extends HttpPdu {
 
     /**
      * The HTTP version of the message
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpMethod.java b/http/src/main/java/org/apache/mina/http/api/HttpMethod.java
index 5c05d0b..9c8331b 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpMethod.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpMethod.java
@@ -21,8 +21,7 @@
 
 /**
  * 
- * @author The Apache MINA Project (dev@mina.apache.org)
- * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public enum HttpMethod {
 
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java b/http/src/main/java/org/apache/mina/http/api/HttpPdu.java
similarity index 62%
copy from core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
copy to http/src/main/java/org/apache/mina/http/api/HttpPdu.java
index 6bbc55e..d868a20 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpPdu.java
@@ -6,34 +6,28 @@
  *  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.
- *
+ *  under the License. 
+ *  
  */
-package org.apache.mina.filter.codec;
+package org.apache.mina.http.api;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.api.IoSession;
-
 /**
- * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other protocol level construction.
+ * Marker interface for decoded HTTP elements (P.D.U.: Protocol Data Units)
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * 
  */
-public interface ProtocolEncoder<INPUT /* message type */, OUTPUT> {
+public interface HttpPdu {
 
-    /**
-     * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type <code>OUTPUT</code>.
-     */
-	OUTPUT encode(IoSession session, INPUT message);
+    public ByteBuffer encode(HttpPduEncodingVisitor visitor);
 
-}
\ No newline at end of file
+}
diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java b/http/src/main/java/org/apache/mina/http/api/HttpPduEncodingVisitor.java
similarity index 62%
copy from core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
copy to http/src/main/java/org/apache/mina/http/api/HttpPduEncodingVisitor.java
index 6bbc55e..206ae9b 100644
--- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpPduEncodingVisitor.java
@@ -6,34 +6,33 @@
  *  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.
- *
+ *  under the License. 
+ *  
  */
-package org.apache.mina.filter.codec;
+package org.apache.mina.http.api;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.api.IoSession;
-
 /**
- * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other protocol level construction.
+ * Visitor in charge of encoding an HTTP message into bytes.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * 
  */
-public interface ProtocolEncoder<INPUT /* message type */, OUTPUT> {
+public interface HttpPduEncodingVisitor {
 
-    /**
-     * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type <code>OUTPUT</code>.
-     */
-	OUTPUT encode(IoSession session, INPUT message);
+    public ByteBuffer visit(HttpRequest msg);
 
-}
\ No newline at end of file
+    public ByteBuffer visit(HttpResponse msg);
+
+    public ByteBuffer visit(HttpContentChunk msg);
+
+    public ByteBuffer visit(HttpEndOfContent msg);
+}
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpRequest.java b/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
index 8f734ee..9e51d72 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
@@ -26,7 +26,7 @@
 /**
  * An HTTP request
  * 
- * @author jvermillar
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
  */
 public interface HttpRequest extends HttpMessage {
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpVerb.java b/http/src/main/java/org/apache/mina/http/api/HttpVerb.java
index 0ff719c..5f96028 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpVerb.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpVerb.java
@@ -19,6 +19,9 @@
  */
 package org.apache.mina.http.api;
 
+/**
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public enum HttpVerb {
 
     GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE, CONNECT
diff --git a/http/src/main/java/org/apache/mina/http/api/HttpVersion.java b/http/src/main/java/org/apache/mina/http/api/HttpVersion.java
index cb74472..475abfb 100644
--- a/http/src/main/java/org/apache/mina/http/api/HttpVersion.java
+++ b/http/src/main/java/org/apache/mina/http/api/HttpVersion.java
@@ -22,7 +22,7 @@
 /**
  * Type safe enumeration representing HTTP protocol version
  * 
- * @author The Apache MINA Project (dev@mina.apache.org)
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public enum HttpVersion {
     /**
diff --git a/ldap/src/main/java/org/apache/mina/ldap/LdapCodec.java b/ldap/src/main/java/org/apache/mina/ldap/LdapCodec.java
index 1928f3a..4509867 100644
--- a/ldap/src/main/java/org/apache/mina/ldap/LdapCodec.java
+++ b/ldap/src/main/java/org/apache/mina/ldap/LdapCodec.java
@@ -41,9 +41,9 @@
 import org.apache.directory.shared.ldap.model.message.SearchResultReference;
 import org.apache.mina.api.IdleStatus;
 import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolCodecFilter;
-import org.apache.mina.filter.codec.ProtocolDecoder;
-import org.apache.mina.filter.codec.ProtocolEncoder;
+import org.apache.mina.codec.ProtocolCodecFilter;
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolEncoder;
 import org.apache.mina.filterchain.WriteFilterChainController;
 import org.apache.mina.session.AttributeKey;
 import org.apache.mina.session.WriteRequest;
diff --git a/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolDecoder.java b/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolDecoder.java
index 55c2473..335c384 100644
--- a/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolDecoder.java
+++ b/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolDecoder.java
@@ -33,7 +33,7 @@
 import org.apache.directory.shared.ldap.model.message.Message;
 import org.apache.directory.shared.util.Strings;
 import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolDecoder;
+import org.apache.mina.codec.ProtocolDecoder;
 import org.apache.mina.filterchain.ReadFilterChainController;
 import org.apache.mina.session.AttributeKey;
 import org.slf4j.Logger;
diff --git a/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolEncoder.java b/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolEncoder.java
index 7cee474..2a2b01f 100644
--- a/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolEncoder.java
+++ b/ldap/src/main/java/org/apache/mina/ldap/LdapProtocolEncoder.java
@@ -25,7 +25,7 @@
 import org.apache.directory.shared.ldap.codec.api.LdapEncoder;
 import org.apache.directory.shared.ldap.model.message.Message;
 import org.apache.mina.api.IoSession;
-import org.apache.mina.filter.codec.ProtocolEncoder;
+import org.apache.mina.codec.ProtocolEncoder;
 import org.apache.mina.filterchain.WriteFilterChainController;
 import org.apache.mina.session.WriteRequest;
 
diff --git a/pom.xml b/pom.xml
index 6aab59b..10bbfd2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -105,12 +105,13 @@
 
 
   <modules>
-    <module>core</module>
-    <module>http</module>
-    <module>ldap</module>
-    <module>examples</module>
-    <!-- Temporarilly commented. Should be run with a dedicatd benchmark profile -->
-    <!-- module>benchmarks</module-->
+      <module>core</module>
+      <module>codec</module>
+      <module>http</module>
+      <module>ldap</module>
+      <module>examples</module>
+      <!-- Temporarilly commented. Should be run with a dedicatd benchmark profile -->
+      <!-- module>benchmarks</module-->
   </modules>
 
   <dependencyManagement>