You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by je...@apache.org on 2015/04/12 23:52:34 UTC

[1/8] mina git commit: Initial HTTP2 work (single HTTP2 PDU)

Repository: mina
Updated Branches:
  refs/heads/trunk eddbca617 -> 4173adaef


Initial HTTP2 work (single HTTP2 PDU)


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/99796938
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/99796938
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/99796938

Branch: refs/heads/trunk
Commit: 99796938d772c2028d6168b768975eb2ab965e6a
Parents: 6022738
Author: Jeff MAURY <je...@apache.org>
Authored: Tue Mar 17 20:56:56 2015 +0100
Committer: Jeff MAURY <je...@apache.org>
Committed: Tue Mar 17 20:56:56 2015 +0100

----------------------------------------------------------------------
 core/pom.xml                                    |  12 ++
 .../mina/filter/codec/ProtocolCodecFilter.java  |   4 +-
 .../org/apache/mina/http/HttpRequestImpl.java   |  16 +-
 .../org/apache/mina/http/api/HttpRequest.java   |  14 ++
 http2/Http2Frames.ods                           | Bin 0 -> 16968 bytes
 http2/pom.xml                                   |  56 ++++++
 .../mina/http2/api/BytePartialDecoder.java      |  50 +++++
 .../apache/mina/http2/api/Http2Constants.java   | 193 +++++++++++++++++++
 .../org/apache/mina/http2/api/Http2Frame.java   | 108 +++++++++++
 .../org/apache/mina/http2/api/Http2Header.java  |  39 ++++
 .../mina/http2/api/Http2NameValuePair.java      |  32 +++
 .../org/apache/mina/http2/api/Http2Setting.java |  23 +++
 .../mina/http2/api/IntPartialDecoder.java       |  62 ++++++
 .../mina/http2/api/LongPartialDecoder.java      |  62 ++++++
 .../apache/mina/http2/api/PartialDecoder.java   |  34 ++++
 .../apache/mina/http2/api/StreamMessage.java    |  21 ++
 .../apache/mina/http2/impl/HeadersEncoder.java  |  68 +++++++
 .../apache/mina/http2/impl/Http2Connection.java |  26 +++
 .../mina/http2/impl/Http2FrameDecoder.java      |  88 +++++++++
 .../mina/http2/impl/Http2ProtocolDecoder.java   |  30 +++
 .../mina/http2/api/BytePartialDecoderTest.java  |  51 +++++
 .../api/Htp2ContinuationFrameDecoderTest.java   |  46 +++++
 .../http2/api/Htp2DataFrameDecoderTest.java     |  89 +++++++++
 .../http2/api/Htp2HeadersFrameDecoderTest.java  |  78 ++++++++
 .../http2/api/Htp2PriorityFrameDecoderTest.java |  52 +++++
 .../api/Htp2PushPromiseFrameDecoderTest.java    |  80 ++++++++
 .../api/Htp2RstStreamFrameDecoderTest.java      |  84 ++++++++
 .../http2/api/Htp2SettingsFrameDecoderTest.java |  74 +++++++
 .../http2/api/Htp2UnknownFrameDecoderTest.java  |  47 +++++
 .../api/Http2FrameHeaderPartialDecoderTest.java |  65 +++++++
 .../mina/http2/api/IntPartialDecoderTest.java   |  47 +++++
 31 files changed, 1645 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index d5c7435..3bb9647 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -56,6 +56,18 @@
       <scope>test</scope>
     </dependency>
 
+    <dependency>
+    	<groupId>org.apache.logging.log4j</groupId>
+    	<artifactId>log4j-slf4j-impl</artifactId>
+    	<version>2.1</version>
+    	<scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.logging.log4j</groupId>
+    	<artifactId>log4j-core</artifactId>
+    	<version>2.1</version>
+    	<scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
 

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java
----------------------------------------------------------------------
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 04228e1..b145d9c 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
@@ -149,12 +149,12 @@ public class ProtocolCodecFilter<MESSAGE, ENCODED, ENCODING_STATE, DECODING_STAT
     // ----------- Helper methods ---------------------------------------------
 
     @SuppressWarnings("unchecked")
-    private DECODING_STATE getDecodingState(IoSession session) {
+    protected DECODING_STATE getDecodingState(IoSession session) {
         return (DECODING_STATE) session.getAttribute(DECODER);
     }
 
     @SuppressWarnings("unchecked")
-    private ENCODING_STATE getEncodingState(IoSession session) {
+    protected ENCODING_STATE getEncodingState(IoSession session) {
         return (ENCODING_STATE) session.getAttribute(ENCODER);
     }
 

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
----------------------------------------------------------------------
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 0c78497..91639f4 100644
--- a/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
+++ b/http/src/main/java/org/apache/mina/http/HttpRequestImpl.java
@@ -39,14 +39,14 @@ public class HttpRequestImpl implements HttpRequest {
 
     private final HttpMethod method;
 
-    private final String requestedPath;
+    private final String targetURI;
 
     private final Map<String, String> headers;
 
-    public HttpRequestImpl(HttpVersion version, HttpMethod method, String requestedPath, Map<String, String> headers) {
+    public HttpRequestImpl(HttpVersion version, HttpMethod method, String targetURI, Map<String, String> headers) {
         this.version = version;
         this.method = method;
-        this.requestedPath = requestedPath;
+        this.targetURI = targetURI;
         this.headers = Collections.unmodifiableMap(headers);
     }
 
@@ -62,6 +62,14 @@ public class HttpRequestImpl implements HttpRequest {
      * {@inheritDoc}
      */
     @Override
+    public String getTargetURI() {
+        return targetURI;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public String getContentType() {
         return headers.get("content-type");
     }
@@ -148,7 +156,7 @@ public class HttpRequestImpl implements HttpRequest {
 
         sb.append("HTTP REQUEST METHOD: ").append(method).append('\n');
         sb.append("VERSION: ").append(version).append('\n');
-        sb.append("PATH: ").append(requestedPath).append('\n');
+        sb.append("PATH: ").append(targetURI).append('\n');
 
         sb.append("--- HEADER --- \n");
 

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http/src/main/java/org/apache/mina/http/api/HttpRequest.java
----------------------------------------------------------------------
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 9e51d72..d248770 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
@@ -62,4 +62,18 @@ public interface HttpRequest extends HttpMessage {
      * @return the method
      */
     HttpMethod getMethod();
+    
+    /**
+     * Return the HTTP protocol version of the request {@link HttpVersion}.
+     * 
+     * @return the HTTP version
+     */
+    HttpVersion getProtocolVersion();
+    
+    /**
+     * Return the target URI of the request.
+     * 
+     * @return the target URI
+     */
+    String getTargetURI();
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/Http2Frames.ods
----------------------------------------------------------------------
diff --git a/http2/Http2Frames.ods b/http2/Http2Frames.ods
new file mode 100644
index 0000000..c2ca426
Binary files /dev/null and b/http2/Http2Frames.ods differ

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/pom.xml
----------------------------------------------------------------------
diff --git a/http2/pom.xml b/http2/pom.xml
new file mode 100644
index 0000000..ecce674
--- /dev/null
+++ b/http2/pom.xml
@@ -0,0 +1,56 @@
+<?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-M3-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>mina-http2</artifactId>
+  <name>Apache MINA HTTP2 ${project.version}</name>
+  <packaging>jar</packaging>
+  <description>Low level HTTP2 codec for building simple &amp; fast HTTP2 server and clients</description>
+
+  <properties>
+    <symbolicName>${project.groupId}.http2</symbolicName>
+    <exportedPackage>${project.groupId}.http2.api</exportedPackage>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mina-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>mina-http</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>com.twitter</groupId>
+    	<artifactId>hpack</artifactId>
+    	<version>0.10.0</version>
+    </dependency>
+  </dependencies>
+</project>
+

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
new file mode 100644
index 0000000..11582de
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
@@ -0,0 +1,50 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class BytePartialDecoder implements PartialDecoder<byte[]> {
+    private int offset;
+    private byte[] value;
+    
+    /**
+     * Decode an byte array.
+     * 
+     * @param size the size of the byte array to decode
+     */
+    public BytePartialDecoder(int size) {
+        this.offset = 0;
+        this.value = new byte[size];
+    }
+
+    public boolean consume(ByteBuffer buffer) {
+        if (value.length - offset == 0) {
+            throw new IllegalStateException();
+        }
+        int length = Math.min(buffer.remaining(), value.length - offset);
+        buffer.get(value, offset, length);
+        offset += length;
+        return value.length - offset == 0;
+    }
+    
+    public byte[] getValue() {
+        if (value.length - offset > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /** 
+     * {@inheritDoc}
+     */
+    @Override
+    public void reset() {
+        offset = 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
new file mode 100644
index 0000000..ba8a8fe
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
@@ -0,0 +1,193 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.charset.Charset;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public final class Http2Constants {
+    /**
+     * Mask used when decoding on a 4 byte boundary, masking the reserved
+     * bit
+     */
+    public static final int HTTP2_31BITS_MASK = 0x7FFFFFFF;
+    
+    /**
+     * Mask used when decoding on a 4 byte boundary, retrieving
+     * the exclusive bit
+     */
+    public static final int HTTP2_EXCLUSIVE_MASK = 0x80000000;
+
+    /*
+     * Frame types
+     */
+    /**
+     * DATA frame
+     */
+    public static final int FRAME_TYPE_DATA = 0x00;
+    
+    /**
+     * HEADERS frame
+     */
+    public static final int FRAME_TYPE_HEADERS = 0x01;
+    
+    /**
+     * PRIORITY frame
+     */
+    public static final int FRAME_TYPE_PRIORITY = 0x02;
+    
+    /**
+     * RST_STREAM frame
+     */
+    public static final int FRAME_TYPE_RST_STREAM = 0x03;
+    
+    /**
+     * SETTINGS stream
+     */
+    public static final int FRAME_TYPE_SETTINGS = 0x04;
+    
+    /**
+     * PUSH_PROMISE frame
+     */
+    public static final int FRAME_TYPE_PUSH_PROMISE = 0x05;
+    
+    /**
+     * PING frame
+     */
+    public static final int FRAME_TYPE_PING = 0x06;
+    
+    /**
+     * GOAWAY frame
+     */
+    public static final int FRAME_TYPE_GOAWAY = 0x07;
+    
+    /**
+     * WINDOW_UPDATE frame
+     */
+    public static final int FRAME_TYPE_WINDOW_UPDATE = 0x08;
+    
+    /**
+     * CONTINUATION frame
+     */
+    public static final int FRAME_TYPE_CONTINUATION = 0x09;
+    
+    /*
+     * Flags
+     */
+    public static final byte FLAGS_END_STREAM = 0x01;
+    
+    public static final byte FLAGS_ACK = 0x01;
+    
+    public static final byte FLAGS_END_HEADERS = 0x04;
+    
+    public static final byte FLAGS_PADDING = 0x08;
+    
+    public static final byte FLAGS_PRIORITY = 0x20;
+    
+    /*
+     * Error codes
+     */
+    /**
+     * The associated condition is not as a result of an error. For example, a GOAWAY might include this code to indicate graceful shutdown of a connection.
+     */
+    public static final int NO_ERROR = 0x0;
+    
+    /**
+     * The endpoint detected an unspecific protocol error. This error is for use when a more specific error code is not available.
+     */
+    public static final int PROTOCOL_ERROR = 0x1;
+
+    /**
+     * The endpoint encountered an unexpected internal error.
+     */
+    public static final int INTERNAL_ERROR = 0x2;
+    
+    /**
+     * The endpoint detected that its peer violated the flow control protocol.
+     */
+    public static final int FLOW_CONTROL_ERROR = 0x3;
+
+    /**
+     * The endpoint sent a SETTINGS frame, but did not receive a response in a timely manner. See Settings Synchronization (Section 6.5.3).
+     */
+    public static final int SETTINGS_TIMEOUT = 0x4;
+
+    /**
+     * The endpoint received a frame after a stream was half closed.
+     */
+    public static final int STREAM_CLOSED = 0x5;
+
+    /**
+     * The endpoint received a frame with an invalid size.
+     */
+    public static final int FRAME_SIZE_ERROR = 0x6;
+
+    /**
+     * The endpoint refuses the stream prior to performing any application processing, see Section 8.1.4 for details.
+     */
+    public static final int REFUSED_STREAM = 0x7;
+     
+    /**
+     * Used by the endpoint to indicate that the stream is no longer needed.
+     */
+    public static final int CANCEL = 0x8;
+
+    /**
+     * The endpoint is unable to maintain the header compression context for the connection.
+     */
+    public static final int COMPRESSION_ERROR = 0x9;
+    
+    /**
+     * The connection established in response to a CONNECT request (Section 8.3) was reset or abnormally closed.
+     */
+    public static final int CONNECT_ERROR = 0xa;
+    
+    /**
+     * The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load.
+     */
+    public static final int ENHANCE_YOUR_CALM = 0xb;
+
+    /**
+     * The underlying transport has properties that do not meet minimum security requirements (see Section 9.2).
+     */
+    public static final int INADEQUATE_SECURITY = 0xc;
+
+    /**
+     * The endpoint requires that HTTP/1.1 be used instead of HTTP/2.
+     */
+    public static final int HTTP_1_1_REQUIRED = 0xd;
+        
+    /*
+     * Settings related stuff
+     */
+    public static final int SETTINGS_HEADER_TABLE_SIZE = 0x01;
+    
+    public static final int SETTINGS_HEADER_TABLE_SIZE_DEFAULT = 4096;
+    
+    public static final int SETTINGS_ENABLE_PUSH = 0x02;
+    
+    public static final int SETTINGS_ENABLE_PUSH_DEFAULT = 1;
+    
+    public static final int SETTINGS_MAX_CONCURRENT_STREAMS = 0x03;
+    
+    public static final int SETTINGS_MAX_CONCURRENT_STREAMS_DEFAULT = Integer.MAX_VALUE;
+    
+    public static final int SETTINGS_INITIAL_WINDOW_SIZE = 0x04;
+    
+    public static final int SETTINGS_INITIAL_WINDOW_SIZE_DEFAULT = 65535;
+    
+    public static final int SETTINGS_MAX_FRAME_SIZE = 0x05;
+    
+    public static final int SETTINGS_MAX_FRAME_SIZE_DEFAULT = 16384;
+    
+    public static final int SETTINGS_MAX_HEADER_LIST_SIZE = 0x06;
+    
+    public static final int SETTINGS_MAX_HEADER_LIST_SIZE_DEFAULT = Integer.MAX_VALUE;
+    
+    public static final Charset US_ASCII_CHARSET = Charset.forName("US-ASCII");
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
new file mode 100644
index 0000000..b6a3ed2
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
@@ -0,0 +1,108 @@
+/*
+ *  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.http2.api;
+
+/**
+ * An SPY frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2Frame {
+    private int length;
+    
+    private short type;
+    
+    private short flags;
+    
+    private int streamID;
+    
+    public byte[] payload;
+
+    /**
+     * @return the length
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * @param length the length to set
+     */
+    public void setLength(int length) {
+        this.length = length;
+    }
+
+    /**
+     * @return the type
+     */
+    public short getType() {
+        return type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    public void setType(short type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the flags
+     */
+    public short getFlags() {
+        return flags;
+    }
+
+    /**
+     * @param flags the flags to set
+     */
+    public void setFlags(short flags) {
+        this.flags = flags;
+    }
+
+    /**
+     * @return the streamID
+     */
+    public int getStreamID() {
+        return streamID;
+    }
+
+    /**
+     * @param streamID the streamID to set
+     */
+    public void setStreamID(int streamID) {
+        this.streamID = streamID;
+    }
+
+    /**
+     * @return the payload
+     */
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    /**
+     * @param payload the payload to set
+     */
+    public void setPayload(byte[] payload) {
+        this.payload = payload;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
new file mode 100644
index 0000000..c0e5ab8
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
@@ -0,0 +1,39 @@
+package org.apache.mina.http2.api;
+
+public enum Http2Header {
+
+    METHOD(":method"),
+    
+    PATH(":path"),
+    
+    STATUS(":status"),
+    
+    AUTHORITY(":authority"),
+    
+    SCHEME(":scheme");
+    
+    private final String name;
+    
+    private Http2Header(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    /**
+     * Check whether a header is an HTTP2 reserved one.
+     * 
+     * @param name the name of the HTTP header
+     * @return true is this is a reserved HTTP2 header, false otherwise
+     */
+    public static boolean isHTTP2ReservedHeader(String name) {
+        for(Http2Header header : Http2Header.values()) {
+            if (header.getName().equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java b/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
new file mode 100644
index 0000000..6e8572d
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
@@ -0,0 +1,32 @@
+package org.apache.mina.http2.api;
+
+public class Http2NameValuePair {
+    private String name;
+    private String value;
+    
+    /**
+     * Build a name/value pair given the name and value.
+     * 
+     * @param name the name of the pair
+     * @param value the value of the pair
+     */
+    public Http2NameValuePair(String name, String value) {
+        this.name = name;
+        this.value = value;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    public String getValue() {
+        return value;
+    }
+    public void setValue(String value) {
+        this.value = value;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
new file mode 100644
index 0000000..acccb65
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
@@ -0,0 +1,23 @@
+package org.apache.mina.http2.api;
+
+public class Http2Setting {
+    private int ID;
+
+    private long value;
+
+    public int getID() {
+        return ID;
+    }
+
+    public void setID(int iD) {
+        ID = iD;
+    }
+
+    public long getValue() {
+        return value;
+    }
+
+    public void setValue(long value) {
+        this.value = value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
new file mode 100644
index 0000000..5e6076d
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
@@ -0,0 +1,62 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class IntPartialDecoder implements PartialDecoder<Integer> {
+    private int size;
+    private int remaining;
+    private int value;
+    
+    /**
+     * Decode an integer whose size is different from the standard 4.
+     * 
+     * @param size the size (1,2,3,4) to decode
+     */
+    public IntPartialDecoder(int size) {
+        this.remaining = size;
+        this.size = size;
+    }
+
+    /**
+     * Decode a 4 bytes integer 
+     */
+    public IntPartialDecoder() {
+        this(4);
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        if (remaining == 0) {
+            throw new IllegalStateException();
+        }
+        while (remaining > 0 && buffer.hasRemaining()) {
+            value = (value << 8) + (buffer.get() & 0x00FF);
+            --remaining;
+        }
+        return remaining == 0;
+    }
+    
+    public Integer getValue() {
+        if (remaining > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        remaining = size;
+        value = 0;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
new file mode 100644
index 0000000..dae0c2f
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
@@ -0,0 +1,62 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class LongPartialDecoder implements PartialDecoder<Long> {
+    private int size;
+    private int remaining;
+    private long value;
+    
+    /**
+     * Decode a long integer whose size is different from the standard 8.
+     * 
+     * @param size the size (1 to 8) to decode
+     */
+    public LongPartialDecoder(int size) {
+        this.remaining = size;
+        this.size = size;
+    }
+
+    /**
+     * Decode a 8 bytes long integer 
+     */
+    public LongPartialDecoder() {
+        this(8);
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        if (remaining == 0) {
+            throw new IllegalStateException();
+        }
+        while (remaining > 0 && buffer.hasRemaining()) {
+            value = (value << 8) + (buffer.get() & 0x00FF);
+            --remaining;
+        }
+        return remaining == 0;
+    }
+    
+    public Long getValue() {
+        if (remaining > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        remaining = size;
+        value = 0;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
new file mode 100644
index 0000000..070b7ce
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
@@ -0,0 +1,34 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public interface PartialDecoder<T> {
+    /**
+     * Consume the buffer so as to decode a value. Not all the input buffer
+     * may be consumed.
+     * 
+     * @param buffer the input buffer to decode
+     * @return true if a value is available false if more data is requested
+     */
+    public boolean consume(ByteBuffer buffer);
+    
+    /**
+     * Return the decoded value.
+     * 
+     * @return the decoded value
+     */
+    public T getValue();
+    
+    /**
+     * Reset the internal state of the decoder to that new decoding can take place.
+     */
+    public void reset();
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java b/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
new file mode 100644
index 0000000..41f85b0
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
@@ -0,0 +1,21 @@
+package org.apache.mina.http2.api;
+
+/**
+ * Marker interface for messages that are attached to a specific stream.
+ * That may not be a start of HTTP PDU (request or response) as they are the
+ * one that creates new streams.
+ * The use of this interface is not mandatory but not using it will cause
+ * request and responses to be pipelined.
+ * 
+ * @author jeffmaury
+ *
+ */
+public interface StreamMessage {
+
+    /**
+     * Return the stream ID the message is attached to.
+     * 
+     * @return the stream ID
+     */
+    public int getStreamID();
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java b/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
new file mode 100644
index 0000000..3afb72d
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
@@ -0,0 +1,68 @@
+package org.apache.mina.http2.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.mina.http.api.HttpMessage;
+import org.apache.mina.http.api.HttpRequest;
+import org.apache.mina.http.api.HttpResponse;
+import org.apache.mina.http2.api.Http2Header;
+
+import com.twitter.hpack.Encoder;
+
+import static org.apache.mina.http2.api.Http2Constants.US_ASCII_CHARSET;
+
+public class HeadersEncoder {
+
+    private final Encoder encoder;
+    
+    public HeadersEncoder(int maxHeaderTableSize) {
+        encoder = new Encoder(maxHeaderTableSize);
+    }
+    
+    private static String getMethod(HttpMessage message) {
+        String method = null;
+        if (message instanceof HttpRequest) {
+            ((HttpRequest)message).getMethod().name();
+        }
+        return method;
+    }
+
+    private static String getPath(HttpMessage message) {
+        String path = null;
+        if (message instanceof HttpRequest) {
+            path = ((HttpRequest)message).getTargetURI();
+        }
+        return path;
+    }
+
+    public void encode(HttpMessage message, OutputStream out) throws IOException {
+        String value = getMethod(message);
+        if (value != null) {
+            encoder.encodeHeader(out,
+                                 Http2Header.METHOD.getName().getBytes(US_ASCII_CHARSET),
+                                 value.getBytes(US_ASCII_CHARSET),
+                                 false);
+        }
+        value = getPath(message);
+        if (value != null) {
+            encoder.encodeHeader(out,
+                                 Http2Header.PATH.getName().getBytes(US_ASCII_CHARSET),
+                                 value.getBytes(US_ASCII_CHARSET),
+                                 false);
+        }
+        if (message instanceof HttpResponse) {
+            encoder.encodeHeader(out,
+                                 Http2Header.STATUS.getName().getBytes(US_ASCII_CHARSET),
+                                 Integer.toString(((HttpResponse)message).getStatus().code()).getBytes(US_ASCII_CHARSET),
+                                 false);
+        }
+        for(String name : message.getHeaders().keySet()) {
+            if (!Http2Header.isHTTP2ReservedHeader(name)) {
+                encoder.encodeHeader(out,
+                                     name.getBytes(US_ASCII_CHARSET),
+                                     message.getHeaders().get(name).getBytes(US_ASCII_CHARSET),
+                                     false);
+            }
+        }
+     }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
new file mode 100644
index 0000000..3019b20
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
@@ -0,0 +1,26 @@
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.Http2Frame;
+
+public class Http2Connection {
+
+    private final Http2FrameDecoder decoder = new Http2FrameDecoder();
+
+    /**
+     * Decode the incoming message and if all frame data has been received,
+     * then the decoded frame will be returned. Otherwise, null is returned.
+     * 
+     * @param input the input buffer to decode
+     * @return the decoder HTTP2 frame or null if more data are required
+     */
+    public Http2Frame decode(ByteBuffer input) {
+        Http2Frame frame = null;
+        if (decoder.consume(input)) {
+            frame = decoder.getValue();
+            decoder.reset();
+        }
+        return frame;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
new file mode 100644
index 0000000..ba32afc
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
@@ -0,0 +1,88 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2Frame;
+import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
+
+    private static enum State {
+        LENGTH_TYPE_FLAGS,
+        STREAMID,
+        PAYLOAD
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private Http2Frame frame;
+    
+    private boolean frameComplete;
+
+    public Http2FrameDecoder() {
+        reset();
+    }
+    
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while (!frameComplete && buffer.remaining() > 0) {
+            switch (state) {
+            case LENGTH_TYPE_FLAGS:
+                if (decoder.consume(buffer)) {
+                    long val = ((LongPartialDecoder)decoder).getValue();
+                    frame.setLength((int) ((val >> 16) & 0xFFFFFFL));
+                    frame.setType((short) ((val >> 8) & 0xFF));
+                    frame.setFlags((short) (val & 0xFF));
+                    state = State.STREAMID;
+                    decoder = new LongPartialDecoder(4);
+                }
+                break;
+            case STREAMID:
+                if (decoder.consume(buffer)) {
+                    frame.setStreamID((int) (((LongPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK));
+                    if (frame.getLength() > 0) {
+                        decoder = new BytePartialDecoder(frame.getLength());
+                        state = State.PAYLOAD;
+                    } else {
+                       frameComplete = true;
+                    }
+                }
+                break;
+            case PAYLOAD:
+                if (decoder.consume(buffer)) {
+                    frame.setPayload(((BytePartialDecoder)decoder).getValue());
+                    frameComplete = true;
+                }
+                break;
+            }
+        }
+        return frameComplete;
+    }
+
+    @Override
+    public Http2Frame getValue() {
+        return frame;
+    }
+
+    @Override
+    public void reset() {
+        state = State.LENGTH_TYPE_FLAGS;
+        decoder = new LongPartialDecoder(5);
+        frame = new Http2Frame();
+        frameComplete = false;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
new file mode 100644
index 0000000..8217166
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
@@ -0,0 +1,30 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.http2.api.Http2Frame;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2ProtocolDecoder implements ProtocolDecoder<ByteBuffer, Http2Frame, Http2Connection> {
+
+    @Override
+    public Http2Connection createDecoderState() {
+        return new Http2Connection();
+    }
+
+    @Override
+    public Http2Frame decode(ByteBuffer input, Http2Connection context) {
+        return context.decode(input);
+    }
+
+    @Override
+    public void finishDecode(Http2Connection context) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
new file mode 100644
index 0000000..7d09d11
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
@@ -0,0 +1,51 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.junit.Test;
+
+public class BytePartialDecoderTest {
+
+    private static final byte[] SAMPLE_VALUE_1 = new byte[] {0x74, 0x18, 0x4F, 0x68};
+    private static final byte[] SAMPLE_VALUE_2 = new byte[] {0x74, 0x18, 0x4F, 0x68, 0x0F};
+
+    @Test
+    public void checkSimpleValue() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_1);
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+    }
+    
+    @Test
+    public void checkNotenoughData() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+    }
+
+    @Test
+    public void checkTooMuchData() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_2);
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+        assertEquals(1, buffer.remaining());
+    }
+
+    @Test
+    public void checkDecodingIn2Steps() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[0], SAMPLE_VALUE_2[1]});
+        assertFalse(decoder.consume(buffer));
+        buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[2], SAMPLE_VALUE_2[3], SAMPLE_VALUE_2[4]});
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+        assertEquals(1, buffer.remaining());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
new file mode 100644
index 0000000..12a661c
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
@@ -0,0 +1,46 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2ContinuationFrameDecoderTest {
+
+    @Test
+    public void checkContinuationNoHeaderFragment() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x09, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32 /*streamID*/});
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getHeaderBlockFragment().length);
+    }
+    
+    @Test
+    public void checkContinuationWithHeaderFragment() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0A, /*length*/
+                                                        0x09, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
+                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/});
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getHeaderBlockFragment().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getHeaderBlockFragment());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
new file mode 100644
index 0000000..f6dad67
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
@@ -0,0 +1,89 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2DataFrameDecoderTest {
+
+    @Test
+    public void checkDataNoPayloadNoPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32 /*streamID*/});
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getData().length);
+        assertEquals(0, frame.getPadding().length);
+    }
+    
+    @Test
+    public void checkDataWithPayloadNoPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0A, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
+                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/});
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(0, frame.getPadding().length);
+    }
+
+    @Test
+    public void checkDataNoPayloadPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x03, /*length*/
+                                                        0x00, /*type*/
+                                                        0x08, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
+                                                        0x02, 0x0E, 0x28 /*padding*/});
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(3, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0,frame.getData().length);
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E,  0x28}, frame.getPadding());
+    }
+    
+    @Test
+    public void checkDataWithPayloadPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0D, /*length*/
+                                                        0x00, /*type*/
+                                                        0x08, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
+                                                        0x02, /*padLength*/
+                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, /*data*/
+                                                        0x0E, 0x28 /*padding*/});
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(13, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E, 0x28}, frame.getPadding());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
new file mode 100644
index 0000000..e974ce5
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
@@ -0,0 +1,78 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2HeadersFrameDecoderTest {
+
+    @Test
+    public void checkHeadersFrameWithNotPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x01, /*length*/
+                                                        0x01, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x01, /*streamID*/
+                                                        (byte) 0x0082 /*headerFragment*/});
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(1, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    
+    @Test
+    public void checkHeadersFramePaddingPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x17, /*length*/
+                                                        0x01, /*type*/
+                                                        0x28, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
+                                                        0x10, /*padding length*/
+                                                        (byte)0x0080, 0x00, 0x00, 0x14, /*stream dependency*/
+                                                        0x09, /*weight*/
+                                                        (byte) 0x0082, /*headerFragment*/
+                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(23, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x28, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(10,  frame.getWeight());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void checkHeadersFramePaddingNoPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x12, /*length*/
+                                                        0x01, /*type*/
+                                                        0x08, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
+                                                        0x10, /*padding length*/
+                                                        (byte) 0x0082, /*headerFragment*/
+                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(18, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
new file mode 100644
index 0000000..cd0c049
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
@@ -0,0 +1,52 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2PriorityFrameDecoderTest {
+
+    @Test
+    public void checkPriorityFrameNoExclusive() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
+                                                        0x02, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x00, 0x00, 0x01, 0x00, /*streamDependency*/
+                                                        0x01});
+        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertFalse(frame.getExclusiveMode());
+    }
+
+    @Test
+    public void checkPriorityFrameExclusive() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
+                                                        0x02, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        (byte) 0x0080, 0x00, 0x01, 0x00, /*streamDependency*/
+                                                        0x01});
+        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertTrue(frame.getExclusiveMode());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
new file mode 100644
index 0000000..30b7299
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
@@ -0,0 +1,80 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2PushPromiseFrameDecoderTest {
+
+    @Test
+    public void checkHeadersFrameWithNotPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
+                                                        0x01, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x01, /*streamID*/
+                                                        0x00, 0x00, 0x01, 0x00, /*promisedStreamID*/
+                                                        (byte) 0x0082 /*headerFragment*/});
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(5, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getPromisedStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    
+    @Test
+    public void checkHeadersFramePaddingPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x17, /*length*/
+                                                        0x01, /*type*/
+                                                        0x28, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
+                                                        0x10, /*padding length*/
+                                                        (byte)0x0080, 0x00, 0x00, 0x14, /*stream dependency*/
+                                                        0x09, /*weight*/
+                                                        (byte) 0x0082, /*headerFragment*/
+                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(23, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x28, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(10,  frame.getWeight());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void checkHeadersFramePaddingNoPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x12, /*length*/
+                                                        0x01, /*type*/
+                                                        0x08, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
+                                                        0x10, /*padding length*/
+                                                        (byte) 0x0082, /*headerFragment*/
+                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(18, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
new file mode 100644
index 0000000..717b0f6
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
@@ -0,0 +1,84 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2RstStreamFrameDecoderTest {
+
+    @Test
+    public void checkRstStreamNoExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x04, /*length*/
+                                                        0x03, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x00, 0x00, 0x01, 0x00, /*errorCode*/});
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+
+    @Test
+    public void checkRstStreamHighestValueNoExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x04, /*length*/
+                                                        0x03, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/});
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+
+    @Test
+    public void checkRstStreamWithExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
+                                                        0x03, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x00, 0x00, 0x01, 0x00, /*errorCode*/
+                                                        0x0E, 0x28});
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+
+    @Test
+    public void checkRstStreamHighestValueWithExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
+                                                        0x03, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/
+                                                        0x0E, 0x28});
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
new file mode 100644
index 0000000..073464e
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
@@ -0,0 +1,74 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2SettingsFrameDecoderTest {
+
+    @Test
+    public void checkRstStream() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
+                                                        0x04, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x00, 0x01, /*ID*/
+                                                        0x01, 0x02, 0x03, 0x04, /*value*/});
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+
+    @Test
+    public void checkRstStreamHighestID() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
+                                                        0x04, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        (byte) 0xFF, (byte) 0xFF, /*ID*/
+                                                        0x01, 0x02, 0x03, 0x04, /*value*/});
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(0x00FFFF, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+ 
+    @Test
+    public void checkRstStreamHighestValue() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
+                                                        0x04, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x00, 0x01, /*ID*/
+                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*value*/});
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0xFFFFFFFFL, setting.getValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
new file mode 100644
index 0000000..ffc6149
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
@@ -0,0 +1,47 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+public class Htp2UnknownFrameDecoderTest {
+
+    @Test
+    public void checkUnknownFrame() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x02, /*length*/
+                                                        (byte) 0x00FF, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
+                                                        0x0E, 0x18});
+        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(2, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(2, frame.getPayload().length);
+        assertArrayEquals(new byte[] {0x0E,  0x18}, frame.getPayload());
+    }
+
+    @Test
+    public void checkUnknownFrameWithoutPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        (byte) 0x00FF, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x20 /*streamID*/});
+        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0, frame.getPayload().length);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
new file mode 100644
index 0000000..bda0c77
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
@@ -0,0 +1,65 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.junit.Test;
+
+public class Http2FrameHeaderPartialDecoderTest {
+
+    @Test
+    public void checkStandardValue() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x01 /*streamID*/});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(0, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+    }
+
+    @Test
+    public void checkReservedBitIsNotTransmitted() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        (byte)0x80, 0x00, 0x00, 0x01 /*streamID*/});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(0, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+    }
+    
+    @Test
+    public void checkPayLoadIsTransmitted() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x01, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        (byte)0x80, 0x00, 0x00, 0x01, /*streamID*/
+                                                        0x40});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(1, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+        assertEquals(1, header.getPayload().length);
+        assertEquals(0x40, header.getPayload()[0]       );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/99796938/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
new file mode 100644
index 0000000..78c9125
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
@@ -0,0 +1,47 @@
+package org.apache.mina.http2.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.junit.Test;
+
+public class IntPartialDecoderTest {
+
+    @Test
+    public void checkSimpleValue() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+    }
+    
+    @Test
+    public void checkNotenoughData() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+    }
+
+    @Test
+    public void checkTooMuchData() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+        assertEquals(1, buffer.remaining());
+    }
+
+    @Test
+    public void checkDecodingIn2Steps() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+        buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+        assertEquals(1, buffer.remaining());
+    }
+}


[8/8] mina git commit: New HTTP2 module (low level)

Posted by je...@apache.org.
New HTTP2 module (low level)


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/4173adae
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/4173adae
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/4173adae

Branch: refs/heads/trunk
Commit: 4173adaef73c4e947736a83439e5f73615b2eb29
Parents: eddbca6 8ca3d89
Author: Jeff MAURY <je...@apache.org>
Authored: Sun Apr 12 23:51:32 2015 +0200
Committer: Jeff MAURY <je...@apache.org>
Committed: Sun Apr 12 23:51:32 2015 +0200

----------------------------------------------------------------------
 core/pom.xml                                    |  12 +
 .../mina/filter/codec/ProtocolCodecFilter.java  |   4 +-
 .../org/apache/mina/http/HttpRequestImpl.java   |  16 +-
 .../org/apache/mina/http/api/HttpRequest.java   |  14 +
 http2/pom.xml                                   |  56 +++
 .../apache/mina/http2/api/Http2Constants.java   | 216 +++++++++
 .../mina/http2/api/Http2ContinuationFrame.java  |  79 ++++
 .../apache/mina/http2/api/Http2DataFrame.java   | 108 +++++
 .../org/apache/mina/http2/api/Http2Frame.java   | 179 +++++++
 .../apache/mina/http2/api/Http2GoAwayFrame.java | 116 +++++
 .../org/apache/mina/http2/api/Http2Header.java  |  62 +++
 .../mina/http2/api/Http2HeadersFrame.java       | 176 +++++++
 .../mina/http2/api/Http2NameValuePair.java      |  55 +++
 .../apache/mina/http2/api/Http2PingFrame.java   |  77 +++
 .../mina/http2/api/Http2PriorityFrame.java      | 115 +++++
 .../mina/http2/api/Http2PushPromiseFrame.java   | 128 +++++
 .../mina/http2/api/Http2RstStreamFrame.java     |  76 +++
 .../org/apache/mina/http2/api/Http2Setting.java |  57 +++
 .../mina/http2/api/Http2SettingsFrame.java      |  80 ++++
 .../mina/http2/api/Http2UnknownFrame.java       |  75 +++
 .../mina/http2/api/Http2WindowUpdateFrame.java  |  77 +++
 .../mina/http2/codec/Http2ProtocolDecoder.java  |  47 ++
 .../mina/http2/codec/Http2ProtocolEncoder.java  |  42 ++
 .../mina/http2/impl/BytePartialDecoder.java     |  66 +++
 .../apache/mina/http2/impl/HeadersEncoder.java  |  91 ++++
 .../apache/mina/http2/impl/Http2Connection.java | 118 +++++
 .../impl/Http2ContinuationFrameDecoder.java     |  66 +++
 .../mina/http2/impl/Http2DataFrameDecoder.java  | 110 +++++
 .../mina/http2/impl/Http2FrameDecoder.java      |  67 +++
 .../impl/Http2FrameHeadePartialDecoder.java     | 123 +++++
 .../http2/impl/Http2GoAwayFrameDecoder.java     |  96 ++++
 .../http2/impl/Http2HeadersFrameDecoder.java    | 130 ++++++
 .../mina/http2/impl/Http2PingFrameDecoder.java  |  61 +++
 .../http2/impl/Http2PriorityFrameDecoder.java   |  96 ++++
 .../impl/Http2PushPromiseFrameDecoder.java      | 114 +++++
 .../http2/impl/Http2RstStreamFrameDecoder.java  |  85 ++++
 .../http2/impl/Http2SettingsFrameDecoder.java   |  79 ++++
 .../http2/impl/Http2UnknownFrameDecoder.java    |  68 +++
 .../impl/Http2WindowUpdateFrameDecoder.java     |  86 ++++
 .../mina/http2/impl/IntPartialDecoder.java      |  78 ++++
 .../mina/http2/impl/LongPartialDecoder.java     |  78 ++++
 .../apache/mina/http2/impl/PartialDecoder.java  |  50 ++
 .../java/org/apache/mina/http2/Http2Test.java   |  35 ++
 .../org/apache/mina/http2/TestMessages.java     | 465 +++++++++++++++++++
 .../http2/api/Http2ContinuationFrameTest.java   |  77 +++
 .../mina/http2/api/Http2DataFrameTest.java      | 122 +++++
 .../mina/http2/api/Http2GoAwayFrameTest.java    | 134 ++++++
 .../mina/http2/api/Http2HeadersFrameTest.java   | 105 +++++
 .../mina/http2/api/Http2PingFrameTest.java      |  95 ++++
 .../mina/http2/api/Http2PriorityFrameTest.java  |  82 ++++
 .../http2/api/Http2PushPromiseFrameTest.java    |  83 ++++
 .../mina/http2/api/Http2RstStreamFrameTest.java | 103 ++++
 .../api/Http2SettingsFrameDecoderTest.java      | 105 +++++
 .../mina/http2/api/Http2UnknownFrameTest.java   |  79 ++++
 .../http2/codec/Http2ProtocolDecoderTest.java   | 458 ++++++++++++++++++
 .../http2/codec/Http2ProtocolEncoderTest.java   | 200 ++++++++
 .../mina/http2/impl/BytePartialDecoderTest.java |  75 +++
 .../Http2FrameHeaderPartialDecoderTest.java     |  87 ++++
 .../mina/http2/impl/IntPartialDecoderTest.java  |  71 +++
 pom.xml                                         |   1 +
 60 files changed, 5900 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[6/8] mina git commit: Complete low level HTTP2

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameHeadePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameHeadePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameHeadePartialDecoder.java
new file mode 100644
index 0000000..41e8817
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameHeadePartialDecoder.java
@@ -0,0 +1,123 @@
+/*
+ *  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.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2FrameHeadePartialDecoder implements PartialDecoder<Http2FrameHeadePartialDecoder.Http2FrameHeader> {
+    public static class Http2FrameHeader {
+        private int length;
+        private short type;
+        private byte flags;
+        private int streamID;
+
+        public int getLength() {
+            return length;
+        }
+       
+        public void setLength(int length) {
+            this.length = length;
+        }
+        
+        public short getType() {
+            return type;
+        }
+        
+        public void setType(short type) {
+            this.type = type;
+        }
+        
+        public byte getFlags() {
+            return flags;
+        }
+        
+        public void setFlags(byte flags) {
+            this.flags = flags;
+        }
+        
+        public int getStreamID() {
+            return streamID;
+        }
+        
+        public void setStreamID(int streamID) {
+            this.streamID = streamID;
+        }
+    }
+    
+    private static enum State {
+        LENGTH,
+        TYPE_FLAGS,
+        STREAMID,
+        END
+    }
+    
+    private State state;
+    private PartialDecoder<?> decoder;
+    private Http2FrameHeader value;
+    
+    public Http2FrameHeadePartialDecoder() {
+        reset();
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        while (buffer.hasRemaining() && state != State.END) {
+            if (decoder.consume(buffer)) {
+                switch (state) {
+                case LENGTH:
+                    value.setLength(((IntPartialDecoder)decoder).getValue().intValue());
+                    decoder = new BytePartialDecoder(2);
+                    state = State.TYPE_FLAGS;
+                    break;
+                case TYPE_FLAGS:
+                    value.setType(((BytePartialDecoder)decoder).getValue()[0]);
+                    value.setFlags(((BytePartialDecoder)decoder).getValue()[1]);
+                    decoder = new IntPartialDecoder(4);
+                    state = State.STREAMID;
+                    break;
+                case STREAMID:
+                    value.setStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    state = State.END;
+                    break;
+                }
+            }
+        }
+        return state == State.END;
+    }
+    
+    public Http2FrameHeader getValue() {
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        state = State.LENGTH;
+        decoder = new IntPartialDecoder(3);
+        value = new Http2FrameHeader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
index 86187b2..e00007f 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
@@ -1,20 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2GoAwayFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2GoAwayFrame.Http2GoAwayFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2GoAwayFrameDecoder extends Http2FrameDecoder {
 
@@ -28,7 +42,7 @@ public class Http2GoAwayFrameDecoder extends Http2FrameDecoder {
     
     private PartialDecoder<?> decoder;
     
-    private Builder builder = new Builder();
+    private Http2GoAwayFrameBuilder builder = new Http2GoAwayFrameBuilder();
     
     public Http2GoAwayFrameDecoder(Http2FrameHeader header) {
         super(header);
@@ -48,11 +62,11 @@ public class Http2GoAwayFrameDecoder extends Http2FrameDecoder {
                 if (decoder.consume(buffer)) {
                     builder.lastStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
                     state = State.CODE;
-                    decoder.reset();
+                    decoder = new LongPartialDecoder(4);
                 }
             case CODE:
                 if (decoder.consume(buffer)) {
-                    builder.errorCode(((IntPartialDecoder)decoder).getValue());
+                    builder.errorCode(((LongPartialDecoder)decoder).getValue());
                     if (getHeader().getLength() > 8) {
                         state = State.EXTRA;
                         decoder = new BytePartialDecoder(getHeader().getLength() - 8);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
index 72a89c3..d1deb9d 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
@@ -1,15 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2HeadersFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2HeadersFrame.Http2HeadersFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
 import static org.apache.mina.http2.api.Http2Constants.FLAGS_PRIORITY;
@@ -17,8 +30,8 @@ import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
 import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2HeadersFrameDecoder extends Http2FrameDecoder {
 
@@ -36,7 +49,7 @@ public class Http2HeadersFrameDecoder extends Http2FrameDecoder {
     
     private int padLength;
     
-    private Builder builder = new Builder();
+    private Http2HeadersFrameBuilder builder = new Http2HeadersFrameBuilder();
     
     public Http2HeadersFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
index 4098d49..c894c98 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
@@ -1,34 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2PingFrame.Builder;
+
+import org.apache.mina.http2.api.Http2PingFrame.Http2PingFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2PingFrameDecoder extends Http2FrameDecoder {
-
-    private static enum State {
-        DATA,
-        EXTRA
-    }
-    
-    private State state;
-    
     private BytePartialDecoder decoder;
     
-    private Builder builder = new Builder();
+    private Http2PingFrameBuilder builder = new Http2PingFrameBuilder();
     
     public Http2PingFrameDecoder(Http2FrameHeader header) {
         super(header);
-        decoder = new BytePartialDecoder(8);
-        state = State.DATA;
+        decoder = new BytePartialDecoder(header.getLength());
         initBuilder(builder);
     }
     
@@ -37,25 +44,9 @@ public class Http2PingFrameDecoder extends Http2FrameDecoder {
      */
     @Override
     public boolean consume(ByteBuffer buffer) {
-        while ((getValue() == null) && buffer.remaining() > 0) {
-            switch (state) {
-            case DATA:
-                if (decoder.consume(buffer)) {
-                    builder.data(decoder.getValue());
-                    if (getHeader().getLength() > 8) {
-                        state = State.EXTRA;
-                        decoder = new BytePartialDecoder(getHeader().getLength() - 8);
-                    } else {
-                        setValue(builder.build());
-                    }
-                }
-                break;
-            case EXTRA:
-                if (decoder.consume(buffer)) {
-                    setValue(builder.build());
-                }
-                break;
-            }
+        if (decoder.consume(buffer)) {
+            builder.data(decoder.getValue());
+            setValue(builder.build());
         }
         return getValue() != null;
     }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
index 8fd1036..3dbdfd2 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
@@ -1,22 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2PriorityFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2PriorityFrame.Http2PriorityFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
 import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2PriorityFrameDecoder extends Http2FrameDecoder {
 
@@ -30,7 +43,7 @@ public class Http2PriorityFrameDecoder extends Http2FrameDecoder {
     
     private PartialDecoder<?> decoder;
     
-    private Builder builder = new Builder();
+    private Http2PriorityFrameBuilder builder = new Http2PriorityFrameBuilder();
     
     public Http2PriorityFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
deleted file mode 100644
index 8217166..0000000
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2ProtocolDecoder.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.impl;
-
-import java.nio.ByteBuffer;
-
-import org.apache.mina.codec.ProtocolDecoder;
-import org.apache.mina.http2.api.Http2Frame;
-
-/**
- * @author jeffmaury
- *
- */
-public class Http2ProtocolDecoder implements ProtocolDecoder<ByteBuffer, Http2Frame, Http2Connection> {
-
-    @Override
-    public Http2Connection createDecoderState() {
-        return new Http2Connection();
-    }
-
-    @Override
-    public Http2Frame decode(ByteBuffer input, Http2Connection context) {
-        return context.decode(input);
-    }
-
-    @Override
-    public void finishDecode(Http2Connection context) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
index 34863ce..077e7da 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
@@ -1,22 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2PushPromiseFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2PushPromiseFrame.Http2PushPromiseFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
 import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2PushPromiseFrameDecoder extends Http2FrameDecoder {
 
@@ -33,7 +46,7 @@ public class Http2PushPromiseFrameDecoder extends Http2FrameDecoder {
     
     private int padLength;
     
-    private Builder builder = new Builder();
+    private Http2PushPromiseFrameBuilder builder = new Http2PushPromiseFrameBuilder();
     
     public Http2PushPromiseFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
index e16b0bc..f64175c 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
@@ -1,22 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2RstStreamFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.LongPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
-
-import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+import org.apache.mina.http2.api.Http2RstStreamFrame.Http2RstStreamFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2RstStreamFrameDecoder extends Http2FrameDecoder {
 
@@ -29,7 +39,7 @@ public class Http2RstStreamFrameDecoder extends Http2FrameDecoder {
     
     private PartialDecoder<?> decoder;
     
-    private Builder builder = new Builder();
+    private Http2RstStreamFrameBuilder builder = new Http2RstStreamFrameBuilder();
     
     public Http2RstStreamFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
index 6213c66..ab3166b 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
@@ -1,5 +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. 
+ *  
  */
 package org.apache.mina.http2.impl;
 
@@ -7,14 +23,13 @@ import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collection;
 
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2SettingsFrame.Builder;
 import org.apache.mina.http2.api.Http2Setting;
-import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.Http2SettingsFrame.Http2SettingsFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2SettingsFrameDecoder extends Http2FrameDecoder {
 
@@ -22,7 +37,7 @@ public class Http2SettingsFrameDecoder extends Http2FrameDecoder {
     
     private LongPartialDecoder decoder = new LongPartialDecoder(6);
     
-    private Builder builder = new Builder();
+    private Http2SettingsFrameBuilder builder = new Http2SettingsFrameBuilder();
     
     private Collection<Http2Setting> settings = new ArrayList<Http2Setting>();
     
@@ -42,7 +57,7 @@ public class Http2SettingsFrameDecoder extends Http2FrameDecoder {
                 remaining--;
                 Http2Setting setting = new Http2Setting();
                 setting.setID((int) ((decoder.getValue() & 0x00FFFF00000000L) >> 32));
-                setting.setValue(decoder.getValue() & 0x00FFFFFFFFL);
+                setting.setValue((decoder.getValue() & 0x00FFFFFFFFL));
                 settings.add(setting);
                 decoder.reset();
                 if (remaining == 0) {

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
index f19e55f..df64cfc 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
@@ -1,22 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2UnknownFrame.Builder;
+
+import org.apache.mina.http2.api.Http2UnknownFrame.Http2UnknownFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2UnknownFrameDecoder extends Http2FrameDecoder {
 
     private BytePartialDecoder decoder;
     
-    private Builder builder = new Builder();
+    private Http2UnknownFrameBuilder builder = new Http2UnknownFrameBuilder();
     
     public Http2UnknownFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
index 6d96327..234db5c 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
@@ -1,19 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2WindowUpdateFrame.Builder;
-import org.apache.mina.http2.api.IntPartialDecoder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2WindowUpdateFrame.Http2WindowUpdateFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2WindowUpdateFrameDecoder extends Http2FrameDecoder {
 
@@ -26,7 +39,7 @@ public class Http2WindowUpdateFrameDecoder extends Http2FrameDecoder {
     
     private PartialDecoder<?> decoder;
     
-    private Builder builder = new Builder();
+    private Http2WindowUpdateFrameBuilder builder = new Http2WindowUpdateFrameBuilder();
     
     public Http2WindowUpdateFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/IntPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/IntPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/IntPartialDecoder.java
new file mode 100644
index 0000000..152d840
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/IntPartialDecoder.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.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class IntPartialDecoder implements PartialDecoder<Integer> {
+    private int size;
+    private int remaining;
+    private int value;
+    
+    /**
+     * Decode an integer whose size is different from the standard 4.
+     * 
+     * @param size the size (1,2,3,4) to decode
+     */
+    public IntPartialDecoder(int size) {
+        this.remaining = size;
+        this.size = size;
+    }
+
+    /**
+     * Decode a 4 bytes integer 
+     */
+    public IntPartialDecoder() {
+        this(4);
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        if (remaining == 0) {
+            throw new IllegalStateException();
+        }
+        while (remaining > 0 && buffer.hasRemaining()) {
+            value = (value << 8) + (buffer.get() & 0x00FF);
+            --remaining;
+        }
+        return remaining == 0;
+    }
+    
+    public Integer getValue() {
+        if (remaining > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        remaining = size;
+        value = 0;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/LongPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/LongPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/LongPartialDecoder.java
new file mode 100644
index 0000000..e6ac6eb
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/LongPartialDecoder.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.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class LongPartialDecoder implements PartialDecoder<Long> {
+    private int size;
+    private int remaining;
+    private long value;
+    
+    /**
+     * Decode a long integer whose size is different from the standard 8.
+     * 
+     * @param size the size (1 to 8) to decode
+     */
+    public LongPartialDecoder(int size) {
+        this.remaining = size;
+        this.size = size;
+    }
+
+    /**
+     * Decode a 8 bytes long integer 
+     */
+    public LongPartialDecoder() {
+        this(8);
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        if (remaining == 0) {
+            throw new IllegalStateException();
+        }
+        while (remaining > 0 && buffer.hasRemaining()) {
+            value = (value << 8) + (buffer.get() & 0x00FF);
+            --remaining;
+        }
+        return remaining == 0;
+    }
+    
+    public Long getValue() {
+        if (remaining > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        remaining = size;
+        value = 0;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/PartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/PartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/PartialDecoder.java
new file mode 100644
index 0000000..0139382
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/PartialDecoder.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.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public interface PartialDecoder<T> {
+    /**
+     * Consume the buffer so as to decode a value. Not all the input buffer
+     * may be consumed.
+     * 
+     * @param buffer the input buffer to decode
+     * @return true if a value is available false if more data is requested
+     */
+    public boolean consume(ByteBuffer buffer);
+    
+    /**
+     * Return the decoded value.
+     * 
+     * @return the decoded value
+     */
+    public T getValue();
+    
+    /**
+     * Reset the internal state of the decoder to that new decoding can take place.
+     */
+    public void reset();
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/Http2Test.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/Http2Test.java b/http2/src/test/java/org/apache/mina/http2/Http2Test.java
new file mode 100644
index 0000000..44ee14b
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/Http2Test.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.mina.http2;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+
+public abstract class Http2Test {
+    protected byte[] toByteArray(ByteBuffer buffer) {
+        byte[] result = new byte[buffer.remaining()];
+        buffer.get(result);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/TestMessages.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/TestMessages.java b/http2/src/test/java/org/apache/mina/http2/TestMessages.java
new file mode 100644
index 0000000..c931603
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/TestMessages.java
@@ -0,0 +1,465 @@
+/*
+ *  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.http2;
+
+import java.util.Collections;
+
+import org.apache.mina.http2.api.Http2ContinuationFrame;
+import org.apache.mina.http2.api.Http2ContinuationFrame.Http2ContinuationFrameBuilder;
+import org.apache.mina.http2.api.Http2DataFrame;
+import org.apache.mina.http2.api.Http2DataFrame.Http2DataFrameBuilder;
+import org.apache.mina.http2.api.Http2GoAwayFrame;
+import org.apache.mina.http2.api.Http2GoAwayFrame.Http2GoAwayFrameBuilder;
+import org.apache.mina.http2.api.Http2HeadersFrame;
+import org.apache.mina.http2.api.Http2HeadersFrame.Http2HeadersFrameBuilder;
+import org.apache.mina.http2.api.Http2PingFrame;
+import org.apache.mina.http2.api.Http2PingFrame.Http2PingFrameBuilder;
+import org.apache.mina.http2.api.Http2PriorityFrame;
+import org.apache.mina.http2.api.Http2PriorityFrame.Http2PriorityFrameBuilder;
+import org.apache.mina.http2.api.Http2PushPromiseFrame;
+import org.apache.mina.http2.api.Http2PushPromiseFrame.Http2PushPromiseFrameBuilder;
+import org.apache.mina.http2.api.Http2RstStreamFrame;
+import org.apache.mina.http2.api.Http2RstStreamFrame.Http2RstStreamFrameBuilder;
+import org.apache.mina.http2.api.Http2Setting;
+import org.apache.mina.http2.api.Http2SettingsFrame;
+import org.apache.mina.http2.api.Http2SettingsFrame.Http2SettingsFrameBuilder;
+import org.apache.mina.http2.api.Http2UnknownFrame;
+import org.apache.mina.http2.api.Http2UnknownFrame.Http2UnknownFrameBuilder;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+
+public final class TestMessages {
+
+    public static final byte[] CONTINUATION_NO_HEADER_FRAGMENT_BUFFER = new byte[] {
+        0x00, 0x00, 0x00, /*length*/
+        0x09, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x32 /*streamID*/
+        };
+
+    public static final Http2ContinuationFrame CONTINUATION_NO_HEADER_FRAGMENT_FRAME = Http2ContinuationFrameBuilder.builder().
+            streamID(50).
+            build();
+    
+    public static final byte[] CONTINUATION_HEADER_FRAGMENT_BUFFER = new byte[] {
+        0x00, 0x00, 0x0A, /*length*/
+        0x09, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x32, /*streamID*/
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/
+        };
+    
+    public static final Http2ContinuationFrame CONTINUATION_HEADER_FRAGMENT_FRAME = Http2ContinuationFrameBuilder.builder().
+                streamID(50).
+                headerBlockFragment(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}).
+                build();
+    
+    public static final byte[] DATA_NO_PAYLOAD_NO_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x00, /*length*/
+        0x00, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x32 /*streamID*/
+        };
+    
+    public static final Http2DataFrame DATA_NO_PAYLOAD_NO_PADDING_FRAME = Http2DataFrameBuilder.builder().
+            streamID(50).
+            build();
+    
+    public static final byte[] DATA_PAYLOAD_NO_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x0A, /*length*/
+        0x00, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x32, /*streamID*/
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/
+        };
+    
+    public static final Http2DataFrame DATA_PAYLOAD_NO_PADDING_FRAME = Http2DataFrameBuilder.builder().
+            streamID(50).
+            data(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}).
+            build();
+    
+    public static final byte[] DATA_NO_PAYLOAD_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x03, /*length*/
+        0x00, /*type*/
+        0x08, /*flags*/
+        0x00, 0x00, 0x00, 0x32, /*streamID*/
+        0x02, /*padLength*/
+        0x0E, 0x28 /*padding*/
+        };
+    
+    public static final Http2DataFrame DATA_NO_PAYLOAD_PADDING_FRAME = Http2DataFrameBuilder.builder().
+            streamID(50).
+            padding(new byte[] {0x0E, 0x28}).
+            build();
+    
+    public static final byte[] DATA_PAYLOAD_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x0D, /*length*/
+        0x00, /*type*/
+        0x08, /*flags*/
+        0x00, 0x00, 0x00, 0x32, /*streamID*/
+        0x02, /*padLength*/
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, /*data*/
+        0x0E, 0x28 /*padding*/
+        };
+    
+    public static final Http2DataFrame DATA_PAYLOAD_PADDING_FRAME = Http2DataFrameBuilder.builder().
+            streamID(50).
+            data(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}).
+            padding(new byte[] {0x0E, 0x28}).
+            build();
+    
+    public static final byte[] GOAWAY_NO_DATA_BUFFER = new byte[] {
+        0x00, 0x00, 0x08, /*length*/
+        0x07, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*lastStreamID*/
+        0x00, 0x01, 0x02, 0x03 /*errorCode*/
+        };
+    
+    public static final Http2GoAwayFrame GOAWAY_NO_DATA_FRAME = Http2GoAwayFrameBuilder.builder().
+            streamID(1).
+            lastStreamID(256).
+            errorCode(0x010203).
+            build();
+    
+    public static final byte[] GOAWAY_NO_DATA_HIGHEST_STREAMID_BUFFER = new byte[] {
+        0x00, 0x00, 0x08, /*length*/
+        0x07, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*lastStreamID*/
+        0x00, 0x01, 0x02, 0x03 /*errorCode*/
+        };
+    
+    public static final Http2GoAwayFrame GOAWAY_NO_DATA_HIGHEST_STREAMID_FRAME = Http2GoAwayFrameBuilder.builder().
+            streamID(1).
+            lastStreamID(0x7FFFFFFF).
+            errorCode(0x010203).
+            build();
+    
+    public static final byte[] GOAWAY_NO_DATA_HIGHEST_STREAMID_RESERVED_BIT_BUFFER = new byte[] {
+        0x00, 0x00, 0x08, /*length*/
+        0x07, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*lastStreamID*/
+        0x00, 0x01, 0x02, 0x03 /*errorCode*/
+        };
+    
+    public static final byte[] GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_BUFFER = new byte[] {
+        0x00, 0x00, 0x08, /*length*/
+        0x07, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        (byte) 0x7F, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*lastStreamID*/
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF /*errorCode*/
+        };
+    
+    public static final Http2GoAwayFrame GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_FRAME = Http2GoAwayFrameBuilder.builder().
+            streamID(1).
+            lastStreamID(0x7FFFFFFF).
+            errorCode(0x00FFFFFFFFL).
+            build();
+    
+    public static final byte[] GOAWAY_DATA_BUFFER = new byte[] {
+        0x00, 0x00, 0x09, /*length*/
+        0x07, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*lastStreamID*/
+        0x00, 0x01, 0x02, 0x03, /*errorCode*/
+        0x01 /*additionData*/
+        };
+    
+    public static final Http2GoAwayFrame GOAWAY_DATA_FRAME = Http2GoAwayFrameBuilder.builder().
+            streamID(1).
+            lastStreamID(256).
+            errorCode(0x010203).
+            data(new byte[] { 0x01}).
+            build();
+    
+    public static final byte[] HEADERS_NO_PADDING_NO_PRIORITY_BUFFER = new byte[] {
+        0x00, 0x00, 0x01, /*length*/
+        0x01, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        (byte) 0x82 /*headerFragment*/
+        };
+    
+    public static final Http2HeadersFrame HEADERS_NO_PADDING_NO_PRIORITY_FRAME = Http2HeadersFrameBuilder.builder().
+            streamID(1).
+            headerBlockFragment(new byte[] {(byte) 0x82}).
+            build();
+    
+    public static final byte[] HEADERS_PADDING_PRIORITY_BUFFER = new byte[] {
+        0x00, 0x00, 0x17, /*length*/
+        0x01, /*type*/
+        0x28, /*flags*/
+        0x00, 0x00, 0x00, 0x03, /*streamID*/
+        0x10, /*padding length*/
+        (byte)0x0080, 0x00, 0x00, 0x14, /*stream dependency*/
+        0x09, /*weight*/
+        (byte) 0x82, /*headerFragment*/
+        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/
+        };
+    
+    public static final Http2HeadersFrame HEADERS_PADDING_PRIORITY_FRAME = Http2HeadersFrameBuilder.builder().
+            streamID(3).
+            exclusiveMode(true).
+            streamDependencyID(20).
+            weight((short) 10).
+            headerBlockFragment(new byte[] { (byte) 0x82}).
+            padding(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}).
+            build();
+    
+    public static final byte[] HEADERS_PADDING_NO_PRIORITY_BUFFER = new byte[] {
+        0x00, 0x00, 0x12, /*length*/
+        0x01, /*type*/
+        0x08, /*flags*/
+        0x00, 0x00, 0x00, 0x03, /*streamID*/
+        0x10, /*padding length*/
+        (byte) 0x0082, /*headerFragment*/
+        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/
+        };
+    
+    public static final Http2HeadersFrame HEADERS_PADDING_NO_PRIORITY_FRAME = Http2HeadersFrameBuilder.builder().
+            streamID(3).
+            headerBlockFragment(new byte[] { (byte) 0x82}).
+            padding(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}).
+            build();
+    
+    public static final byte[] PING_STANDARD_BUFFER = new byte[] {
+        0x00, 0x00, 0x08, /*length*/
+        0x06, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07/*opaqueData*/
+        };
+    
+    public static final Http2PingFrame PING_STANDARD_FRAME = Http2PingFrameBuilder.builder().
+            streamID(32).
+            data(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}).
+            build();
+    
+    public static final byte[] PING_EXTRA_DATA_BUFFER = new byte[] {
+        0x00, 0x00, 0x09, /*length*/
+        0x06, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08/*opaqueData*/
+        };
+    
+    public static final Http2PingFrame PING_EXTRA_DATA_FRAME = Http2PingFrameBuilder.builder().
+            streamID(32).
+            data(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}).
+            build();
+    
+    public static final byte[] PING_NO_ENOUGH_DATA_BUFFER = new byte[] {
+        0x00, 0x00, 0x01, /*length*/
+        0x06, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00/*opaqueData*/
+        };
+    
+    public static final Http2PingFrame PING_NO_ENOUGH_DATA_FRAME = Http2PingFrameBuilder.builder().
+            streamID(32).
+            data(new byte[] {0x00}).
+            build();
+    
+    public static final byte[] PRIORITY_NO_EXCLUSIVE_MODE_BUFFER = new byte[] {
+        0x00, 0x00, 0x05, /*length*/
+        0x02, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*streamDependency*/
+        0x01 /*weight*/
+        };
+    
+    public static final Http2PriorityFrame PRIORITY_NO_EXCLUSIVE_MODE_FRAME = Http2PriorityFrameBuilder.builder().
+            streamID(32).
+            weight((short) 2).
+            streamDependencyID(256).
+            build();
+    
+    public static final byte[] PRIORITY_EXCLUSIVE_MODE_BUFFER = new byte[] {
+        0x00, 0x00, 0x05, /*length*/
+        0x02, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        (byte) 0x80, 0x00, 0x01, 0x00, /*streamDependency*/
+        0x01 /*weight*/
+        };
+    
+    public static final Http2PriorityFrame PRIORITY_EXCLUSIVE_MODE_FRAME = Http2PriorityFrameBuilder.builder().
+            streamID(32).
+            weight((short) 2).
+            streamDependencyID(256).
+            exclusiveMode(true).
+            build();
+    
+    public static final byte[] PUSH_PROMISE_NO_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x05, /*length*/
+        0x05, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x01, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*promisedStreamID*/
+        (byte) 0x82 /*headerFragment*/
+        };
+    
+    public static final Http2PushPromiseFrame PUSH_PROMISE_NO_PADDING_FRAME = Http2PushPromiseFrameBuilder.builder().
+            streamID(1).
+            promisedStreamID(256).
+            headerBlockFragment(new byte[] {(byte) 0x82}).
+            build();
+    
+    public static final byte[] PUSH_PROMISE_PADDING_BUFFER = new byte[] {
+        0x00, 0x00, 0x16, /*length*/
+        0x05, /*type*/
+        0x08, /*flags*/
+        0x00, 0x00, 0x00, 0x03, /*streamID*/
+        0x10, /*padding length*/
+        0x00, 0x00, 0x00, 0x14, /*promisedStreamID*/
+        (byte) 0x0082, /*headerFragment*/
+        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/
+        };
+    
+    public static final Http2PushPromiseFrame PUSH_PROMISE_PADDING_FRAME = Http2PushPromiseFrameBuilder.builder().
+            streamID(3).
+            promisedStreamID(20).
+            headerBlockFragment(new byte[] {(byte) 0x82}).
+            padding(new byte[] { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}).
+            build();
+    
+    public static final byte[] RST_STREAM_NO_EXTRA_PAYLOAD_BUFFER = new byte[] {
+        0x00, 0x00, 0x04, /*length*/
+        0x03, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*errorCode*/
+        };
+    
+    public static final Http2RstStreamFrame RST_STREAM_NO_EXTRA_PAYLOAD_FRAME = Http2RstStreamFrameBuilder.builder().
+            streamID(32).
+            errorCode(256).
+            build();
+    
+    public static final byte[] RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_BUFFER = new byte[] {0x00, 0x00, 0x04, /*length*/
+        0x03, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/
+        };
+    
+    public static final Http2RstStreamFrame RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_FRAME = Http2RstStreamFrameBuilder.builder().
+            streamID(32).
+            errorCode(0x00FFFFFFFFL).
+            build();
+
+    public static final byte[] RST_STREAM_EXTRA_PAYLOAD_BUFFER = new byte[] {
+        0x00, 0x00, 0x06, /*length*/
+        0x03, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x00, 0x01, 0x00, /*errorCode*/
+        0x0E, 0x28
+        };
+   
+    public static final byte[] RST_STREAM_EXTRA_PAYLOAD_HIGHEST_BUFFER = new byte[] {
+        0x00, 0x00, 0x06, /*length*/
+        0x03, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/
+        0x0E, 0x28
+        };
+    
+    public static final byte[] SETTINGS_DEFAULT_BUFFER = new byte[] {
+        0x00, 0x00, 0x06, /*length*/
+        0x04, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x01, /*ID*/
+        0x01, 0x02, 0x03, 0x04, /*value*/
+        };
+    
+    public static final Http2SettingsFrame SETTINGS_DEFAULT_FRAME = Http2SettingsFrameBuilder.builder().
+            streamID(32).
+            settings(Collections.singletonList(new Http2Setting(1, 0x01020304))).
+            build();
+    
+    public static final byte[] SETTINGS_HIGHEST_ID_BUFFER = new byte[] {
+        0x00, 0x00, 0x06, /*length*/
+        0x04, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        (byte) 0xFF, (byte) 0xFF, /*ID*/
+        0x01, 0x02, 0x03, 0x04, /*value*/
+        };
+    
+    public static final Http2SettingsFrame SETTINGS_HIGHEST_ID_FRAME = Http2SettingsFrameBuilder.builder().
+            streamID(32).
+            settings(Collections.singletonList(new Http2Setting(0x00FFFF, 0x01020304))).
+            build();
+    
+    public static final byte[] SETTINGS_HIGHEST_VALUE_BUFFER = new byte[] {
+        0x00, 0x00, 0x06, /*length*/
+        0x04, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x00, 0x01, /*ID*/
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*value*/
+        };
+    
+    public static final Http2SettingsFrame SETTINGS_HIGHEST_VALUE_FRAME = Http2SettingsFrameBuilder.builder().
+            streamID(32).
+            settings(Collections.singletonList(new Http2Setting(1, 0xFFFFFFFFL))).
+            build();
+    
+    public static final byte[] UNKNOWN_PAYLOAD_BUFFER = new byte[] {
+        0x00, 0x00, 0x02, /*length*/
+        (byte) 0x00FF, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20, /*streamID*/
+        0x0E, 0x18
+        };
+    
+    public static final Http2UnknownFrame UNKNOWN_PAYLOAD_FRAME = Http2UnknownFrameBuilder.builder().
+            type((short) 255).
+            streamID(32).
+            payload(new byte[] { 0x0E, 0x18}).
+            build();
+    
+    public static final byte[] UNKNOWN_NO_PAYLOAD_BUFFER = new byte[] {
+        0x00, 0x00, 0x00, /*length*/
+        (byte) 0x00FF, /*type*/
+        0x00, /*flags*/
+        0x00, 0x00, 0x00, 0x20 /*streamID*/
+        };
+    
+    public static final Http2UnknownFrame UNKNOWN_NO_PAYLOAD_FRAME = Http2UnknownFrameBuilder.builder().
+            type((short) 255).
+            streamID(32).
+            build();
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
deleted file mode 100644
index 7d09d11..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/BytePartialDecoderTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.nio.ByteBuffer;
-
-import org.junit.Test;
-
-public class BytePartialDecoderTest {
-
-    private static final byte[] SAMPLE_VALUE_1 = new byte[] {0x74, 0x18, 0x4F, 0x68};
-    private static final byte[] SAMPLE_VALUE_2 = new byte[] {0x74, 0x18, 0x4F, 0x68, 0x0F};
-
-    @Test
-    public void checkSimpleValue() {
-        BytePartialDecoder decoder = new BytePartialDecoder(4);
-        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_1);
-        assertTrue(decoder.consume(buffer));
-        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
-    }
-    
-    @Test
-    public void checkNotenoughData() {
-        BytePartialDecoder decoder = new BytePartialDecoder(4);
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
-        assertFalse(decoder.consume(buffer));
-    }
-
-    @Test
-    public void checkTooMuchData() {
-        BytePartialDecoder decoder = new BytePartialDecoder(4);
-        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_2);
-        assertTrue(decoder.consume(buffer));
-        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
-        assertEquals(1, buffer.remaining());
-    }
-
-    @Test
-    public void checkDecodingIn2Steps() {
-        BytePartialDecoder decoder = new BytePartialDecoder(4);
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[0], SAMPLE_VALUE_2[1]});
-        assertFalse(decoder.consume(buffer));
-        buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[2], SAMPLE_VALUE_2[3], SAMPLE_VALUE_2[4]});
-        assertTrue(decoder.consume(buffer));
-        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
-        assertEquals(1, buffer.remaining());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
deleted file mode 100644
index 12a661c..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2ContinuationFrameDecoderTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2ContinuationFrameDecoderTest {
-
-    @Test
-    public void checkContinuationNoHeaderFragment() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
-                                                        0x09, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32 /*streamID*/});
-        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(0, frame.getLength());
-        assertEquals(9, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(0, frame.getHeaderBlockFragment().length);
-    }
-    
-    @Test
-    public void checkContinuationWithHeaderFragment() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0A, /*length*/
-                                                        0x09, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
-                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/});
-        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(10, frame.getLength());
-        assertEquals(9, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(10, frame.getHeaderBlockFragment().length);
-        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getHeaderBlockFragment());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
deleted file mode 100644
index f6dad67..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2DataFrameDecoderTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2DataFrameDecoderTest {
-
-    @Test
-    public void checkDataNoPayloadNoPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
-                                                        0x00, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32 /*streamID*/});
-        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(0, frame.getLength());
-        assertEquals(0, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(0, frame.getData().length);
-        assertEquals(0, frame.getPadding().length);
-    }
-    
-    @Test
-    public void checkDataWithPayloadNoPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0A, /*length*/
-                                                        0x00, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
-                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A /*headerFragment*/});
-        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(10, frame.getLength());
-        assertEquals(0, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(10, frame.getData().length);
-        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
-        assertEquals(0, frame.getPadding().length);
-    }
-
-    @Test
-    public void checkDataNoPayloadPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x03, /*length*/
-                                                        0x00, /*type*/
-                                                        0x08, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
-                                                        0x02, 0x0E, 0x28 /*padding*/});
-        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(3, frame.getLength());
-        assertEquals(0, frame.getType());
-        assertEquals(0x08, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(0,frame.getData().length);
-        assertEquals(2, frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x0E,  0x28}, frame.getPadding());
-    }
-    
-    @Test
-    public void checkDataWithPayloadPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x0D, /*length*/
-                                                        0x00, /*type*/
-                                                        0x08, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x32, /*streamID*/
-                                                        0x02, /*padLength*/
-                                                        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, /*data*/
-                                                        0x0E, 0x28 /*padding*/});
-        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(13, frame.getLength());
-        assertEquals(0, frame.getType());
-        assertEquals(0x08, frame.getFlags());
-        assertEquals(50, frame.getStreamID());
-        assertEquals(10, frame.getData().length);
-        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
-        assertEquals(2, frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x0E, 0x28}, frame.getPadding());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
deleted file mode 100644
index e974ce5..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2HeadersFrameDecoderTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2HeadersFrameDecoderTest {
-
-    @Test
-    public void checkHeadersFrameWithNotPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x01, /*length*/
-                                                        0x01, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x01, /*streamID*/
-                                                        (byte) 0x0082 /*headerFragment*/});
-        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(1, frame.getLength());
-        assertEquals(1, frame.getType());
-        assertEquals(0, frame.getFlags());
-        assertEquals(1, frame.getStreamID());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-    }
-    
-    
-    @Test
-    public void checkHeadersFramePaddingPriority() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x17, /*length*/
-                                                        0x01, /*type*/
-                                                        0x28, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
-                                                        0x10, /*padding length*/
-                                                        (byte)0x0080, 0x00, 0x00, 0x14, /*stream dependency*/
-                                                        0x09, /*weight*/
-                                                        (byte) 0x0082, /*headerFragment*/
-                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
-        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(23, frame.getLength());
-        assertEquals(1, frame.getType());
-        assertEquals(0x28, frame.getFlags());
-        assertEquals(3, frame.getStreamID());
-        assertEquals(10,  frame.getWeight());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-        assertEquals(16,  frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
-    }
-    
-    @Test
-    public void checkHeadersFramePaddingNoPriority() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x12, /*length*/
-                                                        0x01, /*type*/
-                                                        0x08, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
-                                                        0x10, /*padding length*/
-                                                        (byte) 0x0082, /*headerFragment*/
-                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
-        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(18, frame.getLength());
-        assertEquals(1, frame.getType());
-        assertEquals(0x08, frame.getFlags());
-        assertEquals(3, frame.getStreamID());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-        assertEquals(16,  frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
deleted file mode 100644
index cd0c049..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2PriorityFrameDecoderTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2PriorityFrameDecoderTest {
-
-    @Test
-    public void checkPriorityFrameNoExclusive() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
-                                                        0x02, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x00, 0x00, 0x01, 0x00, /*streamDependency*/
-                                                        0x01});
-        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(5, frame.getLength());
-        assertEquals(2, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(256, frame.getStreamDependencyID());
-        assertFalse(frame.getExclusiveMode());
-    }
-
-    @Test
-    public void checkPriorityFrameExclusive() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
-                                                        0x02, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        (byte) 0x0080, 0x00, 0x01, 0x00, /*streamDependency*/
-                                                        0x01});
-        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(5, frame.getLength());
-        assertEquals(2, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(256, frame.getStreamDependencyID());
-        assertTrue(frame.getExclusiveMode());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
deleted file mode 100644
index 02f7198..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2PushPromiseFrameDecoderTest {
-
-    @Test
-    public void checkWithNoPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
-                                                        0x05, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x01, /*streamID*/
-                                                        0x00, 0x00, 0x01, 0x00, /*promisedStreamID*/
-                                                        (byte) 0x0082 /*headerFragment*/});
-        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(5, frame.getLength());
-        assertEquals(5, frame.getType());
-        assertEquals(0, frame.getFlags());
-        assertEquals(1, frame.getStreamID());
-        assertEquals(256, frame.getPromisedStreamID());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-    }
-    
-    
-    @Test
-    public void checkWithPadding() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x16, /*length*/
-                                                        0x05, /*type*/
-                                                        0x08, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
-                                                        0x10, /*padding length*/
-                                                        0x00, 0x00, 0x00, 0x14, /*promisedStreamID*/
-                                                        (byte) 0x0082, /*headerFragment*/
-                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
-        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
-        assertEquals(22, frame.getLength());
-        assertEquals(5, frame.getType());
-        assertEquals(0x08, frame.getFlags());
-        assertEquals(3, frame.getStreamID());
-        assertEquals(20, frame.getPromisedStreamID());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-        assertEquals(16,  frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
deleted file mode 100644
index 717b0f6..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2RstStreamFrameDecoderTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2RstStreamFrameDecoderTest {
-
-    @Test
-    public void checkRstStreamNoExtraPayload() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x04, /*length*/
-                                                        0x03, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x00, 0x00, 0x01, 0x00, /*errorCode*/});
-        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(4, frame.getLength());
-        assertEquals(3, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(256, frame.getErrorCode());
-    }
-
-    @Test
-    public void checkRstStreamHighestValueNoExtraPayload() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x04, /*length*/
-                                                        0x03, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/});
-        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(4, frame.getLength());
-        assertEquals(3, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
-    }
-
-    @Test
-    public void checkRstStreamWithExtraPayload() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
-                                                        0x03, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x00, 0x00, 0x01, 0x00, /*errorCode*/
-                                                        0x0E, 0x28});
-        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(6, frame.getLength());
-        assertEquals(3, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(256, frame.getErrorCode());
-    }
-
-    @Test
-    public void checkRstStreamHighestValueWithExtraPayload() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
-                                                        0x03, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*errorCode*/
-                                                        0x0E, 0x28});
-        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(6, frame.getLength());
-        assertEquals(3, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
-    }
-}


[7/8] mina git commit: Complete low level HTTP2

Posted by je...@apache.org.
Complete low level HTTP2


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/8ca3d89d
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/8ca3d89d
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/8ca3d89d

Branch: refs/heads/trunk
Commit: 8ca3d89da1d53ed165db2c82df0ad9217c13acaf
Parents: 27938fb
Author: Jeff MAURY <je...@apache.org>
Authored: Sun Apr 12 23:49:29 2015 +0200
Committer: Jeff MAURY <je...@apache.org>
Committed: Sun Apr 12 23:49:29 2015 +0200

----------------------------------------------------------------------
 http2/Http2Frames.ods                           | Bin 16968 -> 0 bytes
 .../mina/http2/api/BytePartialDecoder.java      |  50 --
 .../apache/mina/http2/api/Http2Constants.java   |  49 +-
 .../mina/http2/api/Http2ContinuationFrame.java  |  39 +-
 .../apache/mina/http2/api/Http2DataFrame.java   |  59 ++-
 .../org/apache/mina/http2/api/Http2Frame.java   |  85 +++-
 .../api/Http2FrameHeadePartialDecoder.java      | 106 -----
 .../apache/mina/http2/api/Http2GoAwayFrame.java |  56 ++-
 .../org/apache/mina/http2/api/Http2Header.java  |  23 +
 .../mina/http2/api/Http2HeadersFrame.java       |  89 ++--
 .../mina/http2/api/Http2NameValuePair.java      |  23 +
 .../apache/mina/http2/api/Http2PingFrame.java   |  33 +-
 .../mina/http2/api/Http2PriorityFrame.java      |  50 +-
 .../mina/http2/api/Http2PushPromiseFrame.java   |  55 ++-
 .../mina/http2/api/Http2RstStreamFrame.java     |  34 +-
 .../org/apache/mina/http2/api/Http2Setting.java |  34 ++
 .../mina/http2/api/Http2SettingsFrame.java      |  40 +-
 .../mina/http2/api/Http2UnknownFrame.java       |  31 +-
 .../mina/http2/api/Http2WindowUpdateFrame.java  |  33 +-
 .../mina/http2/api/IntPartialDecoder.java       |  62 ---
 .../mina/http2/api/LongPartialDecoder.java      |  62 ---
 .../apache/mina/http2/api/PartialDecoder.java   |  34 --
 .../apache/mina/http2/api/StreamMessage.java    |  21 -
 .../mina/http2/codec/Http2ProtocolDecoder.java  |  47 ++
 .../mina/http2/codec/Http2ProtocolEncoder.java  |  42 ++
 .../mina/http2/impl/BytePartialDecoder.java     |  66 +++
 .../apache/mina/http2/impl/HeadersEncoder.java  |  23 +
 .../apache/mina/http2/impl/Http2Connection.java |  27 +-
 .../impl/Http2ContinuationFrameDecoder.java     |  31 +-
 .../mina/http2/impl/Http2DataFrameDecoder.java  |  32 +-
 .../mina/http2/impl/Http2FrameDecoder.java      |  27 +-
 .../impl/Http2FrameHeadePartialDecoder.java     | 123 +++++
 .../http2/impl/Http2GoAwayFrameDecoder.java     |  38 +-
 .../http2/impl/Http2HeadersFrameDecoder.java    |  33 +-
 .../mina/http2/impl/Http2PingFrameDecoder.java  |  65 ++-
 .../http2/impl/Http2PriorityFrameDecoder.java   |  33 +-
 .../mina/http2/impl/Http2ProtocolDecoder.java   |  30 --
 .../impl/Http2PushPromiseFrameDecoder.java      |  33 +-
 .../http2/impl/Http2RstStreamFrameDecoder.java  |  36 +-
 .../http2/impl/Http2SettingsFrameDecoder.java   |  33 +-
 .../http2/impl/Http2UnknownFrameDecoder.java    |  32 +-
 .../impl/Http2WindowUpdateFrameDecoder.java     |  33 +-
 .../mina/http2/impl/IntPartialDecoder.java      |  78 ++++
 .../mina/http2/impl/LongPartialDecoder.java     |  78 ++++
 .../apache/mina/http2/impl/PartialDecoder.java  |  50 ++
 .../java/org/apache/mina/http2/Http2Test.java   |  35 ++
 .../org/apache/mina/http2/TestMessages.java     | 465 +++++++++++++++++++
 .../mina/http2/api/BytePartialDecoderTest.java  |  51 --
 .../api/Htp2ContinuationFrameDecoderTest.java   |  46 --
 .../http2/api/Htp2DataFrameDecoderTest.java     |  89 ----
 .../http2/api/Htp2HeadersFrameDecoderTest.java  |  78 ----
 .../http2/api/Htp2PriorityFrameDecoderTest.java |  52 ---
 .../api/Htp2PushPromiseFrameDecoderTest.java    |  57 ---
 .../api/Htp2RstStreamFrameDecoderTest.java      |  84 ----
 .../http2/api/Htp2SettingsFrameDecoderTest.java |  74 ---
 .../http2/api/Htp2UnknownFrameDecoderTest.java  |  47 --
 .../http2/api/Http2ContinuationFrameTest.java   |  77 +++
 .../mina/http2/api/Http2DataFrameTest.java      | 122 +++++
 .../api/Http2FrameHeaderPartialDecoderTest.java |  63 ---
 .../mina/http2/api/Http2GoAwayFrameTest.java    | 134 ++++++
 .../mina/http2/api/Http2HeadersFrameTest.java   | 105 +++++
 .../mina/http2/api/Http2PingFrameTest.java      |  95 ++++
 .../mina/http2/api/Http2PriorityFrameTest.java  |  82 ++++
 .../http2/api/Http2PushPromiseFrameTest.java    |  83 ++++
 .../mina/http2/api/Http2RstStreamFrameTest.java | 103 ++++
 .../api/Http2SettingsFrameDecoderTest.java      | 105 +++++
 .../mina/http2/api/Http2UnknownFrameTest.java   |  79 ++++
 .../mina/http2/api/IntPartialDecoderTest.java   |  47 --
 .../http2/codec/Http2ProtocolDecoderTest.java   | 458 ++++++++++++++++++
 .../http2/codec/Http2ProtocolEncoderTest.java   | 200 ++++++++
 .../mina/http2/impl/BytePartialDecoderTest.java |  75 +++
 .../Http2FrameHeaderPartialDecoderTest.java     |  87 ++++
 .../mina/http2/impl/IntPartialDecoderTest.java  |  71 +++
 pom.xml                                         |   1 +
 74 files changed, 3723 insertions(+), 1400 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/Http2Frames.ods
----------------------------------------------------------------------
diff --git a/http2/Http2Frames.ods b/http2/Http2Frames.ods
deleted file mode 100644
index c2ca426..0000000
Binary files a/http2/Http2Frames.ods and /dev/null differ

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
deleted file mode 100644
index 11582de..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/BytePartialDecoder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.api;
-
-import java.nio.ByteBuffer;
-
-/**
- * @author jeffmaury
- *
- */
-public class BytePartialDecoder implements PartialDecoder<byte[]> {
-    private int offset;
-    private byte[] value;
-    
-    /**
-     * Decode an byte array.
-     * 
-     * @param size the size of the byte array to decode
-     */
-    public BytePartialDecoder(int size) {
-        this.offset = 0;
-        this.value = new byte[size];
-    }
-
-    public boolean consume(ByteBuffer buffer) {
-        if (value.length - offset == 0) {
-            throw new IllegalStateException();
-        }
-        int length = Math.min(buffer.remaining(), value.length - offset);
-        buffer.get(value, offset, length);
-        offset += length;
-        return value.length - offset == 0;
-    }
-    
-    public byte[] getValue() {
-        if (value.length - offset > 0) {
-            throw new IllegalStateException();
-        }
-        return value;
-    }
-
-    /** 
-     * {@inheritDoc}
-     */
-    @Override
-    public void reset() {
-        offset = 0;
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
index 3bf58f6..4b7f04c 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
@@ -1,13 +1,29 @@
-/**
- * 
+/*
+ *  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.http2.api;
 
 import java.nio.charset.Charset;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public final class Http2Constants {
     /**
@@ -21,6 +37,11 @@ public final class Http2Constants {
      * the exclusive bit
      */
     public static final int HTTP2_EXCLUSIVE_MASK = 0x80000000;
+    
+    /**
+     * Length of the HTTP2 header (length, type, flags, streamID)
+     */
+    public static final int HTTP2_HEADER_LENGTH = 9;
 
     /*
      * Frame types
@@ -28,52 +49,52 @@ public final class Http2Constants {
     /**
      * DATA frame
      */
-    public static final int FRAME_TYPE_DATA = 0x00;
+    public static final short FRAME_TYPE_DATA = 0x00;
     
     /**
      * HEADERS frame
      */
-    public static final int FRAME_TYPE_HEADERS = 0x01;
+    public static final short FRAME_TYPE_HEADERS = 0x01;
     
     /**
      * PRIORITY frame
      */
-    public static final int FRAME_TYPE_PRIORITY = 0x02;
+    public static final short FRAME_TYPE_PRIORITY = 0x02;
     
     /**
      * RST_STREAM frame
      */
-    public static final int FRAME_TYPE_RST_STREAM = 0x03;
+    public static final short FRAME_TYPE_RST_STREAM = 0x03;
     
     /**
      * SETTINGS stream
      */
-    public static final int FRAME_TYPE_SETTINGS = 0x04;
+    public static final short FRAME_TYPE_SETTINGS = 0x04;
     
     /**
      * PUSH_PROMISE frame
      */
-    public static final int FRAME_TYPE_PUSH_PROMISE = 0x05;
+    public static final short FRAME_TYPE_PUSH_PROMISE = 0x05;
     
     /**
      * PING frame
      */
-    public static final int FRAME_TYPE_PING = 0x06;
+    public static final short FRAME_TYPE_PING = 0x06;
     
     /**
      * GOAWAY frame
      */
-    public static final int FRAME_TYPE_GOAWAY = 0x07;
+    public static final short FRAME_TYPE_GOAWAY = 0x07;
     
     /**
      * WINDOW_UPDATE frame
      */
-    public static final int FRAME_TYPE_WINDOW_UPDATE = 0x08;
+    public static final short FRAME_TYPE_WINDOW_UPDATE = 0x08;
     
     /**
      * CONTINUATION frame
      */
-    public static final int FRAME_TYPE_CONTINUATION = 0x09;
+    public static final short FRAME_TYPE_CONTINUATION = 0x09;
     
     /*
      * Flags

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
index 0138d17..ce0a6ef 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
@@ -19,11 +19,15 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_CONTINUATION;
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+import java.nio.ByteBuffer;
+
 /**
- * An SPY data frame
+ * An HTTP2 continuation frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * 
  */
 public class Http2ContinuationFrame extends Http2Frame {
 
@@ -34,35 +38,42 @@ public class Http2ContinuationFrame extends Http2Frame {
         return headerBlockFragment;
     }
 
-    protected <T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> Http2ContinuationFrame(AbstractHttp2ContinuationFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.put(getHeaderBlockFragment());
+    }
+
+    protected Http2ContinuationFrame(Http2ContinuationFrameBuilder builder) {
         super(builder);
         this.headerBlockFragment = builder.getHeaderBlockFragment();
     }
 
     
-    public static abstract class AbstractHttp2ContinuationFrameBuilder<T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> extends AbstractHttp2FrameBuilder<T,V> {
-        private byte[] headerBlockFragment = new byte[0];
+    public static class Http2ContinuationFrameBuilder extends AbstractHttp2FrameBuilder<Http2ContinuationFrameBuilder,Http2ContinuationFrame> {
+        private byte[] headerBlockFragment = EMPTY_BYTE_ARRAY;
         
-        @SuppressWarnings("unchecked")
-        public T headerBlockFragment(byte[] headerBlockFragment) {
+        public Http2ContinuationFrameBuilder headerBlockFragment(byte[] headerBlockFragment) {
             this.headerBlockFragment = headerBlockFragment;
-            return (T) this;
+            return this;
         }
         
         public byte[] getHeaderBlockFragment() {
             return headerBlockFragment;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2ContinuationFrameBuilder<Builder, Http2ContinuationFrame> {
 
         @Override
         public Http2ContinuationFrame build() {
-            return new Http2ContinuationFrame(this);
+            if (getLength() == (-1)) {
+                setLength(getHeaderBlockFragment().length);
+            }
+            return new Http2ContinuationFrame(type(FRAME_TYPE_CONTINUATION));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2ContinuationFrameBuilder builder() {
+            return new Http2ContinuationFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
index 2a4802d..e8de92e 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
@@ -20,9 +20,14 @@
 package org.apache.mina.http2.api;
 
 import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_DATA;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_HEADER_LENGTH;
+
+import java.nio.ByteBuffer;
 
 /**
- * An SPY data frame
+ * An HTTP2 data frame
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -40,48 +45,64 @@ public class Http2DataFrame extends Http2Frame {
         return padding;
     }
     
-    protected <T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> Http2DataFrame(AbstractHttp2DataFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put((byte) getPadding().length);
+        }
+        buffer.put(getData());
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put(getPadding());
+        }
+    }
+
+    protected Http2DataFrame(Http2DataFrameBuilder builder) {
         super(builder);
-        this.data = builder.getData();
-        this.padding = builder.getPadding();
+        data = builder.getData();
+        padding = builder.getPadding();
     }
 
-    
-    public static abstract class AbstractHttp2DataFrameBuilder<T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2DataFrameBuilder extends AbstractHttp2FrameBuilder<Http2DataFrameBuilder,Http2DataFrame> {
         private byte[] data = EMPTY_BYTE_ARRAY;
         
         private byte[] padding = EMPTY_BYTE_ARRAY;
 
-        @SuppressWarnings("unchecked")
-        public T data(byte[] data) {
+        public Http2DataFrameBuilder data(byte[] data) {
             this.data = data;
-            return (T) this;
+            return this;
         }
         
         public byte[] getData() {
             return data;
         }
 
-        @SuppressWarnings("unchecked")
-        public T padding(byte[] padding) {
+        public Http2DataFrameBuilder padding(byte[] padding) {
             this.padding = padding;
-            return (T) this;
+            addFlag(FLAGS_PADDING);
+            return this;
         }
         
         public byte[] getPadding() {
             return padding;
         }
-}
-    
-    public static class Builder extends AbstractHttp2DataFrameBuilder<Builder, Http2Frame> {
 
         @Override
-        public Http2Frame build() {
-            return new Http2DataFrame(this);
+        public Http2DataFrame build() {
+            if (getLength() == (-1)) {
+                int length = getData().length;
+                if (isFlagSet(FLAGS_PADDING)) {
+                    length += getPadding().length + 1;
+                }
+                length(length);
+            }
+            return new Http2DataFrame(type(FRAME_TYPE_DATA));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2DataFrameBuilder builder() {
+            return new Http2DataFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
index 356c2b8..82da9f7 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
@@ -19,8 +19,12 @@
  */
 package org.apache.mina.http2.api;
 
+import java.nio.ByteBuffer;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_HEADER_LENGTH;
+
 /**
- * An SPY data frame
+ * An HTTP2 frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -31,7 +35,7 @@ public abstract class Http2Frame {
     
     private final short type;
     
-    private final short flags;
+    private final byte flags;
     
     private final int streamID;
     
@@ -43,13 +47,49 @@ public abstract class Http2Frame {
         return type;
     }
     
-    public short getFlags() {
+    public byte getFlags() {
         return flags;
     }
 
+    /**
+     * Utility method to test if a specific bit is set in the flags.
+     * 
+     * @param flag the bit to test
+     * @return
+     */
+    protected boolean isFlagSet(byte flag) {
+        return (getFlags() & flag) == flag;
+    }
+
     public int getStreamID() {
         return streamID;
     }
+    
+    /**
+     * Serialize the frame to a buffer.
+     * 
+     * @return the allocated buffer
+     */
+    public ByteBuffer toBuffer() {
+        ByteBuffer buffer = ByteBuffer.allocateDirect(HTTP2_HEADER_LENGTH + getLength());
+        buffer.put((byte) (getLength() >> 16));
+        buffer.put((byte) (getLength() >> 8));
+        buffer.put((byte) (getLength() ));
+        buffer.put((byte) getType());
+        buffer.put(getFlags());
+        buffer.putInt(getStreamID());
+        writePayload(buffer);
+        buffer.flip();
+        return buffer;
+    }
+    
+    /**
+     * Writes the frame specific payload to the allocated buffer.
+     * Must be implemented by frames implementation.
+     *  
+     * @param buffer the buffer to write to
+     */
+    public abstract void writePayload(ByteBuffer buffer);
 
     protected <T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame> Http2Frame(AbstractHttp2FrameBuilder<T, V> builder) {
         this.length = builder.getLength();
@@ -59,17 +99,21 @@ public abstract class Http2Frame {
     }
 
     public static abstract class AbstractHttp2FrameBuilder<T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame>  {
-        private int length;
+        private int length = (-1);
         
         private short type;
         
-        private short flags;
+        private byte flags;
         
         private int streamID;
         
+        public void setLength(int length) {
+            this.length = length;
+        }
+        
         @SuppressWarnings("unchecked")
         public T length(int length) {
-            this.length = length;
+            setLength(length);
             return (T) this;
         }
         
@@ -86,16 +130,39 @@ public abstract class Http2Frame {
         public short getType() {
             return type;
         }
+        
+        public void setFlags(byte flags) {
+            this.flags = flags;
+        }
 
         @SuppressWarnings("unchecked")
-        public T flags(short flags) {
-            this.flags = flags;
+        public T flags(byte flags) {
+            setFlags(flags);
             return (T) this;
         }
         
-        public short getFlags() {
+        public byte getFlags() {
             return flags;
         }
+        
+        /**
+         * Utility method for setting a specific bit in the flags.
+         * 
+         * @param flag the bit to set
+         */
+        protected void addFlag(byte flag) {
+            setFlags((byte) (getFlags() | flag));
+        }
+        
+        /**
+         * Utility method to test if a specific bit is set in the flags.
+         * 
+         * @param flag the bit to test
+         * @return
+         */
+        protected boolean isFlagSet(byte flag) {
+            return (getFlags() & flag) == flag;
+        }
 
         @SuppressWarnings("unchecked")
         public T streamID(int streamID) {

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
deleted file mode 100644
index 059f193..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.api;
-
-import java.nio.ByteBuffer;
-
-import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
-/**
- * @author jeffmaury
- *
- */
-public class Http2FrameHeadePartialDecoder implements PartialDecoder<Http2FrameHeadePartialDecoder.Http2FrameHeader> {
-    public static class Http2FrameHeader {
-        private int length;
-        private short type;
-        private byte flags;
-        private int streamID;
-
-        public int getLength() {
-            return length;
-        }
-       
-        public void setLength(int length) {
-            this.length = length;
-        }
-        
-        public short getType() {
-            return type;
-        }
-        
-        public void setType(short type) {
-            this.type = type;
-        }
-        
-        public byte getFlags() {
-            return flags;
-        }
-        
-        public void setFlags(byte flags) {
-            this.flags = flags;
-        }
-        
-        public int getStreamID() {
-            return streamID;
-        }
-        
-        public void setStreamID(int streamID) {
-            this.streamID = streamID;
-        }
-    }
-    
-    private static enum State {
-        LENGTH,
-        TYPE_FLAGS,
-        STREAMID,
-        END
-    }
-    
-    private State state;
-    private PartialDecoder<?> decoder;
-    private Http2FrameHeader value;
-    
-    public Http2FrameHeadePartialDecoder() {
-        reset();
-    }
-    
-    public boolean consume(ByteBuffer buffer) {
-        while (buffer.hasRemaining() && state != State.END) {
-            if (decoder.consume(buffer)) {
-                switch (state) {
-                case LENGTH:
-                    value.setLength(((IntPartialDecoder)decoder).getValue().intValue());
-                    decoder = new BytePartialDecoder(2);
-                    state = State.TYPE_FLAGS;
-                    break;
-                case TYPE_FLAGS:
-                    value.setType(((BytePartialDecoder)decoder).getValue()[0]);
-                    value.setFlags(((BytePartialDecoder)decoder).getValue()[1]);
-                    decoder = new IntPartialDecoder(4);
-                    state = State.STREAMID;
-                    break;
-                case STREAMID:
-                    value.setStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
-                    state = State.END;
-                    break;
-                }
-            }
-        }
-        return state == State.END;
-    }
-    
-    public Http2FrameHeader getValue() {
-        return value;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.mina.http2.api.PartialDecoder#reset()
-     */
-    @Override
-    public void reset() {
-        state = State.LENGTH;
-        decoder = new IntPartialDecoder(3);
-        value = new Http2FrameHeader();
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
index fbc5ea1..8dcb487 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
@@ -19,6 +19,11 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_GOAWAY;
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+import java.nio.ByteBuffer;
+
 /**
  * An SPY data frame
  * 
@@ -28,7 +33,7 @@ package org.apache.mina.http2.api;
 public class Http2GoAwayFrame extends Http2Frame {
     private final int lastStreamID;
     
-    private final int errorCode;
+    private final long errorCode;
 
     private byte[] data;
     
@@ -36,7 +41,7 @@ public class Http2GoAwayFrame extends Http2Frame {
         return lastStreamID;
     }
     
-    public int getErrorCode() {
+    public long getErrorCode() {
         return errorCode;
     }
 
@@ -44,7 +49,17 @@ public class Http2GoAwayFrame extends Http2Frame {
         return data;
     }
     
-    protected <T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> Http2GoAwayFrame(AbstractHttp2GoAwayFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.putInt(getLastStreamID());
+        buffer.putInt((int) getErrorCode());
+        buffer.put(getData());
+    }
+
+    protected Http2GoAwayFrame(Http2GoAwayFrameBuilder builder) {
         super(builder);
         this.lastStreamID = builder.getLastStreamID();
         this.errorCode = builder.getErrorCode();
@@ -52,53 +67,50 @@ public class Http2GoAwayFrame extends Http2Frame {
     }
 
     
-    public static abstract class AbstractHttp2GoAwayFrameBuilder<T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2GoAwayFrameBuilder extends AbstractHttp2FrameBuilder<Http2GoAwayFrameBuilder,Http2GoAwayFrame> {
         private int lastStreamID;
         
-        private int errorCode;
+        private long errorCode;
         
-        private byte[] data;
+        private byte[] data = EMPTY_BYTE_ARRAY;
         
-        @SuppressWarnings("unchecked")
-        public T lastStreamID(int lastStreamID) {
+        public Http2GoAwayFrameBuilder lastStreamID(int lastStreamID) {
             this.lastStreamID = lastStreamID;
-            return (T) this;
+            return this;
         }
         
         public int getLastStreamID() {
             return lastStreamID;
         }
 
-        @SuppressWarnings("unchecked")
-        public T errorCode(int errorCode) {
+        public Http2GoAwayFrameBuilder errorCode(long errorCode) {
             this.errorCode = errorCode;
-            return (T) this;
+            return this;
         }
         
-        public int getErrorCode() {
+        public long getErrorCode() {
             return errorCode;
         }
         
-        @SuppressWarnings("unchecked")
-        public T data(byte[] data) {
+        public Http2GoAwayFrameBuilder data(byte[] data) {
             this.data = data;
-            return (T) this;
+            return this;
         }
         
         public byte[] getData() {
             return data;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2GoAwayFrameBuilder<Builder, Http2GoAwayFrame> {
 
         @Override
         public Http2GoAwayFrame build() {
-            return new Http2GoAwayFrame(this);
+            if (getLength() == (-1)) {
+                setLength(getData().length + 8);
+            }
+            return new Http2GoAwayFrame(type(FRAME_TYPE_GOAWAY));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2GoAwayFrameBuilder builder() {
+            return new Http2GoAwayFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
index c0e5ab8..3ee02ca 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Header.java
@@ -1,5 +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.mina.http2.api;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public enum Http2Header {
 
     METHOD(":method"),

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
index aadb1bc..1dd2bcc 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
@@ -19,8 +19,16 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_HEADERS;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_HEADER_LENGTH;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+import java.nio.ByteBuffer;
+
 /**
- * An SPY data frame
+ * An HTTP2 HEADERS frame
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -33,7 +41,7 @@ public class Http2HeadersFrame extends Http2Frame {
     
     private final boolean exclusiveMode;
     
-    private final byte weight;
+    private final short weight;
     
     private final byte[] headerBlockFragment;
     
@@ -50,7 +58,7 @@ public class Http2HeadersFrame extends Http2Frame {
         return exclusiveMode;
     }
 
-    public byte getWeight() {
+    public short getWeight() {
         return weight;
     }
 
@@ -58,7 +66,25 @@ public class Http2HeadersFrame extends Http2Frame {
         return headerBlockFragment;
     }
 
-    protected <T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> Http2HeadersFrame(AbstractHttp2HeadersFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put((byte) getPadding().length);
+        }
+        if (isFlagSet(FLAGS_PRIORITY)) {
+            buffer.putInt(getExclusiveMode()?HTTP2_EXCLUSIVE_MASK | getStreamDependencyID():getStreamDependencyID());
+            buffer.put((byte) (getWeight() - 1));
+        }
+        buffer.put(getHeaderBlockFragment());
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put(getPadding());
+        }
+    }
+
+    protected Http2HeadersFrame(Http2HeadersFrameBuilder builder) {
         super(builder);
         this.padding = builder.getPadding();
         this.streamDependencyID = builder.getStreamDependencyID();
@@ -68,78 +94,83 @@ public class Http2HeadersFrame extends Http2Frame {
     }
 
     
-    public static abstract class AbstractHttp2HeadersFrameBuilder<T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2HeadersFrameBuilder extends AbstractHttp2FrameBuilder<Http2HeadersFrameBuilder,Http2HeadersFrame> {
         private byte[] padding;
         
         private int streamDependencyID;
         
-        private byte weight;
+        private short weight;
         
         private byte[] headerBlockFragment;
         
         private boolean exclusiveMode;
         
-        @SuppressWarnings("unchecked")
-        public T padding(byte[] padding) {
+        public Http2HeadersFrameBuilder padding(byte[] padding) {
             this.padding = padding;
-            return (T) this;
+            addFlag(FLAGS_PADDING);
+            return this;
         }
         
         public byte[] getPadding() {
             return padding;
         }
 
-        @SuppressWarnings("unchecked")
-        public T streamDependencyID(int streamDependencyID) {
+        public Http2HeadersFrameBuilder streamDependencyID(int streamDependencyID) {
             this.streamDependencyID = streamDependencyID;
-            return (T) this;
+            addFlag(FLAGS_PRIORITY);
+            return this;
         }
         
         public int getStreamDependencyID() {
             return streamDependencyID;
         }
 
-        @SuppressWarnings("unchecked")
-        public T exclusiveMode(boolean exclusiveMode) {
+        public Http2HeadersFrameBuilder exclusiveMode(boolean exclusiveMode) {
             this.exclusiveMode = exclusiveMode;
-            return (T) this;
+            addFlag(FLAGS_PRIORITY);
+            return this;
         }
         
         public boolean getExclusiveMode() {
             return exclusiveMode;
         }
 
-        @SuppressWarnings("unchecked")
-        public T weight(byte weight) {
+        public Http2HeadersFrameBuilder weight(short weight) {
             this.weight = weight;
-            return (T) this;
+            addFlag(FLAGS_PRIORITY);
+            return this;
         }
         
-        public byte getWeight() {
+        public short getWeight() {
             return weight;
         }
 
-        @SuppressWarnings("unchecked")
-        public T headerBlockFragment(byte[] headerBlockFragment) {
+        public Http2HeadersFrameBuilder headerBlockFragment(byte[] headerBlockFragment) {
             this.headerBlockFragment = headerBlockFragment;
-            return (T) this;
+            return this;
         }
         
         public byte[] getHeaderBlockFragment() {
             return headerBlockFragment;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2HeadersFrameBuilder<Builder, Http2HeadersFrame> {
 
         @Override
         public Http2HeadersFrame build() {
-            return new Http2HeadersFrame(this);
+            if (getLength() == (-1)) {
+                int length = getHeaderBlockFragment().length;
+                if (isFlagSet(FLAGS_PADDING)) {
+                    length += getPadding().length + 1;
+                }
+                if (isFlagSet(FLAGS_PRIORITY)) {
+                    length += 5;
+                }
+                length(length);
+            }
+            return new Http2HeadersFrame(type(FRAME_TYPE_HEADERS));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2HeadersFrameBuilder builder() {
+            return new Http2HeadersFrameBuilder();
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java b/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
index 6e8572d..994ccca 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2NameValuePair.java
@@ -1,5 +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.mina.http2.api;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public class Http2NameValuePair {
     private String name;
     private String value;

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
index c1df709..1bd87e5 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
@@ -19,6 +19,10 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PING;
+
+import java.nio.ByteBuffer;
+
 /**
  * An SPY data frame
  * 
@@ -32,35 +36,42 @@ public class Http2PingFrame extends Http2Frame {
         return data;
     }
 
-    protected <T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> Http2PingFrame(AbstractHttp2PingFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.put(getData());
+    }
+
+    protected Http2PingFrame(Http2PingFrameBuilder builder) {
         super(builder);
         this.data = builder.getData();
     }
 
     
-    public static abstract class AbstractHttp2PingFrameBuilder<T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2PingFrameBuilder extends AbstractHttp2FrameBuilder<Http2PingFrameBuilder,Http2PingFrame> {
         private byte[] data;
         
-        @SuppressWarnings("unchecked")
-        public T data(byte[] data) {
+        public Http2PingFrameBuilder data(byte[] data) {
             this.data = data;
-            return (T) this;
+            return this;
         }
         
         public byte[] getData() {
             return data;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2PingFrameBuilder<Builder, Http2PingFrame> {
 
         @Override
         public Http2PingFrame build() {
-            return new Http2PingFrame(this);
+            if (getLength() == (-1)) {
+                setLength(getData().length);
+            }
+            return new Http2PingFrame(type(FRAME_TYPE_PING));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2PingFrameBuilder builder() {
+            return new Http2PingFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
index 5478c69..1f766d3 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
@@ -19,8 +19,13 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+import java.nio.ByteBuffer;
+
 /**
- * An SPY data frame
+ * An HTTP2 PRIORITY frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -44,7 +49,16 @@ public class Http2PriorityFrame extends Http2Frame {
         return weight;
     }
 
-    protected <T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> Http2PriorityFrame(AbstractHttp2PriorityFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.putInt(getExclusiveMode()?HTTP2_EXCLUSIVE_MASK | getStreamDependencyID():getStreamDependencyID());
+        buffer.put((byte) (getWeight() - 1));
+    }
+
+    protected Http2PriorityFrame(Http2PriorityFrameBuilder builder) {
         super(builder);
         this.streamDependencyID = builder.getStreamDependencyID();
         this.exclusiveMode = builder.exclusiveMode;
@@ -52,54 +66,50 @@ public class Http2PriorityFrame extends Http2Frame {
     }
 
     
-    public static abstract class AbstractHttp2PriorityFrameBuilder<T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2PriorityFrameBuilder extends AbstractHttp2FrameBuilder<Http2PriorityFrameBuilder,Http2PriorityFrame> {
         private int streamDependencyID;
         
         private boolean exclusiveMode;
         
         private short weight;
         
-        @SuppressWarnings("unchecked")
-        public T streamDependencyID(int streamDependencyID) {
+        public Http2PriorityFrameBuilder streamDependencyID(int streamDependencyID) {
             this.streamDependencyID = streamDependencyID;
-            return (T) this;
+            return this;
         }
         
         public int getStreamDependencyID() {
             return streamDependencyID;
         }
         
-        @SuppressWarnings("unchecked")
-        public T exclusiveMode(boolean exclusiveMode) {
+        public Http2PriorityFrameBuilder exclusiveMode(boolean exclusiveMode) {
             this.exclusiveMode = exclusiveMode;
-            return (T) this;
+            return this;
         }
         
         public boolean getExclusiveMode() {
             return exclusiveMode;
         }
 
-
-        @SuppressWarnings("unchecked")
-        public T weight(short weight) {
+        public Http2PriorityFrameBuilder weight(short weight) {
             this.weight = weight;
-            return (T) this;
+            return this;
         }
         
         public short getWeight() {
             return weight;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2PriorityFrameBuilder<Builder, Http2PriorityFrame> {
 
         @Override
         public Http2PriorityFrame build() {
-            return new Http2PriorityFrame(this);
+            if (getLength() == (-1)) {
+                setLength(5);
+            }
+            return new Http2PriorityFrame(type(FRAME_TYPE_PRIORITY));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2PriorityFrameBuilder builder() {
+            return new Http2PriorityFrameBuilder();
         }
     }
-}
+ }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
index a2ab2c7..c28b4f6 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
@@ -20,6 +20,10 @@
 package org.apache.mina.http2.api;
 
 import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PUSH_PROMISE;
+
+import java.nio.ByteBuffer;
 
 /**
  * An SPY data frame
@@ -48,60 +52,77 @@ public class Http2PushPromiseFrame extends Http2Frame {
         return headerBlockFragment;
     }
 
-    protected <T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> Http2PushPromiseFrame(AbstractHttp2PushPromiseFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put((byte) getPadding().length);
+        }
+        buffer.putInt(getPromisedStreamID());
+        buffer.put(getHeaderBlockFragment());
+        if (isFlagSet(FLAGS_PADDING)) {
+            buffer.put(getPadding());
+        }
+    }
+
+    protected Http2PushPromiseFrame(Http2PushPromiseFrameBuilder builder) {
         super(builder);
         this.padding = builder.getPadding();
         this.promisedStreamID = builder.getPromisedStreamID();
         this.headerBlockFragment = builder.getHeaderBlockFragment();
     }
 
-    public static abstract class AbstractHttp2PushPromiseFrameBuilder<T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2PushPromiseFrameBuilder extends AbstractHttp2FrameBuilder<Http2PushPromiseFrameBuilder,Http2PushPromiseFrame> {
         private byte[] padding = EMPTY_BYTE_ARRAY;
         
         private int promisedStreamID;
         
         private byte[] headerBlockFragment = EMPTY_BYTE_ARRAY;
         
-        @SuppressWarnings("unchecked")
-        public T padding(byte[] padding) {
+        public Http2PushPromiseFrameBuilder padding(byte[] padding) {
             this.padding = padding;
-            return (T) this;
+            addFlag(FLAGS_PADDING);
+            return this;
         }
         
         public byte[] getPadding() {
             return padding;
         }
 
-        @SuppressWarnings("unchecked")
-        public T promisedStreamID(int promisedStreamID) {
+        public Http2PushPromiseFrameBuilder promisedStreamID(int promisedStreamID) {
             this.promisedStreamID = promisedStreamID;
-            return (T) this;
+            return this;
         }
         
         public int getPromisedStreamID() {
             return promisedStreamID;
         }
 
-        @SuppressWarnings("unchecked")
-        public T headerBlockFragment(byte[] headerBlockFragment) {
+        public Http2PushPromiseFrameBuilder headerBlockFragment(byte[] headerBlockFragment) {
             this.headerBlockFragment = headerBlockFragment;
-            return (T) this;
+            return this;
         }
         
         public byte[] getHeaderBlockFragment() {
             return headerBlockFragment;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2PushPromiseFrameBuilder<Builder, Http2PushPromiseFrame> {
 
         @Override
         public Http2PushPromiseFrame build() {
-            return new Http2PushPromiseFrame(this);
+            if (getLength() == (-1)) {
+                int length = getHeaderBlockFragment().length + 4;
+                if (isFlagSet(FLAGS_PADDING)) {
+                    length += getPadding().length + 1;
+                }
+                setLength(length);
+            }
+            return new Http2PushPromiseFrame(type(FRAME_TYPE_PUSH_PROMISE));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2PushPromiseFrameBuilder builder() {
+            return new Http2PushPromiseFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
index 1536594..b6bcb23 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
@@ -19,8 +19,11 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_RST_STREAM;
+
+import java.nio.ByteBuffer;
 /**
- * An SPY data frame
+ * An HTTP2 RST_STREAM frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -32,35 +35,42 @@ public class Http2RstStreamFrame extends Http2Frame {
         return errorCode;
     }
 
-    protected <T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> Http2RstStreamFrame(AbstractHttp2RstStreamFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.putInt((int) getErrorCode());
+    }
+
+    protected Http2RstStreamFrame(Http2RstStreamFrameBuilder builder) {
         super(builder);
         this.errorCode = builder.getErrorCode();
     }
 
     
-    public static abstract class AbstractHttp2RstStreamFrameBuilder<T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2RstStreamFrameBuilder extends AbstractHttp2FrameBuilder<Http2RstStreamFrameBuilder,Http2RstStreamFrame> {
         private long errorCode;
         
-        @SuppressWarnings("unchecked")
-        public T errorCode(long errorCode) {
+        public Http2RstStreamFrameBuilder errorCode(long errorCode) {
             this.errorCode = errorCode;
-            return (T) this;
+            return this;
         }
         
         public long getErrorCode() {
             return errorCode;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2RstStreamFrameBuilder<Builder, Http2RstStreamFrame> {
 
         @Override
         public Http2RstStreamFrame build() {
-            return new Http2RstStreamFrame(this);
+            if (getLength() == (-1)) {
+                setLength(4);
+            }
+            return new Http2RstStreamFrame(type(FRAME_TYPE_RST_STREAM));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2RstStreamFrameBuilder builder() {
+            return new Http2RstStreamFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
index acccb65..f78e9aa 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Setting.java
@@ -1,10 +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.mina.http2.api;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public class Http2Setting {
     private int ID;
 
     private long value;
 
+    public Http2Setting(int ID, long value) {
+        this.ID = ID;
+        this.value = value;
+    }
+    
+    /**
+     * Default empty constructor 
+     */
+    public Http2Setting() {
+    }
+
     public int getID() {
         return ID;
     }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
index 66c44ba..d72d5ee 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
@@ -19,10 +19,13 @@
  */
 package org.apache.mina.http2.api;
 
+import java.nio.ByteBuffer;
 import java.util.Collection;
+import java.util.Collections;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_SETTINGS;
 /**
- * An SPY data frame
+ * An HTTP2 SETTINGS frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -34,35 +37,44 @@ public class Http2SettingsFrame extends Http2Frame {
         return settings;
     }
 
-    protected <T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> Http2SettingsFrame(AbstractHttp2SettingsFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        for(Http2Setting setting : getSettings()) {
+            buffer.putShort((short) setting.getID());
+            buffer.putInt((int) setting.getValue());
+        }
+    }
+
+    protected Http2SettingsFrame(Http2SettingsFrameBuilder builder) {
         super(builder);
         this.settings = builder.getSettings();
     }
 
-    
-    public static abstract class AbstractHttp2SettingsFrameBuilder<T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> extends AbstractHttp2FrameBuilder<T,V> {
-        private Collection<Http2Setting> settings;
+    public static class Http2SettingsFrameBuilder extends AbstractHttp2FrameBuilder<Http2SettingsFrameBuilder,Http2SettingsFrame> {
+        private Collection<Http2Setting> settings = Collections.emptyList();
         
-        @SuppressWarnings("unchecked")
-        public T settings(Collection<Http2Setting> settings) {
+        public Http2SettingsFrameBuilder settings(Collection<Http2Setting> settings) {
             this.settings = settings;
-            return (T) this;
+            return this;
         }
         
         public Collection<Http2Setting> getSettings() {
             return settings;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2SettingsFrameBuilder<Builder, Http2SettingsFrame> {
 
         @Override
         public Http2SettingsFrame build() {
-            return new Http2SettingsFrame(this);
+            if (getLength() == (-1)) {
+                setLength(getSettings().size() * 6);
+            }
+            return new Http2SettingsFrame(type(FRAME_TYPE_SETTINGS));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2SettingsFrameBuilder builder() {
+            return new Http2SettingsFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
index 1cdcaef..8714100 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
@@ -19,8 +19,10 @@
  */
 package org.apache.mina.http2.api;
 
+import java.nio.ByteBuffer;
+
 /**
- * An SPY data frame
+ * An HTTP2 unknown frame.
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
@@ -32,35 +34,42 @@ public class Http2UnknownFrame extends Http2Frame {
         return payload;
     }
 
-    protected <T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> Http2UnknownFrame(AbstractHttp2UnknownFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.put(getPayload());
+    }
+
+    protected Http2UnknownFrame(Http2UnknownFrameBuilder builder) {
         super(builder);
         this.payload = builder.getPayload();
     }
 
     
-    public static abstract class AbstractHttp2UnknownFrameBuilder<T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2UnknownFrameBuilder extends AbstractHttp2FrameBuilder<Http2UnknownFrameBuilder,Http2UnknownFrame> {
         private byte[] payload = new byte[0];
         
-        @SuppressWarnings("unchecked")
-        public T payload(byte[] payload) {
+        public Http2UnknownFrameBuilder payload(byte[] payload) {
             this.payload = payload;
-            return (T) this;
+            return this;
         }
         
         public byte[] getPayload() {
             return payload;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2UnknownFrameBuilder<Builder, Http2UnknownFrame> {
 
         @Override
         public Http2UnknownFrame build() {
+            if (getLength() == (-1)) {
+                setLength(getPayload().length);
+            }
             return new Http2UnknownFrame(this);
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2UnknownFrameBuilder builder() {
+            return new Http2UnknownFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
index f552aaf..c468d81 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
@@ -19,6 +19,10 @@
  */
 package org.apache.mina.http2.api;
 
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_WINDOW_UPDATE;
+
+import java.nio.ByteBuffer;
+
 /**
  * An SPY data frame
  * 
@@ -32,35 +36,42 @@ public class Http2WindowUpdateFrame extends Http2Frame {
         return windowUpdateIncrement;
     }
 
-    protected <T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> Http2WindowUpdateFrame(AbstractHttp2WindowUpdateFrameBuilder<T, V> builder) {
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.Http2Frame#writePayload(java.nio.ByteBuffer)
+     */
+    @Override
+    public void writePayload(ByteBuffer buffer) {
+        buffer.putInt(getWindowUpdateIncrement());
+    }
+
+    protected Http2WindowUpdateFrame(Http2WindowUpdateFrameBuilder builder) {
         super(builder);
         this.windowUpdateIncrement = builder.getWindowUpdateIncrement();
     }
 
     
-    public static abstract class AbstractHttp2WindowUpdateFrameBuilder<T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> extends AbstractHttp2FrameBuilder<T,V> {
+    public static class Http2WindowUpdateFrameBuilder extends AbstractHttp2FrameBuilder<Http2WindowUpdateFrameBuilder,Http2WindowUpdateFrame> {
         private int windowUpdateIncrement;
         
-        @SuppressWarnings("unchecked")
-        public T windowUpdateIncrement(int windowUpdateIncrement) {
+        public Http2WindowUpdateFrameBuilder windowUpdateIncrement(int windowUpdateIncrement) {
             this.windowUpdateIncrement = windowUpdateIncrement;
-            return (T) this;
+            return this;
         }
         
         public int getWindowUpdateIncrement() {
             return windowUpdateIncrement;
         }
-    }
-    
-    public static class Builder extends AbstractHttp2WindowUpdateFrameBuilder<Builder, Http2WindowUpdateFrame> {
 
         @Override
         public Http2WindowUpdateFrame build() {
-            return new Http2WindowUpdateFrame(this);
+            if (getLength() == (-1)) {
+                setLength(4);
+            }
+            return new Http2WindowUpdateFrame(type(FRAME_TYPE_WINDOW_UPDATE));
         }
         
-        public static Builder builder() {
-            return new Builder();
+        public static Http2WindowUpdateFrameBuilder builder() {
+            return new Http2WindowUpdateFrameBuilder();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
deleted file mode 100644
index 5e6076d..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/IntPartialDecoder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.api;
-
-import java.nio.ByteBuffer;
-
-/**
- * @author jeffmaury
- *
- */
-public class IntPartialDecoder implements PartialDecoder<Integer> {
-    private int size;
-    private int remaining;
-    private int value;
-    
-    /**
-     * Decode an integer whose size is different from the standard 4.
-     * 
-     * @param size the size (1,2,3,4) to decode
-     */
-    public IntPartialDecoder(int size) {
-        this.remaining = size;
-        this.size = size;
-    }
-
-    /**
-     * Decode a 4 bytes integer 
-     */
-    public IntPartialDecoder() {
-        this(4);
-    }
-    
-    public boolean consume(ByteBuffer buffer) {
-        if (remaining == 0) {
-            throw new IllegalStateException();
-        }
-        while (remaining > 0 && buffer.hasRemaining()) {
-            value = (value << 8) + (buffer.get() & 0x00FF);
-            --remaining;
-        }
-        return remaining == 0;
-    }
-    
-    public Integer getValue() {
-        if (remaining > 0) {
-            throw new IllegalStateException();
-        }
-        return value;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.mina.http2.api.PartialDecoder#reset()
-     */
-    @Override
-    public void reset() {
-        remaining = size;
-        value = 0;
-    }
-    
-    
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
deleted file mode 100644
index dae0c2f..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/LongPartialDecoder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.api;
-
-import java.nio.ByteBuffer;
-
-/**
- * @author jeffmaury
- *
- */
-public class LongPartialDecoder implements PartialDecoder<Long> {
-    private int size;
-    private int remaining;
-    private long value;
-    
-    /**
-     * Decode a long integer whose size is different from the standard 8.
-     * 
-     * @param size the size (1 to 8) to decode
-     */
-    public LongPartialDecoder(int size) {
-        this.remaining = size;
-        this.size = size;
-    }
-
-    /**
-     * Decode a 8 bytes long integer 
-     */
-    public LongPartialDecoder() {
-        this(8);
-    }
-    
-    public boolean consume(ByteBuffer buffer) {
-        if (remaining == 0) {
-            throw new IllegalStateException();
-        }
-        while (remaining > 0 && buffer.hasRemaining()) {
-            value = (value << 8) + (buffer.get() & 0x00FF);
-            --remaining;
-        }
-        return remaining == 0;
-    }
-    
-    public Long getValue() {
-        if (remaining > 0) {
-            throw new IllegalStateException();
-        }
-        return value;
-    }
-
-    /* (non-Javadoc)
-     * @see org.apache.mina.http2.api.PartialDecoder#reset()
-     */
-    @Override
-    public void reset() {
-        remaining = size;
-        value = 0;
-    }
-    
-    
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
deleted file mode 100644
index 070b7ce..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/PartialDecoder.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 
- */
-package org.apache.mina.http2.api;
-
-import java.nio.ByteBuffer;
-
-/**
- * @author jeffmaury
- *
- */
-public interface PartialDecoder<T> {
-    /**
-     * Consume the buffer so as to decode a value. Not all the input buffer
-     * may be consumed.
-     * 
-     * @param buffer the input buffer to decode
-     * @return true if a value is available false if more data is requested
-     */
-    public boolean consume(ByteBuffer buffer);
-    
-    /**
-     * Return the decoded value.
-     * 
-     * @return the decoded value
-     */
-    public T getValue();
-    
-    /**
-     * Reset the internal state of the decoder to that new decoding can take place.
-     */
-    public void reset();
-
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java b/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
deleted file mode 100644
index 41f85b0..0000000
--- a/http2/src/main/java/org/apache/mina/http2/api/StreamMessage.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.apache.mina.http2.api;
-
-/**
- * Marker interface for messages that are attached to a specific stream.
- * That may not be a start of HTTP PDU (request or response) as they are the
- * one that creates new streams.
- * The use of this interface is not mandatory but not using it will cause
- * request and responses to be pipelined.
- * 
- * @author jeffmaury
- *
- */
-public interface StreamMessage {
-
-    /**
-     * Return the stream ID the message is attached to.
-     * 
-     * @return the stream ID
-     */
-    public int getStreamID();
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolDecoder.java b/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolDecoder.java
new file mode 100644
index 0000000..d87060e
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolDecoder.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.http2.codec;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.codec.ProtocolDecoder;
+import org.apache.mina.http2.api.Http2Frame;
+import org.apache.mina.http2.impl.Http2Connection;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2ProtocolDecoder implements ProtocolDecoder<ByteBuffer, Http2Frame, Http2Connection> {
+
+    @Override
+    public Http2Connection createDecoderState() {
+        return new Http2Connection();
+    }
+
+    @Override
+    public Http2Frame decode(ByteBuffer input, Http2Connection context) {
+        return context.decode(input);
+    }
+
+    @Override
+    public void finishDecode(Http2Connection context) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolEncoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolEncoder.java b/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolEncoder.java
new file mode 100644
index 0000000..bd1655c
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/codec/Http2ProtocolEncoder.java
@@ -0,0 +1,42 @@
+/*
+ *  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.http2.codec;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.codec.StatelessProtocolEncoder;
+import org.apache.mina.http2.api.Http2Frame;
+
+/**
+ *      
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2ProtocolEncoder implements StatelessProtocolEncoder<Http2Frame, ByteBuffer> {
+
+    @Override
+    public Void createEncoderState() {
+        return null;
+    }
+
+    @Override
+    public ByteBuffer encode(Http2Frame message, Void context) {
+        return message.toBuffer();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/BytePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/BytePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/BytePartialDecoder.java
new file mode 100644
index 0000000..9153b97
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/BytePartialDecoder.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.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class BytePartialDecoder implements PartialDecoder<byte[]> {
+    private int offset;
+    private byte[] value;
+    
+    /**
+     * Decode an byte array.
+     * 
+     * @param size the size of the byte array to decode
+     */
+    public BytePartialDecoder(int size) {
+        this.offset = 0;
+        this.value = new byte[size];
+    }
+
+    public boolean consume(ByteBuffer buffer) {
+        if (value.length - offset == 0) {
+            throw new IllegalStateException();
+        }
+        int length = Math.min(buffer.remaining(), value.length - offset);
+        buffer.get(value, offset, length);
+        offset += length;
+        return value.length - offset == 0;
+    }
+    
+    public byte[] getValue() {
+        if (value.length - offset > 0) {
+            throw new IllegalStateException();
+        }
+        return value;
+    }
+
+    /** 
+     * {@inheritDoc}
+     */
+    @Override
+    public void reset() {
+        offset = 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java b/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
index 3afb72d..6c51612 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/HeadersEncoder.java
@@ -1,3 +1,22 @@
+/*
+ *  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.http2.impl;
 
 import java.io.IOException;
@@ -11,6 +30,10 @@ import com.twitter.hpack.Encoder;
 
 import static org.apache.mina.http2.api.Http2Constants.US_ASCII_CHARSET;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public class HeadersEncoder {
 
     private final Encoder encoder;

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
index 9ec5b4f..584e6f2 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
@@ -1,10 +1,29 @@
+/*
+ *  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.http2.impl;
 
 import java.nio.ByteBuffer;
 
 import org.apache.mina.http2.api.Http2Frame;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+
 import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_DATA;
 import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_HEADERS;
 import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PRIORITY;
@@ -16,6 +35,10 @@ import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_GOAWAY;
 import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_WINDOW_UPDATE;
 import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_CONTINUATION;
 
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
 public class Http2Connection {
 
     private static enum DecoderState {

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
index 39f6706..d9ca244 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
@@ -1,23 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2ContinuationFrame.Builder;
+import org.apache.mina.http2.api.Http2ContinuationFrame.Http2ContinuationFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2ContinuationFrameDecoder extends Http2FrameDecoder {
 
     private BytePartialDecoder decoder;
     
-    private Builder builder = new Builder();
+    private Http2ContinuationFrameBuilder builder = new Http2ContinuationFrameBuilder();
     
     public Http2ContinuationFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
index 7a07812..6763e55 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
@@ -1,20 +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.mina.http2.impl;
 
 import java.nio.ByteBuffer;
 
-import org.apache.mina.http2.api.BytePartialDecoder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.Http2DataFrame.Builder;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.api.Http2DataFrame.Http2DataFrameBuilder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public class Http2DataFrameDecoder extends Http2FrameDecoder {
 
@@ -30,7 +44,7 @@ public class Http2DataFrameDecoder extends Http2FrameDecoder {
     
     private int padLength;
     
-    private Builder builder = new Builder();
+    private Http2DataFrameBuilder builder = new Http2DataFrameBuilder();
     
     public Http2DataFrameDecoder(Http2FrameHeader header) {
         super(header);

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
index e59c41e..003bd53 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
@@ -1,16 +1,31 @@
-/**
- * 
+/*
+ *  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.http2.impl;
 
 import org.apache.mina.http2.api.Http2Frame;
 import org.apache.mina.http2.api.Http2Frame.AbstractHttp2FrameBuilder;
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.apache.mina.http2.api.PartialDecoder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 
 /**
- * @author jeffmaury
- *
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
 public abstract class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
     private Http2FrameHeader header;


[4/8] mina git commit: Complete low level HTTP2

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/impl/BytePartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/impl/BytePartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/impl/BytePartialDecoderTest.java
new file mode 100644
index 0000000..6a30567
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/impl/BytePartialDecoderTest.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.mina.http2.impl;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.BytePartialDecoder;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class BytePartialDecoderTest {
+
+    private static final byte[] SAMPLE_VALUE_1 = new byte[] {0x74, 0x18, 0x4F, 0x68};
+    private static final byte[] SAMPLE_VALUE_2 = new byte[] {0x74, 0x18, 0x4F, 0x68, 0x0F};
+
+    @Test
+    public void checkSimpleValue() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_1);
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+    }
+    
+    @Test
+    public void checkNotenoughData() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+    }
+
+    @Test
+    public void checkTooMuchData() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(SAMPLE_VALUE_2);
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+        assertEquals(1, buffer.remaining());
+    }
+
+    @Test
+    public void checkDecodingIn2Steps() {
+        BytePartialDecoder decoder = new BytePartialDecoder(4);
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[0], SAMPLE_VALUE_2[1]});
+        assertFalse(decoder.consume(buffer));
+        buffer = ByteBuffer.wrap(new byte[] {SAMPLE_VALUE_2[2], SAMPLE_VALUE_2[3], SAMPLE_VALUE_2[4]});
+        assertTrue(decoder.consume(buffer));
+        assertArrayEquals(SAMPLE_VALUE_1, decoder.getValue());
+        assertEquals(1, buffer.remaining());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/impl/Http2FrameHeaderPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/impl/Http2FrameHeaderPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/impl/Http2FrameHeaderPartialDecoderTest.java
new file mode 100644
index 0000000..dc12569
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/impl/Http2FrameHeaderPartialDecoderTest.java
@@ -0,0 +1,87 @@
+/*
+ *  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.http2.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder;
+import org.apache.mina.http2.impl.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2FrameHeaderPartialDecoderTest {
+
+    @Test
+    public void checkStandardValue() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        0x00, 0x00, 0x00, 0x01 /*streamID*/});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(0, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+    }
+
+    @Test
+    public void checkReservedBitIsNotTransmitted() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        (byte)0x80, 0x00, 0x00, 0x01 /*streamID*/});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(0, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+    }
+    
+    @Test
+    public void checkPayLoadIsTransmitted() {
+        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x01, /*length*/
+                                                        0x00, /*type*/
+                                                        0x00, /*flags*/
+                                                        (byte)0x80, 0x00, 0x00, 0x01, /*streamID*/
+                                                        0x40});
+        assertTrue(decoder.consume(buffer));
+        Http2FrameHeader header = decoder.getValue();
+        assertNotNull(header);
+        assertEquals(1, header.getLength());
+        assertEquals(0, header.getType());
+        assertEquals(0, header.getFlags());
+        assertEquals(1, header.getStreamID());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/impl/IntPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/impl/IntPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/impl/IntPartialDecoderTest.java
new file mode 100644
index 0000000..674a76e
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/impl/IntPartialDecoderTest.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.mina.http2.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.impl.IntPartialDecoder;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class IntPartialDecoderTest {
+
+    @Test
+    public void checkSimpleValue() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+    }
+    
+    @Test
+    public void checkNotenoughData() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+    }
+
+    @Test
+    public void checkTooMuchData() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+        assertEquals(1, buffer.remaining());
+    }
+
+    @Test
+    public void checkDecodingIn2Steps() {
+        IntPartialDecoder decoder = new IntPartialDecoder();
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
+        assertFalse(decoder.consume(buffer));
+        buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00});
+        assertTrue(decoder.consume(buffer));
+        assertEquals(0, decoder.getValue().intValue());
+        assertEquals(1, buffer.remaining());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 97a960e..cc851e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -111,6 +111,7 @@
     <module>core</module>
     <module>codec</module>
     <module>http</module>
+    <module>http2</module>
     <module>examples</module>
     <module>coap</module>
     <module>thrift</module>


[5/8] mina git commit: Complete low level HTTP2

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
deleted file mode 100644
index 073464e..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2SettingsFrameDecoderTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2SettingsFrameDecoderTest {
-
-    @Test
-    public void checkRstStream() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
-                                                        0x04, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x00, 0x01, /*ID*/
-                                                        0x01, 0x02, 0x03, 0x04, /*value*/});
-        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(6, frame.getLength());
-        assertEquals(4, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(1, frame.getSettings().size());
-        Http2Setting setting = frame.getSettings().iterator().next();
-        assertEquals(1, setting.getID());
-        assertEquals(0x01020304L, setting.getValue());
-    }
-
-    @Test
-    public void checkRstStreamHighestID() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
-                                                        0x04, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        (byte) 0xFF, (byte) 0xFF, /*ID*/
-                                                        0x01, 0x02, 0x03, 0x04, /*value*/});
-        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(6, frame.getLength());
-        assertEquals(4, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(1, frame.getSettings().size());
-        Http2Setting setting = frame.getSettings().iterator().next();
-        assertEquals(0x00FFFF, setting.getID());
-        assertEquals(0x01020304L, setting.getValue());
-    }
- 
-    @Test
-    public void checkRstStreamHighestValue() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x06, /*length*/
-                                                        0x04, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x00, 0x01, /*ID*/
-                                                        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, /*value*/});
-        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(6, frame.getLength());
-        assertEquals(4, frame.getType());
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(1, frame.getSettings().size());
-        Http2Setting setting = frame.getSettings().iterator().next();
-        assertEquals(1, setting.getID());
-        assertEquals(0xFFFFFFFFL, setting.getValue());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
deleted file mode 100644
index ffc6149..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2UnknownFrameDecoderTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.impl.Http2Connection;
-import org.junit.Test;
-
-public class Htp2UnknownFrameDecoderTest {
-
-    @Test
-    public void checkUnknownFrame() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x02, /*length*/
-                                                        (byte) 0x00FF, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20, /*streamID*/
-                                                        0x0E, 0x18});
-        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(2, frame.getLength());
-        assertEquals(255, frame.getType() & 0x00FF);
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(2, frame.getPayload().length);
-        assertArrayEquals(new byte[] {0x0E,  0x18}, frame.getPayload());
-    }
-
-    @Test
-    public void checkUnknownFrameWithoutPayload() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
-                                                        (byte) 0x00FF, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x20 /*streamID*/});
-        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(0, frame.getLength());
-        assertEquals(255, frame.getType() & 0x00FF);
-        assertEquals(0x00, frame.getFlags());
-        assertEquals(32, frame.getStreamID());
-        assertEquals(0, frame.getPayload().length);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2ContinuationFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2ContinuationFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2ContinuationFrameTest.java
new file mode 100644
index 0000000..0c0329f
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2ContinuationFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2ContinuationFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoHeaderFragment() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_BUFFER);
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getHeaderBlockFragment().length);
+    }
+    
+    @Test
+    public void encodeNoHeaderFragment() {
+        Http2ContinuationFrame frame = TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_FRAME;
+        assertArrayEquals(TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodeHeaderFragment() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.CONTINUATION_HEADER_FRAGMENT_BUFFER);
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getHeaderBlockFragment().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getHeaderBlockFragment());
+    }
+
+    @Test
+    public void encodeHeaderFragment() {
+        Http2ContinuationFrame frame = TestMessages.CONTINUATION_HEADER_FRAGMENT_FRAME;
+        assertArrayEquals(TestMessages.CONTINUATION_HEADER_FRAGMENT_BUFFER, toByteArray(frame.toBuffer()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2DataFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2DataFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2DataFrameTest.java
new file mode 100644
index 0000000..5c7ff95
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2DataFrameTest.java
@@ -0,0 +1,122 @@
+/*
+ *  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.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2DataFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoPayloadNoPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_NO_PAYLOAD_NO_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getData().length);
+        assertEquals(0, frame.getPadding().length);
+    }
+    
+    @Test
+    public void encodeNoPayloadNoPadding() {
+        Http2DataFrame frame = TestMessages.DATA_NO_PAYLOAD_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_NO_PAYLOAD_NO_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodePayloadNoPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_PAYLOAD_NO_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(0, frame.getPadding().length);
+    }
+
+    @Test
+    public void encodePayloadNoPadding() {
+        Http2DataFrame frame = TestMessages.DATA_PAYLOAD_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_PAYLOAD_NO_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeNoPayloadPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_NO_PAYLOAD_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(3, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0,frame.getData().length);
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E,  0x28}, frame.getPadding());
+    }
+    
+    @Test
+    public void encodeNoPayloadPadding() {
+        Http2DataFrame frame = TestMessages.DATA_NO_PAYLOAD_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_NO_PAYLOAD_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodePayloadPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_PAYLOAD_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(13, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E, 0x28}, frame.getPadding());
+    }
+
+    @Test
+    public void encodePayloadPadding() {
+        Http2DataFrame frame = TestMessages.DATA_PAYLOAD_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_PAYLOAD_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
deleted file mode 100644
index af684b4..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
-import org.junit.Test;
-
-public class Http2FrameHeaderPartialDecoderTest {
-
-    @Test
-    public void checkStandardValue() {
-        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
-                                                        0x00, /*type*/
-                                                        0x00, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x01 /*streamID*/});
-        assertTrue(decoder.consume(buffer));
-        Http2FrameHeader header = decoder.getValue();
-        assertNotNull(header);
-        assertEquals(0, header.getLength());
-        assertEquals(0, header.getType());
-        assertEquals(0, header.getFlags());
-        assertEquals(1, header.getStreamID());
-    }
-
-    @Test
-    public void checkReservedBitIsNotTransmitted() {
-        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, /*length*/
-                                                        0x00, /*type*/
-                                                        0x00, /*flags*/
-                                                        (byte)0x80, 0x00, 0x00, 0x01 /*streamID*/});
-        assertTrue(decoder.consume(buffer));
-        Http2FrameHeader header = decoder.getValue();
-        assertNotNull(header);
-        assertEquals(0, header.getLength());
-        assertEquals(0, header.getType());
-        assertEquals(0, header.getFlags());
-        assertEquals(1, header.getStreamID());
-    }
-    
-    @Test
-    public void checkPayLoadIsTransmitted() {
-        Http2FrameHeadePartialDecoder decoder = new Http2FrameHeadePartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x01, /*length*/
-                                                        0x00, /*type*/
-                                                        0x00, /*flags*/
-                                                        (byte)0x80, 0x00, 0x00, 0x01, /*streamID*/
-                                                        0x40});
-        assertTrue(decoder.consume(buffer));
-        Http2FrameHeader header = decoder.getValue();
-        assertNotNull(header);
-        assertEquals(1, header.getLength());
-        assertEquals(0, header.getType());
-        assertEquals(0, header.getFlags());
-        assertEquals(1, header.getStreamID());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2GoAwayFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2GoAwayFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2GoAwayFrameTest.java
new file mode 100644
index 0000000..1921423
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2GoAwayFrameTest.java
@@ -0,0 +1,134 @@
+/*
+ *  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.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2GoAwayFrameTest extends Http2Test {
+
+
+    @Test
+    public void decodeNoAdditionalData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void encodeWNoAdditionalData() {
+        Http2GoAwayFrame frame = TestMessages.GOAWAY_NO_DATA_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeHighestLastStreamIDNoAdditionalData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void encodeHighestLastStreamIDWNoAdditionalData() {
+        Http2GoAwayFrame frame = TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodeHighestLastStreamIDReservedBitSetNoAdditionalData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_RESERVED_BIT_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void decodeHighestErrorCodeNoAdditionalData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+    
+    @Test
+    public void encodeHighestErrorCodeNoAdditionalData() {
+        Http2GoAwayFrame frame = TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodeAdditionalData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_DATA_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(9, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getLastStreamID());
+        assertEquals(0x00010203, frame.getErrorCode());
+        assertArrayEquals(new byte[] {0x01}, frame.getData());
+    }
+    
+    @Test
+    public void encodeAdditionalData() {
+        Http2GoAwayFrame frame = TestMessages.GOAWAY_DATA_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_DATA_BUFFER, toByteArray(frame.toBuffer()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2HeadersFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2HeadersFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2HeadersFrameTest.java
new file mode 100644
index 0000000..a108474
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2HeadersFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2HeadersFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoPaddingNoPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(1, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    @Test
+    public void encodeNoPaddingNoPriority() {
+        Http2HeadersFrame frame = TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_FRAME;
+       assertArrayEquals(TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_BUFFER, toByteArray(frame.toBuffer())); 
+    }
+    
+    
+    @Test
+    public void decodePaddingPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_PADDING_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(23, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x28, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(10,  frame.getWeight());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void encodePaddingPriority() {
+        Http2HeadersFrame frame = TestMessages.HEADERS_PADDING_PRIORITY_FRAME;
+                assertArrayEquals(TestMessages.HEADERS_PADDING_PRIORITY_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodePaddingNoPriority() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_PADDING_NO_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(18, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void encodePaddingNoPriority() {
+        Http2HeadersFrame frame = TestMessages.HEADERS_PADDING_NO_PRIORITY_FRAME;
+                assertArrayEquals(TestMessages.HEADERS_PADDING_NO_PRIORITY_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2PingFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2PingFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2PingFrameTest.java
new file mode 100644
index 0000000..12d3283
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2PingFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2PingFrameTest extends Http2Test {
+
+    @Test
+    public void decode() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_STANDARD_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, frame.getData());
+    }
+    
+    @Test
+    public void encode() {
+        Http2PingFrame frame = TestMessages.PING_STANDARD_FRAME;
+        assertArrayEquals(TestMessages.PING_STANDARD_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodeExtraData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_EXTRA_DATA_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(9, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, frame.getData());
+    }
+    
+    @Test
+    public void encodeExtraData() {
+        Http2PingFrame frame = TestMessages.PING_EXTRA_DATA_FRAME;
+        assertArrayEquals(TestMessages.PING_EXTRA_DATA_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    @Test
+    public void decodeNotEnoughData() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_NO_ENOUGH_DATA_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(1, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00}, frame.getData());
+    }
+    
+    @Test
+    public void encodeNotEnoughData() {
+        Http2PingFrame frame = TestMessages.PING_NO_ENOUGH_DATA_FRAME;
+        assertArrayEquals(TestMessages.PING_NO_ENOUGH_DATA_BUFFER, toByteArray(frame.toBuffer()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2PriorityFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2PriorityFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2PriorityFrameTest.java
new file mode 100644
index 0000000..397ba36
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2PriorityFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2PriorityFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoExclusive() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_BUFFER);
+        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertFalse(frame.getExclusiveMode());
+        assertEquals(2, frame.getWeight());
+    }
+    
+    @Test
+    public void encodeNoExclusive() {
+        Http2PriorityFrame frame = TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_FRAME;
+        assertArrayEquals(TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeExclusive() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PRIORITY_EXCLUSIVE_MODE_BUFFER);
+        Http2PriorityFrame frame = (Http2PriorityFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertTrue(frame.getExclusiveMode());
+        assertEquals(2, frame.getWeight());
+    }
+ 
+    @Test
+    public void encodeExclusive() {
+        Http2PriorityFrame frame = TestMessages.PRIORITY_EXCLUSIVE_MODE_FRAME;
+        assertArrayEquals(TestMessages.PRIORITY_EXCLUSIVE_MODE_BUFFER, toByteArray(frame.toBuffer()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2PushPromiseFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2PushPromiseFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2PushPromiseFrameTest.java
new file mode 100644
index 0000000..612c788
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2PushPromiseFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2PushPromiseFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoPadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PUSH_PROMISE_NO_PADDING_BUFFER);
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(5, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getPromisedStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    @Test
+    public void encodeNoPadding() {
+        Http2PushPromiseFrame frame = TestMessages.PUSH_PROMISE_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.PUSH_PROMISE_NO_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+    
+    @Test
+    public void decodePadding() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PUSH_PROMISE_PADDING_BUFFER);
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
+        assertEquals(22, frame.getLength());
+        assertEquals(5, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(20, frame.getPromisedStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void encodePadding() {
+        Http2PushPromiseFrame frame = TestMessages.PUSH_PROMISE_PADDING_FRAME;
+        assertArrayEquals(TestMessages.PUSH_PROMISE_PADDING_BUFFER, toByteArray(frame.toBuffer()));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2RstStreamFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2RstStreamFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2RstStreamFrameTest.java
new file mode 100644
index 0000000..c8b42d5
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2RstStreamFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.api.Http2RstStreamFrame.Http2RstStreamFrameBuilder;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2RstStreamFrameTest extends Http2Test {
+
+    @Test
+    public void decodeNoExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+    
+    @Test
+    public void encodeNoExtraPayload() {
+        Http2RstStreamFrame frame = TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeHighestValueNoExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+    
+    @Test
+    public void encodeHighestValueNoExtraPayload() {
+        Http2RstStreamFrame frame = TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+
+    @Test
+    public void decodeHighestValueExtraPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_EXTRA_PAYLOAD_HIGHEST_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2SettingsFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2SettingsFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2SettingsFrameDecoderTest.java
new file mode 100644
index 0000000..3681978
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2SettingsFrameDecoderTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2SettingsFrameDecoderTest extends Http2Test {
+
+    @Test
+    public void decode() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_DEFAULT_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+    
+    @Test
+    public void encode() {
+        Http2SettingsFrame frame = TestMessages.SETTINGS_DEFAULT_FRAME;
+         assertArrayEquals(TestMessages.SETTINGS_DEFAULT_BUFFER, toByteArray(frame.toBuffer()));       
+    }
+
+    @Test
+    public void decodeHighestID() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_HIGHEST_ID_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(0x00FFFF, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+ 
+    @Test
+    public void encodeHighestID() {
+        Http2SettingsFrame frame = TestMessages.SETTINGS_HIGHEST_ID_FRAME;
+         assertArrayEquals(TestMessages.SETTINGS_HIGHEST_ID_BUFFER, toByteArray(frame.toBuffer()));       
+    }
+
+    @Test
+    public void decodeHighestValue() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_HIGHEST_VALUE_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0xFFFFFFFFL, setting.getValue());
+    }
+    
+    @Test
+    public void encodeHighestValue() {
+        Http2SettingsFrame frame = TestMessages.SETTINGS_HIGHEST_VALUE_FRAME;
+         assertArrayEquals(TestMessages.SETTINGS_HIGHEST_VALUE_BUFFER, toByteArray(frame.toBuffer()));       
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/Http2UnknownFrameTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2UnknownFrameTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2UnknownFrameTest.java
new file mode 100644
index 0000000..764e924
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2UnknownFrameTest.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.mina.http2.api;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class Http2UnknownFrameTest extends Http2Test {
+
+    @Test
+    public void decode() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.UNKNOWN_PAYLOAD_BUFFER);
+        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(2, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(2, frame.getPayload().length);
+        assertArrayEquals(new byte[] {0x0E,  0x18}, frame.getPayload());
+    }
+    
+    @Test
+    public void encode() {
+        Http2UnknownFrame frame = TestMessages.UNKNOWN_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.UNKNOWN_PAYLOAD_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+    @Test
+    public void decodeWithoutPayload() {
+        Http2Connection connection = new Http2Connection();
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.UNKNOWN_NO_PAYLOAD_BUFFER);
+        Http2UnknownFrame frame = (Http2UnknownFrame) connection.decode(buffer);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0, frame.getPayload().length);
+    }
+    
+    @Test
+    public void encodeWithoutPayload() {
+        Http2UnknownFrame frame = TestMessages.UNKNOWN_NO_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.UNKNOWN_NO_PAYLOAD_BUFFER, toByteArray(frame.toBuffer()));
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
deleted file mode 100644
index 78c9125..0000000
--- a/http2/src/test/java/org/apache/mina/http2/api/IntPartialDecoderTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.apache.mina.http2.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.nio.ByteBuffer;
-
-import org.junit.Test;
-
-public class IntPartialDecoderTest {
-
-    @Test
-    public void checkSimpleValue() {
-        IntPartialDecoder decoder = new IntPartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00});
-        assertTrue(decoder.consume(buffer));
-        assertEquals(0, decoder.getValue().intValue());
-    }
-    
-    @Test
-    public void checkNotenoughData() {
-        IntPartialDecoder decoder = new IntPartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
-        assertFalse(decoder.consume(buffer));
-    }
-
-    @Test
-    public void checkTooMuchData() {
-        IntPartialDecoder decoder = new IntPartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00, 0x00, 0x00});
-        assertTrue(decoder.consume(buffer));
-        assertEquals(0, decoder.getValue().intValue());
-        assertEquals(1, buffer.remaining());
-    }
-
-    @Test
-    public void checkDecodingIn2Steps() {
-        IntPartialDecoder decoder = new IntPartialDecoder();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00});
-        assertFalse(decoder.consume(buffer));
-        buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x00});
-        assertTrue(decoder.consume(buffer));
-        assertEquals(0, decoder.getValue().intValue());
-        assertEquals(1, buffer.remaining());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolDecoderTest.java
new file mode 100644
index 0000000..6a478dd
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolDecoderTest.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.mina.http2.codec;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.api.Http2ContinuationFrame;
+import org.apache.mina.http2.api.Http2DataFrame;
+import org.apache.mina.http2.api.Http2Frame;
+import org.apache.mina.http2.api.Http2GoAwayFrame;
+import org.apache.mina.http2.api.Http2HeadersFrame;
+import org.apache.mina.http2.api.Http2PingFrame;
+import org.apache.mina.http2.api.Http2PriorityFrame;
+import org.apache.mina.http2.api.Http2PushPromiseFrame;
+import org.apache.mina.http2.api.Http2RstStreamFrame;
+import org.apache.mina.http2.api.Http2Setting;
+import org.apache.mina.http2.api.Http2SettingsFrame;
+import org.apache.mina.http2.api.Http2UnknownFrame;
+import org.apache.mina.http2.impl.Http2Connection;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+
+public class Http2ProtocolDecoderTest extends Http2Test {
+
+    private Http2ProtocolDecoder decoder = new Http2ProtocolDecoder();
+    private Http2Connection context = new Http2Connection();
+    
+    @Test
+    public void continuationNoHeaderBlock() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_BUFFER);
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getHeaderBlockFragment().length);
+    }
+
+    @Test
+    public void continuationHeaderBlock() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.CONTINUATION_HEADER_FRAGMENT_BUFFER);
+        Http2ContinuationFrame frame = (Http2ContinuationFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(9, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getHeaderBlockFragment().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getHeaderBlockFragment());
+    }
+    
+    @Test
+    public void dataNoPayloadNoPadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_NO_PAYLOAD_NO_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0, frame.getData().length);
+        assertEquals(0, frame.getPadding().length);
+    }
+    
+    @Test
+    public void dataPayloadNoPadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_PAYLOAD_NO_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(10, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(0, frame.getPadding().length);
+    }
+    
+    @Test
+    public void dataNoPayloadPadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_NO_PAYLOAD_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(3, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(0,frame.getData().length);
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E,  0x28}, frame.getPadding());
+    }
+    
+    @Test
+    public void dataPayloadPadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.DATA_PAYLOAD_PADDING_BUFFER);
+        Http2DataFrame frame = (Http2DataFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(13, frame.getLength());
+        assertEquals(0, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(50, frame.getStreamID());
+        assertEquals(10, frame.getData().length);
+        assertArrayEquals(new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, frame.getData());
+        assertEquals(2, frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x0E, 0x28}, frame.getPadding());
+    }
+    
+    @Test
+    public void goAwayNoAdditionalData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void goAwayHighestLastStreamIDNoAdditionalData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void goAwayHighestLastStreamIDReservedBitSetNoAdditionalData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_RESERVED_BIT_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x010203, frame.getErrorCode());
+    }
+    
+    @Test
+    public void goAwayHighestErrorCodeNoAdditionalData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(0x7FFFFFFF, frame.getLastStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+    
+    @Test
+    public void goAwayAdditionalData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.GOAWAY_DATA_BUFFER);
+        Http2GoAwayFrame frame = (Http2GoAwayFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(9, frame.getLength());
+        assertEquals(7, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getLastStreamID());
+        assertEquals(0x00010203, frame.getErrorCode());
+        assertArrayEquals(new byte[] {0x01}, frame.getData());
+    }
+    
+    @Test
+    public void headersNoPaddingNoPriority() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(1, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    @Test
+    public void headersPaddingPriority() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_PADDING_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(23, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x28, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(10,  frame.getWeight());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void headersPaddingNoPriority() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.HEADERS_PADDING_NO_PRIORITY_BUFFER);
+        Http2HeadersFrame frame = (Http2HeadersFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(18, frame.getLength());
+        assertEquals(1, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void ping() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_STANDARD_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(8, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, frame.getData());
+    }
+    
+    @Test
+    public void pingExtraData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_EXTRA_DATA_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(9, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, frame.getData());
+    }
+    
+    @Test
+    public void pingNotEnoughData() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PING_NO_ENOUGH_DATA_BUFFER);
+        Http2PingFrame frame = (Http2PingFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(1, frame.getLength());
+        assertEquals(6, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertArrayEquals(new byte[] {0x00}, frame.getData());
+    }
+    
+    @Test
+    public void priorityNoExclusive() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_BUFFER);
+        Http2PriorityFrame frame = (Http2PriorityFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertFalse(frame.getExclusiveMode());
+        assertEquals(2, frame.getWeight());
+    }
+  
+    @Test
+    public void priorityExclusive() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PRIORITY_EXCLUSIVE_MODE_BUFFER);
+        Http2PriorityFrame frame = (Http2PriorityFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(2, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getStreamDependencyID());
+        assertTrue(frame.getExclusiveMode());
+        assertEquals(2, frame.getWeight());
+    }
+    
+    @Test
+    public void pushPromiseNoPadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PUSH_PROMISE_NO_PADDING_BUFFER);
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(5, frame.getLength());
+        assertEquals(5, frame.getType());
+        assertEquals(0, frame.getFlags());
+        assertEquals(1, frame.getStreamID());
+        assertEquals(256, frame.getPromisedStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+    }
+    
+    @Test
+    public void pushPromisePadding() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.PUSH_PROMISE_PADDING_BUFFER);
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) decoder.decode(buffer, context);
+        assertEquals(22, frame.getLength());
+        assertEquals(5, frame.getType());
+        assertEquals(0x08, frame.getFlags());
+        assertEquals(3, frame.getStreamID());
+        assertEquals(20, frame.getPromisedStreamID());
+        assertEquals(1, frame.getHeaderBlockFragment().length);
+        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
+        assertEquals(16,  frame.getPadding().length);
+        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
+    }
+    
+    @Test
+    public void rstStreamNoExtraPayload() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+    
+    @Test
+    public void rstStreamHighestValueNoExtraPayload() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(4, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+    
+    @Test
+    public void rstStreamExtraPayload() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_EXTRA_PAYLOAD_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(256, frame.getErrorCode());
+    }
+    
+    @Test
+    public void rstStreamHighestValueExtraPayload() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.RST_STREAM_EXTRA_PAYLOAD_HIGHEST_BUFFER);
+        Http2RstStreamFrame frame = (Http2RstStreamFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(3, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0x00FFFFFFFFL, frame.getErrorCode());
+    }
+    
+    @Test
+    public void settings() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_DEFAULT_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+    
+    @Test
+    public void settingsHighestID() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_HIGHEST_ID_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(0x00FFFF, setting.getID());
+        assertEquals(0x01020304L, setting.getValue());
+    }
+    
+    @Test
+    public void settingsHighestValue() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.SETTINGS_HIGHEST_VALUE_BUFFER);
+        Http2SettingsFrame frame = (Http2SettingsFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(6, frame.getLength());
+        assertEquals(4, frame.getType());
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(1, frame.getSettings().size());
+        Http2Setting setting = frame.getSettings().iterator().next();
+        assertEquals(1, setting.getID());
+        assertEquals(0xFFFFFFFFL, setting.getValue());
+    }
+    
+    @Test
+    public void unknownFrame() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.UNKNOWN_PAYLOAD_BUFFER);
+        Http2UnknownFrame frame = (Http2UnknownFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(2, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(2, frame.getPayload().length);
+        assertArrayEquals(new byte[] {0x0E,  0x18}, frame.getPayload());
+    }
+    
+    @Test
+    public void unknownFrameNoPayload() {
+        ByteBuffer buffer = ByteBuffer.wrap(TestMessages.UNKNOWN_NO_PAYLOAD_BUFFER);
+        Http2UnknownFrame frame = (Http2UnknownFrame) decoder.decode(buffer, context);
+        assertNotNull(frame);
+        assertEquals(0, frame.getLength());
+        assertEquals(255, frame.getType() & 0x00FF);
+        assertEquals(0x00, frame.getFlags());
+        assertEquals(32, frame.getStreamID());
+        assertEquals(0, frame.getPayload().length);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/8ca3d89d/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolEncoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolEncoderTest.java b/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolEncoderTest.java
new file mode 100644
index 0000000..ecea462
--- /dev/null
+++ b/http2/src/test/java/org/apache/mina/http2/codec/Http2ProtocolEncoderTest.java
@@ -0,0 +1,200 @@
+/*
+ *  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.http2.codec;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.apache.mina.http2.Http2Test;
+import org.apache.mina.http2.TestMessages;
+import org.apache.mina.http2.api.Http2Frame;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+
+public class Http2ProtocolEncoderTest extends Http2Test {
+
+    private Http2ProtocolEncoder encoder = new Http2ProtocolEncoder();
+    
+    @Test
+    public void continuationNoHeaderBlock() {
+        Http2Frame frame = TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_FRAME;
+        assertArrayEquals(TestMessages.CONTINUATION_NO_HEADER_FRAGMENT_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void continuationHeaderBlock() {
+        Http2Frame frame = TestMessages.CONTINUATION_HEADER_FRAGMENT_FRAME;
+        assertArrayEquals(TestMessages.CONTINUATION_HEADER_FRAGMENT_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+
+    @Test
+    public void dataNoPayloadNoPadding() {
+        Http2Frame frame = TestMessages.DATA_NO_PAYLOAD_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_NO_PAYLOAD_NO_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void dataPayloadNoPadding() {
+        Http2Frame frame = TestMessages.DATA_PAYLOAD_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_PAYLOAD_NO_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void dataNoPayloadPadding() {
+        Http2Frame frame = TestMessages.DATA_NO_PAYLOAD_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_NO_PAYLOAD_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void dataPayloadPadding() {
+        Http2Frame frame = TestMessages.DATA_PAYLOAD_PADDING_FRAME;
+        assertArrayEquals(TestMessages.DATA_PAYLOAD_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void goAwayNoAdditionalData() {
+        Http2Frame frame = TestMessages.GOAWAY_NO_DATA_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void goAwayHighestLastStreamIDNoAdditionalData() {
+        Http2Frame frame = TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_HIGHEST_STREAMID_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void goAwayHighestErrorCodeNoAdditionalData() {
+        Http2Frame frame = TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_NO_DATA_HIGHEST_ERROR_CODE_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void goAwayAdditionalData() {
+        Http2Frame frame = TestMessages.GOAWAY_DATA_FRAME;
+        assertArrayEquals(TestMessages.GOAWAY_DATA_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void headersNoPaddingNoPriority() {
+        Http2Frame frame = TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_FRAME;
+        assertArrayEquals(TestMessages.HEADERS_NO_PADDING_NO_PRIORITY_BUFFER,  toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void headersPaddingPriority() {
+        Http2Frame frame = TestMessages.HEADERS_PADDING_PRIORITY_FRAME;
+        assertArrayEquals(TestMessages.HEADERS_PADDING_PRIORITY_BUFFER,  toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void headersPaddingNoPriority() {
+        Http2Frame frame = TestMessages.HEADERS_PADDING_NO_PRIORITY_FRAME;
+        assertArrayEquals(TestMessages.HEADERS_PADDING_NO_PRIORITY_BUFFER,  toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void ping() {
+        Http2Frame frame = TestMessages.PING_STANDARD_FRAME;
+        assertArrayEquals(TestMessages.PING_STANDARD_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void pingExtraData() {
+        Http2Frame frame = TestMessages.PING_EXTRA_DATA_FRAME;
+        assertArrayEquals(TestMessages.PING_EXTRA_DATA_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void pingNotEnoughData() {
+        Http2Frame frame = TestMessages.PING_NO_ENOUGH_DATA_FRAME;
+        assertArrayEquals(TestMessages.PING_NO_ENOUGH_DATA_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void priorityNoExclusive() {
+        Http2Frame frame = TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_FRAME;
+        assertArrayEquals(TestMessages.PRIORITY_NO_EXCLUSIVE_MODE_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+  
+    @Test
+    public void priorityExclusive() {
+        Http2Frame frame = TestMessages.PRIORITY_EXCLUSIVE_MODE_FRAME;
+        assertArrayEquals(TestMessages.PRIORITY_EXCLUSIVE_MODE_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void pushPromiseNoPadding() {
+        Http2Frame frame = TestMessages.PUSH_PROMISE_NO_PADDING_FRAME;
+        assertArrayEquals(TestMessages.PUSH_PROMISE_NO_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void pushPromisePadding() {
+        Http2Frame frame = TestMessages.PUSH_PROMISE_PADDING_FRAME;
+        assertArrayEquals(TestMessages.PUSH_PROMISE_PADDING_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void rstStreamNoExtraPayload() {
+        Http2Frame frame = TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.RST_STREAM_NO_EXTRA_PAYLOAD_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void rstStreamHighestValueNoExtraPayload() {
+        Http2Frame frame = TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.RST_STREAM_HIGHEST_VALUE_NO_EXTRA_PAYLOAD_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void settings() {
+        Http2Frame frame = TestMessages.SETTINGS_DEFAULT_FRAME;
+        assertArrayEquals(TestMessages.SETTINGS_DEFAULT_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void settingsHighestID() {
+        Http2Frame frame = TestMessages.SETTINGS_HIGHEST_ID_FRAME;
+        assertArrayEquals(TestMessages.SETTINGS_HIGHEST_ID_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void settingsHighestValue() {
+        Http2Frame frame = TestMessages.SETTINGS_HIGHEST_VALUE_FRAME;
+        assertArrayEquals(TestMessages.SETTINGS_HIGHEST_VALUE_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void unknownFrame() {
+        Http2Frame frame = TestMessages.UNKNOWN_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.UNKNOWN_PAYLOAD_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+    
+    @Test
+    public void unknownFrameNoPayload() {
+        Http2Frame frame = TestMessages.UNKNOWN_NO_PAYLOAD_FRAME;
+        assertArrayEquals(TestMessages.UNKNOWN_NO_PAYLOAD_BUFFER, toByteArray(encoder.encode(frame, null)));
+    }
+}


[3/8] mina git commit: Multiple HTTP2 PDUs

Posted by je...@apache.org.
Multiple HTTP2 PDUs


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/27938fb1
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/27938fb1
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/27938fb1

Branch: refs/heads/trunk
Commit: 27938fb1e54c5e93ea14da20da03856ee395681e
Parents: 9979693
Author: Jeff MAURY <je...@apache.org>
Authored: Mon Mar 23 22:43:42 2015 +0100
Committer: Jeff MAURY <je...@apache.org>
Committed: Mon Mar 23 22:43:42 2015 +0100

----------------------------------------------------------------------
 .../apache/mina/http2/api/Http2Constants.java   |   2 +
 .../mina/http2/api/Http2ContinuationFrame.java  |  68 +++++++++
 .../apache/mina/http2/api/Http2DataFrame.java   |  87 +++++++++++
 .../org/apache/mina/http2/api/Http2Frame.java   | 120 +++++++--------
 .../api/Http2FrameHeadePartialDecoder.java      | 106 ++++++++++++++
 .../apache/mina/http2/api/Http2GoAwayFrame.java | 104 +++++++++++++
 .../mina/http2/api/Http2HeadersFrame.java       | 145 +++++++++++++++++++
 .../apache/mina/http2/api/Http2PingFrame.java   |  66 +++++++++
 .../mina/http2/api/Http2PriorityFrame.java      | 105 ++++++++++++++
 .../mina/http2/api/Http2PushPromiseFrame.java   | 107 ++++++++++++++
 .../mina/http2/api/Http2RstStreamFrame.java     |  66 +++++++++
 .../mina/http2/api/Http2SettingsFrame.java      |  68 +++++++++
 .../mina/http2/api/Http2UnknownFrame.java       |  66 +++++++++
 .../mina/http2/api/Http2WindowUpdateFrame.java  |  66 +++++++++
 .../apache/mina/http2/impl/Http2Connection.java |  77 +++++++++-
 .../impl/Http2ContinuationFrameDecoder.java     |  51 +++++++
 .../mina/http2/impl/Http2DataFrameDecoder.java  |  96 ++++++++++++
 .../mina/http2/impl/Http2FrameDecoder.java      |  82 +++--------
 .../http2/impl/Http2GoAwayFrameDecoder.java     |  82 +++++++++++
 .../http2/impl/Http2HeadersFrameDecoder.java    | 117 +++++++++++++++
 .../mina/http2/impl/Http2PingFrameDecoder.java  |  70 +++++++++
 .../http2/impl/Http2PriorityFrameDecoder.java   |  83 +++++++++++
 .../impl/Http2PushPromiseFrameDecoder.java      | 101 +++++++++++++
 .../http2/impl/Http2RstStreamFrameDecoder.java  |  75 ++++++++++
 .../http2/impl/Http2SettingsFrameDecoder.java   |  64 ++++++++
 .../http2/impl/Http2UnknownFrameDecoder.java    |  52 +++++++
 .../impl/Http2WindowUpdateFrameDecoder.java     |  73 ++++++++++
 .../api/Htp2PushPromiseFrameDecoderTest.java    |  45 ++----
 .../api/Http2FrameHeaderPartialDecoderTest.java |   2 -
 29 files changed, 2089 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
index ba8a8fe..3bf58f6 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Constants.java
@@ -190,4 +190,6 @@ public final class Http2Constants {
     
     public static final Charset US_ASCII_CHARSET = Charset.forName("US-ASCII");
     
+    public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.java
new file mode 100644
index 0000000..0138d17
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2ContinuationFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2ContinuationFrame extends Http2Frame {
+
+    private final byte[] headerBlockFragment;
+    
+    
+    public byte[] getHeaderBlockFragment() {
+        return headerBlockFragment;
+    }
+
+    protected <T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> Http2ContinuationFrame(AbstractHttp2ContinuationFrameBuilder<T, V> builder) {
+        super(builder);
+        this.headerBlockFragment = builder.getHeaderBlockFragment();
+    }
+
+    
+    public static abstract class AbstractHttp2ContinuationFrameBuilder<T extends AbstractHttp2ContinuationFrameBuilder<T,V>, V extends Http2ContinuationFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] headerBlockFragment = new byte[0];
+        
+        @SuppressWarnings("unchecked")
+        public T headerBlockFragment(byte[] headerBlockFragment) {
+            this.headerBlockFragment = headerBlockFragment;
+            return (T) this;
+        }
+        
+        public byte[] getHeaderBlockFragment() {
+            return headerBlockFragment;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2ContinuationFrameBuilder<Builder, Http2ContinuationFrame> {
+
+        @Override
+        public Http2ContinuationFrame build() {
+            return new Http2ContinuationFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
new file mode 100644
index 0000000..2a4802d
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2DataFrame.java
@@ -0,0 +1,87 @@
+/*
+ *  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.http2.api;
+
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2DataFrame extends Http2Frame {
+    private final byte[] data;
+    
+    private final byte[] padding;
+    
+    public byte[] getData() {
+        return data;
+    }
+    
+    public byte[] getPadding() {
+        return padding;
+    }
+    
+    protected <T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> Http2DataFrame(AbstractHttp2DataFrameBuilder<T, V> builder) {
+        super(builder);
+        this.data = builder.getData();
+        this.padding = builder.getPadding();
+    }
+
+    
+    public static abstract class AbstractHttp2DataFrameBuilder<T extends AbstractHttp2DataFrameBuilder<T,V>, V extends Http2Frame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] data = EMPTY_BYTE_ARRAY;
+        
+        private byte[] padding = EMPTY_BYTE_ARRAY;
+
+        @SuppressWarnings("unchecked")
+        public T data(byte[] data) {
+            this.data = data;
+            return (T) this;
+        }
+        
+        public byte[] getData() {
+            return data;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T padding(byte[] padding) {
+            this.padding = padding;
+            return (T) this;
+        }
+        
+        public byte[] getPadding() {
+            return padding;
+        }
+}
+    
+    public static class Builder extends AbstractHttp2DataFrameBuilder<Builder, Http2Frame> {
+
+        @Override
+        public Http2Frame build() {
+            return new Http2DataFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
index b6a3ed2..356c2b8 100644
--- a/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2Frame.java
@@ -20,89 +20,93 @@
 package org.apache.mina.http2.api;
 
 /**
- * An SPY frame
+ * An SPY data frame
  * 
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  * 
  */
-public class Http2Frame {
-    private int length;
+public abstract class Http2Frame {
+
+    private final int length;
     
-    private short type;
+    private final short type;
     
-    private short flags;
+    private final short flags;
     
-    private int streamID;
+    private final int streamID;
     
-    public byte[] payload;
-
-    /**
-     * @return the length
-     */
     public int getLength() {
         return length;
     }
 
-    /**
-     * @param length the length to set
-     */
-    public void setLength(int length) {
-        this.length = length;
-    }
-
-    /**
-     * @return the type
-     */
     public short getType() {
         return type;
     }
-
-    /**
-     * @param type the type to set
-     */
-    public void setType(short type) {
-        this.type = type;
-    }
-
-    /**
-     * @return the flags
-     */
+    
     public short getFlags() {
         return flags;
     }
 
-    /**
-     * @param flags the flags to set
-     */
-    public void setFlags(short flags) {
-        this.flags = flags;
-    }
-
-    /**
-     * @return the streamID
-     */
     public int getStreamID() {
         return streamID;
     }
 
-    /**
-     * @param streamID the streamID to set
-     */
-    public void setStreamID(int streamID) {
-        this.streamID = streamID;
+    protected <T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame> Http2Frame(AbstractHttp2FrameBuilder<T, V> builder) {
+        this.length = builder.getLength();
+        this.type = builder.getType();
+        this.flags = builder.getFlags();
+        this.streamID = builder.getStreamID();
     }
 
-    /**
-     * @return the payload
-     */
-    public byte[] getPayload() {
-        return payload;
-    }
+    public static abstract class AbstractHttp2FrameBuilder<T extends AbstractHttp2FrameBuilder<T,V>, V extends Http2Frame>  {
+        private int length;
+        
+        private short type;
+        
+        private short flags;
+        
+        private int streamID;
+        
+        @SuppressWarnings("unchecked")
+        public T length(int length) {
+            this.length = length;
+            return (T) this;
+        }
+        
+        public int getLength() {
+            return length;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T type(short type) {
+            this.type = type;
+            return (T) this;
+        }
+        
+        public short getType() {
+            return type;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T flags(short flags) {
+            this.flags = flags;
+            return (T) this;
+        }
+        
+        public short getFlags() {
+            return flags;
+        }
 
-    /**
-     * @param payload the payload to set
-     */
-    public void setPayload(byte[] payload) {
-        this.payload = payload;
+        @SuppressWarnings("unchecked")
+        public T streamID(int streamID) {
+            this.streamID = streamID;
+            return (T) this;
+        }
+        
+        public int getStreamID() {
+            return streamID;
+        }
+        
+        public abstract V build();
     }
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java b/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
new file mode 100644
index 0000000..059f193
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2FrameHeadePartialDecoder.java
@@ -0,0 +1,106 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.api;
+
+import java.nio.ByteBuffer;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2FrameHeadePartialDecoder implements PartialDecoder<Http2FrameHeadePartialDecoder.Http2FrameHeader> {
+    public static class Http2FrameHeader {
+        private int length;
+        private short type;
+        private byte flags;
+        private int streamID;
+
+        public int getLength() {
+            return length;
+        }
+       
+        public void setLength(int length) {
+            this.length = length;
+        }
+        
+        public short getType() {
+            return type;
+        }
+        
+        public void setType(short type) {
+            this.type = type;
+        }
+        
+        public byte getFlags() {
+            return flags;
+        }
+        
+        public void setFlags(byte flags) {
+            this.flags = flags;
+        }
+        
+        public int getStreamID() {
+            return streamID;
+        }
+        
+        public void setStreamID(int streamID) {
+            this.streamID = streamID;
+        }
+    }
+    
+    private static enum State {
+        LENGTH,
+        TYPE_FLAGS,
+        STREAMID,
+        END
+    }
+    
+    private State state;
+    private PartialDecoder<?> decoder;
+    private Http2FrameHeader value;
+    
+    public Http2FrameHeadePartialDecoder() {
+        reset();
+    }
+    
+    public boolean consume(ByteBuffer buffer) {
+        while (buffer.hasRemaining() && state != State.END) {
+            if (decoder.consume(buffer)) {
+                switch (state) {
+                case LENGTH:
+                    value.setLength(((IntPartialDecoder)decoder).getValue().intValue());
+                    decoder = new BytePartialDecoder(2);
+                    state = State.TYPE_FLAGS;
+                    break;
+                case TYPE_FLAGS:
+                    value.setType(((BytePartialDecoder)decoder).getValue()[0]);
+                    value.setFlags(((BytePartialDecoder)decoder).getValue()[1]);
+                    decoder = new IntPartialDecoder(4);
+                    state = State.STREAMID;
+                    break;
+                case STREAMID:
+                    value.setStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    state = State.END;
+                    break;
+                }
+            }
+        }
+        return state == State.END;
+    }
+    
+    public Http2FrameHeader getValue() {
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+        state = State.LENGTH;
+        decoder = new IntPartialDecoder(3);
+        value = new Http2FrameHeader();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
new file mode 100644
index 0000000..fbc5ea1
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2GoAwayFrame.java
@@ -0,0 +1,104 @@
+/*
+ *  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.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2GoAwayFrame extends Http2Frame {
+    private final int lastStreamID;
+    
+    private final int errorCode;
+
+    private byte[] data;
+    
+    public int getLastStreamID() {
+        return lastStreamID;
+    }
+    
+    public int getErrorCode() {
+        return errorCode;
+    }
+
+    public byte[] getData() {
+        return data;
+    }
+    
+    protected <T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> Http2GoAwayFrame(AbstractHttp2GoAwayFrameBuilder<T, V> builder) {
+        super(builder);
+        this.lastStreamID = builder.getLastStreamID();
+        this.errorCode = builder.getErrorCode();
+        this.data = builder.getData();
+    }
+
+    
+    public static abstract class AbstractHttp2GoAwayFrameBuilder<T extends AbstractHttp2GoAwayFrameBuilder<T,V>, V extends Http2GoAwayFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private int lastStreamID;
+        
+        private int errorCode;
+        
+        private byte[] data;
+        
+        @SuppressWarnings("unchecked")
+        public T lastStreamID(int lastStreamID) {
+            this.lastStreamID = lastStreamID;
+            return (T) this;
+        }
+        
+        public int getLastStreamID() {
+            return lastStreamID;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T errorCode(int errorCode) {
+            this.errorCode = errorCode;
+            return (T) this;
+        }
+        
+        public int getErrorCode() {
+            return errorCode;
+        }
+        
+        @SuppressWarnings("unchecked")
+        public T data(byte[] data) {
+            this.data = data;
+            return (T) this;
+        }
+        
+        public byte[] getData() {
+            return data;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2GoAwayFrameBuilder<Builder, Http2GoAwayFrame> {
+
+        @Override
+        public Http2GoAwayFrame build() {
+            return new Http2GoAwayFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
new file mode 100644
index 0000000..aadb1bc
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2HeadersFrame.java
@@ -0,0 +1,145 @@
+/*
+ *  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.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2HeadersFrame extends Http2Frame {
+
+    private final byte[] padding;
+    
+    private final int streamDependencyID;
+    
+    private final boolean exclusiveMode;
+    
+    private final byte weight;
+    
+    private final byte[] headerBlockFragment;
+    
+    
+    public byte[] getPadding() {
+        return padding;
+    }
+
+    public int getStreamDependencyID() {
+        return streamDependencyID;
+    }
+    
+    public boolean getExclusiveMode() {
+        return exclusiveMode;
+    }
+
+    public byte getWeight() {
+        return weight;
+    }
+
+    public byte[] getHeaderBlockFragment() {
+        return headerBlockFragment;
+    }
+
+    protected <T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> Http2HeadersFrame(AbstractHttp2HeadersFrameBuilder<T, V> builder) {
+        super(builder);
+        this.padding = builder.getPadding();
+        this.streamDependencyID = builder.getStreamDependencyID();
+        this.exclusiveMode = builder.getExclusiveMode();
+        this.weight = builder.getWeight();
+        this.headerBlockFragment = builder.getHeaderBlockFragment();
+    }
+
+    
+    public static abstract class AbstractHttp2HeadersFrameBuilder<T extends AbstractHttp2HeadersFrameBuilder<T,V>, V extends Http2HeadersFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] padding;
+        
+        private int streamDependencyID;
+        
+        private byte weight;
+        
+        private byte[] headerBlockFragment;
+        
+        private boolean exclusiveMode;
+        
+        @SuppressWarnings("unchecked")
+        public T padding(byte[] padding) {
+            this.padding = padding;
+            return (T) this;
+        }
+        
+        public byte[] getPadding() {
+            return padding;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T streamDependencyID(int streamDependencyID) {
+            this.streamDependencyID = streamDependencyID;
+            return (T) this;
+        }
+        
+        public int getStreamDependencyID() {
+            return streamDependencyID;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T exclusiveMode(boolean exclusiveMode) {
+            this.exclusiveMode = exclusiveMode;
+            return (T) this;
+        }
+        
+        public boolean getExclusiveMode() {
+            return exclusiveMode;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T weight(byte weight) {
+            this.weight = weight;
+            return (T) this;
+        }
+        
+        public byte getWeight() {
+            return weight;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T headerBlockFragment(byte[] headerBlockFragment) {
+            this.headerBlockFragment = headerBlockFragment;
+            return (T) this;
+        }
+        
+        public byte[] getHeaderBlockFragment() {
+            return headerBlockFragment;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2HeadersFrameBuilder<Builder, Http2HeadersFrame> {
+
+        @Override
+        public Http2HeadersFrame build() {
+            return new Http2HeadersFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.java
new file mode 100644
index 0000000..c1df709
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PingFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2PingFrame extends Http2Frame {
+    private final byte[] data;
+    
+    public byte[] getData() {
+        return data;
+    }
+
+    protected <T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> Http2PingFrame(AbstractHttp2PingFrameBuilder<T, V> builder) {
+        super(builder);
+        this.data = builder.getData();
+    }
+
+    
+    public static abstract class AbstractHttp2PingFrameBuilder<T extends AbstractHttp2PingFrameBuilder<T,V>, V extends Http2PingFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] data;
+        
+        @SuppressWarnings("unchecked")
+        public T data(byte[] data) {
+            this.data = data;
+            return (T) this;
+        }
+        
+        public byte[] getData() {
+            return data;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2PingFrameBuilder<Builder, Http2PingFrame> {
+
+        @Override
+        public Http2PingFrame build() {
+            return new Http2PingFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.java
new file mode 100644
index 0000000..5478c69
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PriorityFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2PriorityFrame extends Http2Frame {
+    private final int streamDependencyID;
+    
+    private boolean exclusiveMode;
+    
+    private final short weight;
+    
+    public int getStreamDependencyID() {
+        return streamDependencyID;
+    }
+    
+    public boolean getExclusiveMode() {
+        return exclusiveMode;
+    }
+
+    public short getWeight() {
+        return weight;
+    }
+
+    protected <T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> Http2PriorityFrame(AbstractHttp2PriorityFrameBuilder<T, V> builder) {
+        super(builder);
+        this.streamDependencyID = builder.getStreamDependencyID();
+        this.exclusiveMode = builder.exclusiveMode;
+        this.weight = builder.getWeight();
+    }
+
+    
+    public static abstract class AbstractHttp2PriorityFrameBuilder<T extends AbstractHttp2PriorityFrameBuilder<T,V>, V extends Http2PriorityFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private int streamDependencyID;
+        
+        private boolean exclusiveMode;
+        
+        private short weight;
+        
+        @SuppressWarnings("unchecked")
+        public T streamDependencyID(int streamDependencyID) {
+            this.streamDependencyID = streamDependencyID;
+            return (T) this;
+        }
+        
+        public int getStreamDependencyID() {
+            return streamDependencyID;
+        }
+        
+        @SuppressWarnings("unchecked")
+        public T exclusiveMode(boolean exclusiveMode) {
+            this.exclusiveMode = exclusiveMode;
+            return (T) this;
+        }
+        
+        public boolean getExclusiveMode() {
+            return exclusiveMode;
+        }
+
+
+        @SuppressWarnings("unchecked")
+        public T weight(short weight) {
+            this.weight = weight;
+            return (T) this;
+        }
+        
+        public short getWeight() {
+            return weight;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2PriorityFrameBuilder<Builder, Http2PriorityFrame> {
+
+        @Override
+        public Http2PriorityFrame build() {
+            return new Http2PriorityFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
new file mode 100644
index 0000000..a2ab2c7
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2PushPromiseFrame.java
@@ -0,0 +1,107 @@
+/*
+ *  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.http2.api;
+
+import static org.apache.mina.http2.api.Http2Constants.EMPTY_BYTE_ARRAY;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2PushPromiseFrame extends Http2Frame {
+
+    private final byte[] padding;
+    
+    private final int promisedStreamID;
+    
+    private final byte[] headerBlockFragment;
+    
+    
+    public byte[] getPadding() {
+        return padding;
+    }
+
+    public int getPromisedStreamID() {
+        return promisedStreamID;
+    }
+
+    public byte[] getHeaderBlockFragment() {
+        return headerBlockFragment;
+    }
+
+    protected <T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> Http2PushPromiseFrame(AbstractHttp2PushPromiseFrameBuilder<T, V> builder) {
+        super(builder);
+        this.padding = builder.getPadding();
+        this.promisedStreamID = builder.getPromisedStreamID();
+        this.headerBlockFragment = builder.getHeaderBlockFragment();
+    }
+
+    public static abstract class AbstractHttp2PushPromiseFrameBuilder<T extends AbstractHttp2PushPromiseFrameBuilder<T,V>, V extends Http2PushPromiseFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] padding = EMPTY_BYTE_ARRAY;
+        
+        private int promisedStreamID;
+        
+        private byte[] headerBlockFragment = EMPTY_BYTE_ARRAY;
+        
+        @SuppressWarnings("unchecked")
+        public T padding(byte[] padding) {
+            this.padding = padding;
+            return (T) this;
+        }
+        
+        public byte[] getPadding() {
+            return padding;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T promisedStreamID(int promisedStreamID) {
+            this.promisedStreamID = promisedStreamID;
+            return (T) this;
+        }
+        
+        public int getPromisedStreamID() {
+            return promisedStreamID;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T headerBlockFragment(byte[] headerBlockFragment) {
+            this.headerBlockFragment = headerBlockFragment;
+            return (T) this;
+        }
+        
+        public byte[] getHeaderBlockFragment() {
+            return headerBlockFragment;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2PushPromiseFrameBuilder<Builder, Http2PushPromiseFrame> {
+
+        @Override
+        public Http2PushPromiseFrame build() {
+            return new Http2PushPromiseFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.java
new file mode 100644
index 0000000..1536594
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2RstStreamFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2RstStreamFrame extends Http2Frame {
+    private final long errorCode;
+    
+    public long getErrorCode() {
+        return errorCode;
+    }
+
+    protected <T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> Http2RstStreamFrame(AbstractHttp2RstStreamFrameBuilder<T, V> builder) {
+        super(builder);
+        this.errorCode = builder.getErrorCode();
+    }
+
+    
+    public static abstract class AbstractHttp2RstStreamFrameBuilder<T extends AbstractHttp2RstStreamFrameBuilder<T,V>, V extends Http2RstStreamFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private long errorCode;
+        
+        @SuppressWarnings("unchecked")
+        public T errorCode(long errorCode) {
+            this.errorCode = errorCode;
+            return (T) this;
+        }
+        
+        public long getErrorCode() {
+            return errorCode;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2RstStreamFrameBuilder<Builder, Http2RstStreamFrame> {
+
+        @Override
+        public Http2RstStreamFrame build() {
+            return new Http2RstStreamFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.java
new file mode 100644
index 0000000..66c44ba
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2SettingsFrame.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.mina.http2.api;
+
+import java.util.Collection;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2SettingsFrame extends Http2Frame {
+    private final Collection<Http2Setting> settings;
+    
+    public Collection<Http2Setting> getSettings() {
+        return settings;
+    }
+
+    protected <T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> Http2SettingsFrame(AbstractHttp2SettingsFrameBuilder<T, V> builder) {
+        super(builder);
+        this.settings = builder.getSettings();
+    }
+
+    
+    public static abstract class AbstractHttp2SettingsFrameBuilder<T extends AbstractHttp2SettingsFrameBuilder<T,V>, V extends Http2SettingsFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private Collection<Http2Setting> settings;
+        
+        @SuppressWarnings("unchecked")
+        public T settings(Collection<Http2Setting> settings) {
+            this.settings = settings;
+            return (T) this;
+        }
+        
+        public Collection<Http2Setting> getSettings() {
+            return settings;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2SettingsFrameBuilder<Builder, Http2SettingsFrame> {
+
+        @Override
+        public Http2SettingsFrame build() {
+            return new Http2SettingsFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.java
new file mode 100644
index 0000000..1cdcaef
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2UnknownFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2UnknownFrame extends Http2Frame {
+    private final byte[] payload;
+    
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    protected <T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> Http2UnknownFrame(AbstractHttp2UnknownFrameBuilder<T, V> builder) {
+        super(builder);
+        this.payload = builder.getPayload();
+    }
+
+    
+    public static abstract class AbstractHttp2UnknownFrameBuilder<T extends AbstractHttp2UnknownFrameBuilder<T,V>, V extends Http2UnknownFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private byte[] payload = new byte[0];
+        
+        @SuppressWarnings("unchecked")
+        public T payload(byte[] payload) {
+            this.payload = payload;
+            return (T) this;
+        }
+        
+        public byte[] getPayload() {
+            return payload;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2UnknownFrameBuilder<Builder, Http2UnknownFrame> {
+
+        @Override
+        public Http2UnknownFrame build() {
+            return new Http2UnknownFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.java
new file mode 100644
index 0000000..f552aaf
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/api/Http2WindowUpdateFrame.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.mina.http2.api;
+
+/**
+ * An SPY data frame
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public class Http2WindowUpdateFrame extends Http2Frame {
+    private final int windowUpdateIncrement;
+    
+    public int getWindowUpdateIncrement() {
+        return windowUpdateIncrement;
+    }
+
+    protected <T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> Http2WindowUpdateFrame(AbstractHttp2WindowUpdateFrameBuilder<T, V> builder) {
+        super(builder);
+        this.windowUpdateIncrement = builder.getWindowUpdateIncrement();
+    }
+
+    
+    public static abstract class AbstractHttp2WindowUpdateFrameBuilder<T extends AbstractHttp2WindowUpdateFrameBuilder<T,V>, V extends Http2WindowUpdateFrame> extends AbstractHttp2FrameBuilder<T,V> {
+        private int windowUpdateIncrement;
+        
+        @SuppressWarnings("unchecked")
+        public T windowUpdateIncrement(int windowUpdateIncrement) {
+            this.windowUpdateIncrement = windowUpdateIncrement;
+            return (T) this;
+        }
+        
+        public int getWindowUpdateIncrement() {
+            return windowUpdateIncrement;
+        }
+    }
+    
+    public static class Builder extends AbstractHttp2WindowUpdateFrameBuilder<Builder, Http2WindowUpdateFrame> {
+
+        @Override
+        public Http2WindowUpdateFrame build() {
+            return new Http2WindowUpdateFrame(this);
+        }
+        
+        public static Builder builder() {
+            return new Builder();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
index 3019b20..9ec5b4f 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2Connection.java
@@ -3,10 +3,29 @@ package org.apache.mina.http2.impl;
 import java.nio.ByteBuffer;
 
 import org.apache.mina.http2.api.Http2Frame;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_DATA;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_HEADERS;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_RST_STREAM;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_SETTINGS;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PUSH_PROMISE;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_PING;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_GOAWAY;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_WINDOW_UPDATE;
+import static org.apache.mina.http2.api.Http2Constants.FRAME_TYPE_CONTINUATION;
 
 public class Http2Connection {
 
-    private final Http2FrameDecoder decoder = new Http2FrameDecoder();
+    private static enum DecoderState {
+        HEADER,
+        FRAME
+    }
+    
+    private final Http2FrameHeadePartialDecoder headerDecoder = new Http2FrameHeadePartialDecoder();
+    private Http2FrameDecoder frameDecoder;
+    private DecoderState decoderState = DecoderState.HEADER;
 
     /**
      * Decode the incoming message and if all frame data has been received,
@@ -17,9 +36,59 @@ public class Http2Connection {
      */
     public Http2Frame decode(ByteBuffer input) {
         Http2Frame frame = null;
-        if (decoder.consume(input)) {
-            frame = decoder.getValue();
-            decoder.reset();
+        switch (decoderState) {
+        case HEADER:
+            if (headerDecoder.consume(input)) {
+                Http2FrameHeader header = headerDecoder.getValue();
+                headerDecoder.reset();
+                decoderState = DecoderState.FRAME;
+                switch (header.getType()) {
+                case FRAME_TYPE_DATA:
+                    frameDecoder = new Http2DataFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_HEADERS:
+                    frameDecoder = new Http2HeadersFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_PRIORITY:
+                    frameDecoder = new Http2PriorityFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_RST_STREAM:
+                    frameDecoder = new Http2RstStreamFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_SETTINGS:
+                    frameDecoder =new Http2SettingsFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_PUSH_PROMISE:
+                    frameDecoder = new Http2PushPromiseFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_PING:
+                    frameDecoder = new Http2PingFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_GOAWAY:
+                    frameDecoder = new Http2GoAwayFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_WINDOW_UPDATE:
+                    frameDecoder = new Http2WindowUpdateFrameDecoder(header);
+                    break;
+                case FRAME_TYPE_CONTINUATION:
+                    frameDecoder = new Http2ContinuationFrameDecoder(header);
+                    break;
+                default:
+                    frameDecoder = new Http2UnknownFrameDecoder(header);
+                    break;
+                }
+                if (frameDecoder.consume(input)) {
+                    frame = frameDecoder.getValue();
+                    decoderState = DecoderState.HEADER;
+                }
+            }
+            break;
+        case FRAME:
+            if (frameDecoder.consume(input)) {
+                frame = frameDecoder.getValue();
+                decoderState = DecoderState.HEADER;
+            }
+            break;
         }
         return frame;
     }

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
new file mode 100644
index 0000000..39f6706
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2ContinuationFrameDecoder.java
@@ -0,0 +1,51 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2ContinuationFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2ContinuationFrameDecoder extends Http2FrameDecoder {
+
+    private BytePartialDecoder decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2ContinuationFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        initBuilder(builder);
+        if (header.getLength() > 0) {
+            decoder = new BytePartialDecoder(header.getLength());
+        } else {
+            setValue(builder.build());
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        if ((decoder != null) && decoder.consume(buffer)) {
+            builder.headerBlockFragment(decoder.getValue());
+            setValue(builder.build());
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
new file mode 100644
index 0000000..7a07812
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2DataFrameDecoder.java
@@ -0,0 +1,96 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2DataFrame.Builder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2DataFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        PAD_LENGTH,
+        DATA,
+        PADDING
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private int padLength;
+    
+    private Builder builder = new Builder();
+    
+    public Http2DataFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        initBuilder(builder);
+        if (isFlagSet(FLAGS_PADDING)) {
+            state = State.PAD_LENGTH;
+        } else if (header.getLength() > 0) {
+            state = State.DATA;
+            decoder = new BytePartialDecoder(header.getLength());
+        } else {
+            setValue(builder.build());
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case PAD_LENGTH:
+                padLength = buffer.get();
+                if ((getHeader().getLength() - 1 - padLength) > 0) {
+                    state = State.DATA;
+                    decoder = new BytePartialDecoder(getHeader().getLength() - 1 - padLength);
+                } else if (padLength > 0) {
+                    state = State.PADDING;
+                    decoder = new BytePartialDecoder(padLength);
+                } else {
+                    setValue(builder.build());
+                }
+                break;
+            case DATA:
+                if (decoder.consume(buffer)) {
+                    builder.data(((BytePartialDecoder)decoder).getValue());
+                    if (isFlagSet(FLAGS_PADDING) && (padLength > 0)) {
+                      state = State.PADDING;
+                      decoder = new BytePartialDecoder(padLength);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case PADDING:
+                if (decoder.consume(buffer)) {
+                    builder.padding(((BytePartialDecoder)decoder).getValue());
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
index ba32afc..e59c41e 100644
--- a/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2FrameDecoder.java
@@ -3,86 +3,50 @@
  */
 package org.apache.mina.http2.impl;
 
-import java.nio.ByteBuffer;
-
-import org.apache.mina.http2.api.BytePartialDecoder;
 import org.apache.mina.http2.api.Http2Frame;
-import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.Http2Frame.AbstractHttp2FrameBuilder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
 import org.apache.mina.http2.api.PartialDecoder;
 
-import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
-
 /**
  * @author jeffmaury
  *
  */
-public class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
+public abstract class Http2FrameDecoder implements PartialDecoder<Http2Frame> {
+    private Http2FrameHeader header;
+    
+    private Http2Frame frame;
 
-    private static enum State {
-        LENGTH_TYPE_FLAGS,
-        STREAMID,
-        PAYLOAD
+    public Http2FrameDecoder(Http2FrameHeader header) {
+        this.header = header;
     }
     
-    private State state;
-    
-    private PartialDecoder<?> decoder;
-    
-    private Http2Frame frame;
+    protected boolean isFlagSet(short mask) {
+        return (header.getFlags() & mask) == mask;
+    }
     
-    private boolean frameComplete;
-
-    public Http2FrameDecoder() {
-        reset();
+    protected void initBuilder(AbstractHttp2FrameBuilder builder) {
+        builder.length(header.getLength());
+        builder.type(header.getType());
+        builder.flags(header.getFlags());
+        builder.streamID(header.getStreamID());
     }
     
-    @Override
-    public boolean consume(ByteBuffer buffer) {
-        while (!frameComplete && buffer.remaining() > 0) {
-            switch (state) {
-            case LENGTH_TYPE_FLAGS:
-                if (decoder.consume(buffer)) {
-                    long val = ((LongPartialDecoder)decoder).getValue();
-                    frame.setLength((int) ((val >> 16) & 0xFFFFFFL));
-                    frame.setType((short) ((val >> 8) & 0xFF));
-                    frame.setFlags((short) (val & 0xFF));
-                    state = State.STREAMID;
-                    decoder = new LongPartialDecoder(4);
-                }
-                break;
-            case STREAMID:
-                if (decoder.consume(buffer)) {
-                    frame.setStreamID((int) (((LongPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK));
-                    if (frame.getLength() > 0) {
-                        decoder = new BytePartialDecoder(frame.getLength());
-                        state = State.PAYLOAD;
-                    } else {
-                       frameComplete = true;
-                    }
-                }
-                break;
-            case PAYLOAD:
-                if (decoder.consume(buffer)) {
-                    frame.setPayload(((BytePartialDecoder)decoder).getValue());
-                    frameComplete = true;
-                }
-                break;
-            }
-        }
-        return frameComplete;
+    protected Http2FrameHeader getHeader() {
+        return header;
     }
-
+    
     @Override
     public Http2Frame getValue() {
         return frame;
     }
+    
+    protected void setValue(Http2Frame frame) {
+        this.frame = frame;
+    }
 
     @Override
     public void reset() {
-        state = State.LENGTH_TYPE_FLAGS;
-        decoder = new LongPartialDecoder(5);
-        frame = new Http2Frame();
-        frameComplete = false;
     }
     
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
new file mode 100644
index 0000000..86187b2
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2GoAwayFrameDecoder.java
@@ -0,0 +1,82 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2GoAwayFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2GoAwayFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        LAST_STREAM_ID,
+        CODE,
+        EXTRA
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2GoAwayFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        state = State.LAST_STREAM_ID;
+        decoder = new IntPartialDecoder(4);
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case LAST_STREAM_ID:
+                if (decoder.consume(buffer)) {
+                    builder.lastStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    state = State.CODE;
+                    decoder.reset();
+                }
+            case CODE:
+                if (decoder.consume(buffer)) {
+                    builder.errorCode(((IntPartialDecoder)decoder).getValue());
+                    if (getHeader().getLength() > 8) {
+                        state = State.EXTRA;
+                        decoder = new BytePartialDecoder(getHeader().getLength() - 8);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case EXTRA:
+                if (decoder.consume(buffer)) {
+                    builder.data(((BytePartialDecoder)decoder).getValue());
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
new file mode 100644
index 0000000..72a89c3
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2HeadersFrameDecoder.java
@@ -0,0 +1,117 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2HeadersFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PRIORITY;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2HeadersFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        PAD_LENGTH,
+        STREAM_DEPENDENCY,
+        WEIGHT,
+        HEADER,
+        PADDING
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private int padLength;
+    
+    private Builder builder = new Builder();
+    
+    public Http2HeadersFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        if (isFlagSet(FLAGS_PADDING)) {
+            state = State.PAD_LENGTH;
+        } else if (isFlagSet(FLAGS_PRIORITY)) {
+            state = State.STREAM_DEPENDENCY;
+            decoder = new IntPartialDecoder(4);
+        } else {
+            state = State.HEADER;
+            decoder = new BytePartialDecoder(header.getLength());
+        }
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case PAD_LENGTH:
+                padLength = buffer.get();
+                if (isFlagSet(FLAGS_PRIORITY)) {
+                    decoder = new IntPartialDecoder(4);
+                    state = State.STREAM_DEPENDENCY;
+                } else {
+                    state = State.HEADER;
+                    decoder = new BytePartialDecoder(getHeader().getLength() - 1 - padLength);
+                }
+                break;
+            case STREAM_DEPENDENCY:
+                if (decoder.consume(buffer)) {
+                    builder.streamDependencyID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    builder.exclusiveMode((((IntPartialDecoder)decoder).getValue() & HTTP2_EXCLUSIVE_MASK) == HTTP2_EXCLUSIVE_MASK);
+                    state = State.WEIGHT;
+                }
+                break;
+            case WEIGHT:
+                builder.weight((byte) (buffer.get()+1));
+                state = State.HEADER;
+                int headerLength = getHeader().getLength() - 5;
+                if (isFlagSet(FLAGS_PADDING)) {
+                    headerLength -= (padLength + 1);
+                }
+                decoder = new BytePartialDecoder(headerLength);
+                break;
+            case HEADER:
+                if (decoder.consume(buffer)) {
+                    builder.headerBlockFragment(((BytePartialDecoder)decoder).getValue());
+                    if (isFlagSet(FLAGS_PADDING)) {
+                      state = State.PADDING;
+                      decoder = new BytePartialDecoder(padLength);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case PADDING:
+                if (decoder.consume(buffer)) {
+                    builder.padding(((BytePartialDecoder)decoder).getValue());
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
new file mode 100644
index 0000000..4098d49
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PingFrameDecoder.java
@@ -0,0 +1,70 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PingFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PingFrameDecoder extends Http2FrameDecoder {
+
+    private static enum State {
+        DATA,
+        EXTRA
+    }
+    
+    private State state;
+    
+    private BytePartialDecoder decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2PingFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        decoder = new BytePartialDecoder(8);
+        state = State.DATA;
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case DATA:
+                if (decoder.consume(buffer)) {
+                    builder.data(decoder.getValue());
+                    if (getHeader().getLength() > 8) {
+                        state = State.EXTRA;
+                        decoder = new BytePartialDecoder(getHeader().getLength() - 8);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case EXTRA:
+                if (decoder.consume(buffer)) {
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
new file mode 100644
index 0000000..8fd1036
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PriorityFrameDecoder.java
@@ -0,0 +1,83 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PriorityFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_EXCLUSIVE_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PriorityFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        STREAM_DEPENDENCY,
+        WEIGHT,
+        EXTRA
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2PriorityFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        state = State.STREAM_DEPENDENCY;
+        decoder = new IntPartialDecoder(4);
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case STREAM_DEPENDENCY:
+                if (decoder.consume(buffer)) {
+                    builder.streamDependencyID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    builder.exclusiveMode((((IntPartialDecoder)decoder).getValue() & HTTP2_EXCLUSIVE_MASK) == HTTP2_EXCLUSIVE_MASK);
+                    state = State.WEIGHT;
+                }
+                break;
+            case WEIGHT:
+                builder.weight((short) ((buffer.get() & 0x00FF) + 1));
+                int extraLength = getHeader().getLength() - 5;
+                if (extraLength > 0) {
+                    decoder = new BytePartialDecoder(extraLength);
+                state = State.EXTRA;
+                } else {
+                    setValue(builder.build());
+                }
+                break;
+            case EXTRA:
+                if (decoder.consume(buffer)) {
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
new file mode 100644
index 0000000..34863ce
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2PushPromiseFrameDecoder.java
@@ -0,0 +1,101 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2PushPromiseFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.FLAGS_PADDING;
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2PushPromiseFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        PAD_LENGTH,
+        PROMISED_STREAM,
+        HEADER,
+        PADDING
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private int padLength;
+    
+    private Builder builder = new Builder();
+    
+    public Http2PushPromiseFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        if (isFlagSet(FLAGS_PADDING)) {
+            state = State.PAD_LENGTH;
+        } else {
+            state = State.PROMISED_STREAM;
+            decoder = new IntPartialDecoder(4);
+        }
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case PAD_LENGTH:
+                padLength = buffer.get();
+                state = State.PROMISED_STREAM;
+                decoder = new IntPartialDecoder(4);
+                break;
+            case PROMISED_STREAM:
+                if (decoder.consume(buffer)) {
+                    builder.promisedStreamID(((IntPartialDecoder)decoder).getValue() & HTTP2_31BITS_MASK);
+                    state = State.HEADER;
+                    int headerLength = getHeader().getLength() - 4;
+                    if (isFlagSet(FLAGS_PADDING)) {
+                        headerLength -= (padLength + 1);
+                    }
+                    decoder = new BytePartialDecoder(headerLength);
+                }
+                break;
+            case HEADER:
+                if (decoder.consume(buffer)) {
+                    builder.headerBlockFragment(((BytePartialDecoder)decoder).getValue());
+                    if (isFlagSet(FLAGS_PADDING)) {
+                      state = State.PADDING;
+                      decoder = new BytePartialDecoder(padLength);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case PADDING:
+                if (decoder.consume(buffer)) {
+                    builder.padding(((BytePartialDecoder)decoder).getValue());
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
new file mode 100644
index 0000000..e16b0bc
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2RstStreamFrameDecoder.java
@@ -0,0 +1,75 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2RstStreamFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.LongPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+import static org.apache.mina.http2.api.Http2Constants.HTTP2_31BITS_MASK;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2RstStreamFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        ERROR_CODE,
+        EXTRA
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2RstStreamFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        state = State.ERROR_CODE;
+        decoder = new LongPartialDecoder(4);
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case ERROR_CODE:
+                if (decoder.consume(buffer)) {
+                    builder.errorCode(((LongPartialDecoder)decoder).getValue());
+                    if (getHeader().getLength() > 4) {
+                        state = State.EXTRA;
+                        decoder = new BytePartialDecoder(getHeader().getLength() - 4);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case EXTRA:
+                if (decoder.consume(buffer)) {
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
new file mode 100644
index 0000000..6213c66
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2SettingsFrameDecoder.java
@@ -0,0 +1,64 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2SettingsFrame.Builder;
+import org.apache.mina.http2.api.Http2Setting;
+import org.apache.mina.http2.api.LongPartialDecoder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2SettingsFrameDecoder extends Http2FrameDecoder {
+
+    private int remaining;
+    
+    private LongPartialDecoder decoder = new LongPartialDecoder(6);
+    
+    private Builder builder = new Builder();
+    
+    private Collection<Http2Setting> settings = new ArrayList<Http2Setting>();
+    
+    public Http2SettingsFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        remaining = header.getLength() / 6;
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            if (decoder.consume(buffer)) {
+                remaining--;
+                Http2Setting setting = new Http2Setting();
+                setting.setID((int) ((decoder.getValue() & 0x00FFFF00000000L) >> 32));
+                setting.setValue(decoder.getValue() & 0x00FFFFFFFFL);
+                settings.add(setting);
+                decoder.reset();
+                if (remaining == 0) {
+                    builder.settings(settings);
+                    setValue(builder.build());
+                }
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
new file mode 100644
index 0000000..f19e55f
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2UnknownFrameDecoder.java
@@ -0,0 +1,52 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2UnknownFrame.Builder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2UnknownFrameDecoder extends Http2FrameDecoder {
+
+    private BytePartialDecoder decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2UnknownFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        initBuilder(builder);
+        if (header.getLength() > 0) {
+            decoder = new BytePartialDecoder(header.getLength());
+        } else {
+            setValue(builder.build());
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            if (decoder.consume(buffer)) {
+                builder.payload(decoder.getValue());
+                setValue(builder.build());
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
----------------------------------------------------------------------
diff --git a/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
new file mode 100644
index 0000000..6d96327
--- /dev/null
+++ b/http2/src/main/java/org/apache/mina/http2/impl/Http2WindowUpdateFrameDecoder.java
@@ -0,0 +1,73 @@
+/**
+ * 
+ */
+package org.apache.mina.http2.impl;
+
+import java.nio.ByteBuffer;
+
+import org.apache.mina.http2.api.BytePartialDecoder;
+import org.apache.mina.http2.api.Http2FrameHeadePartialDecoder.Http2FrameHeader;
+import org.apache.mina.http2.api.Http2WindowUpdateFrame.Builder;
+import org.apache.mina.http2.api.IntPartialDecoder;
+import org.apache.mina.http2.api.PartialDecoder;
+
+/**
+ * @author jeffmaury
+ *
+ */
+public class Http2WindowUpdateFrameDecoder extends Http2FrameDecoder {
+
+    private enum State {
+        INCREMENT,
+        EXTRA
+    }
+    
+    private State state;
+    
+    private PartialDecoder<?> decoder;
+    
+    private Builder builder = new Builder();
+    
+    public Http2WindowUpdateFrameDecoder(Http2FrameHeader header) {
+        super(header);
+        state = State.INCREMENT;
+        decoder = new IntPartialDecoder(4);
+        initBuilder(builder);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#consume(java.nio.ByteBuffer)
+     */
+    @Override
+    public boolean consume(ByteBuffer buffer) {
+        while ((getValue() == null) && buffer.remaining() > 0) {
+            switch (state) {
+            case INCREMENT:
+                if (decoder.consume(buffer)) {
+                    builder.windowUpdateIncrement(((IntPartialDecoder)decoder).getValue());
+                    if (getHeader().getLength() > 4) {
+                        state = State.EXTRA;
+                        decoder = new BytePartialDecoder(getHeader().getLength() - 4);
+                    } else {
+                        setValue(builder.build());
+                    }
+                }
+                break;
+            case EXTRA:
+                if (decoder.consume(buffer)) {
+                    setValue(builder.build());
+                }
+                break;
+            }
+        }
+        return getValue() != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.mina.http2.api.PartialDecoder#reset()
+     */
+    @Override
+    public void reset() {
+    }
+
+}


[2/8] mina git commit: Multiple HTTP2 PDUs

Posted by je...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
index 30b7299..02f7198 100644
--- a/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
+++ b/http2/src/test/java/org/apache/mina/http2/api/Htp2PushPromiseFrameDecoderTest.java
@@ -11,10 +11,10 @@ import org.junit.Test;
 public class Htp2PushPromiseFrameDecoderTest {
 
     @Test
-    public void checkHeadersFrameWithNotPadding() {
+    public void checkWithNoPadding() {
         Http2Connection connection = new Http2Connection();
         ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x05, /*length*/
-                                                        0x01, /*type*/
+                                                        0x05, /*type*/
                                                         0x00, /*flags*/
                                                         0x00, 0x00, 0x00, 0x01, /*streamID*/
                                                         0x00, 0x00, 0x01, 0x00, /*promisedStreamID*/
@@ -32,49 +32,26 @@ public class Htp2PushPromiseFrameDecoderTest {
     
     
     @Test
-    public void checkHeadersFramePaddingPriority() {
+    public void checkWithPadding() {
         Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x17, /*length*/
-                                                        0x01, /*type*/
-                                                        0x28, /*flags*/
-                                                        0x00, 0x00, 0x00, 0x03, /*streamID*/
-                                                        0x10, /*padding length*/
-                                                        (byte)0x0080, 0x00, 0x00, 0x14, /*stream dependency*/
-                                                        0x09, /*weight*/
-                                                        (byte) 0x0082, /*headerFragment*/
-                                                        0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
-        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(23, frame.getLength());
-        assertEquals(1, frame.getType());
-        assertEquals(0x28, frame.getFlags());
-        assertEquals(3, frame.getStreamID());
-        assertEquals(10,  frame.getWeight());
-        assertEquals(1, frame.getHeaderBlockFragment().length);
-        assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
-        assertEquals(16,  frame.getPadding().length);
-        assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
-    }
-    
-    @Test
-    public void checkHeadersFramePaddingNoPriority() {
-        Http2Connection connection = new Http2Connection();
-        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x12, /*length*/
-                                                        0x01, /*type*/
+        ByteBuffer buffer = ByteBuffer.wrap(new byte[] {0x00, 0x00, 0x16, /*length*/
+                                                        0x05, /*type*/
                                                         0x08, /*flags*/
                                                         0x00, 0x00, 0x00, 0x03, /*streamID*/
                                                         0x10, /*padding length*/
+                                                        0x00, 0x00, 0x00, 0x14, /*promisedStreamID*/
                                                         (byte) 0x0082, /*headerFragment*/
                                                         0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E /*padding*/});
-        Http2HeadersFrame frame = (Http2HeadersFrame) connection.decode(buffer);
-        assertNotNull(frame);
-        assertEquals(18, frame.getLength());
-        assertEquals(1, frame.getType());
+        Http2PushPromiseFrame frame = (Http2PushPromiseFrame) connection.decode(buffer);
+        assertEquals(22, frame.getLength());
+        assertEquals(5, frame.getType());
         assertEquals(0x08, frame.getFlags());
         assertEquals(3, frame.getStreamID());
+        assertEquals(20, frame.getPromisedStreamID());
         assertEquals(1, frame.getHeaderBlockFragment().length);
         assertEquals(0x0082, frame.getHeaderBlockFragment()[0] & 0x00FF);
         assertEquals(16,  frame.getPadding().length);
         assertArrayEquals(new byte[] {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x2E}, frame.getPadding());
     }
+    
 }

http://git-wip-us.apache.org/repos/asf/mina/blob/27938fb1/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
----------------------------------------------------------------------
diff --git a/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java b/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
index bda0c77..af684b4 100644
--- a/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
+++ b/http2/src/test/java/org/apache/mina/http2/api/Http2FrameHeaderPartialDecoderTest.java
@@ -58,8 +58,6 @@ public class Http2FrameHeaderPartialDecoderTest {
         assertEquals(0, header.getType());
         assertEquals(0, header.getFlags());
         assertEquals(1, header.getStreamID());
-        assertEquals(1, header.getPayload().length);
-        assertEquals(0x40, header.getPayload()[0]       );
     }
 
 }