[hornetq-commits] JBoss hornetq SVN: r11519 - in trunk: hornetq-core/src/main/java/org/hornetq/core/protocol/stomp and 7 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Oct 12 04:32:15 EDT 2011


Author: gaohoward
Date: 2011-10-12 04:32:14 -0400 (Wed, 12 Oct 2011)
New Revision: 11519

Added:
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
Removed:
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
Modified:
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java
   trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java
   trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java
   trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java
Log:
stomp 1.1 impl


Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -72,7 +72,7 @@
    public int sendMessage(ServerMessage message, long consumerID, int deliveryCount)
    {
       Packet packet = new SessionReceiveMessage(consumerID, message, deliveryCount);
-
+      
       channel.sendBatched(packet);
 
       int size = packet.getPacketSize();

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/FrameEventListener.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +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.hornetq.core.protocol.stomp;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public interface FrameEventListener
+{
+
+   void replySent(StompFrame reply);
+
+   void requestAccepted(StompFrame request);
+
+}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/HornetQStompException.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class HornetQStompException extends Exception {
+
+   private static final long serialVersionUID = -274452327574950068L;
+   
+   private List<Header> headers = new ArrayList<Header>(10);
+   private String body;
+   private VersionedStompFrameHandler handler;
+   private boolean disconnect;
+   
+   public HornetQStompException(StompConnection connection, String msg)
+   {
+      super(msg);
+      handler = connection.getFrameHandler();
+   }
+   public HornetQStompException(String msg)
+   {
+      super(msg);
+   }
+   
+   public HornetQStompException(String msg, Throwable t)
+   {
+      super(msg, t);
+      this.body = t.getMessage();
+   }
+   
+   public HornetQStompException(Throwable t)
+   {
+      super(t);
+   }
+
+   public void addHeader(String header, String value)
+   {
+      headers.add(new Header(header, value));
+   }
+   
+   public void setBody(String body)
+   {
+      this.body = body;
+   }
+
+   public StompFrame getFrame()
+   {
+      StompFrame frame = null;
+      if (handler == null)
+      {
+         frame = new StompFrame("ERROR");
+         frame.addHeader("message", this.getMessage());
+         if (body != null)
+         {
+            try
+            {
+               frame.setByteBody(body.getBytes("UTF-8"));
+            }
+            catch (UnsupportedEncodingException e)
+            {
+            }
+         }
+         else
+         {
+            frame.setByteBody(new byte[0]);
+         }
+      }
+      else
+      {
+         frame = handler.createStompFrame("ERROR");
+         frame.addHeader("message", this.getMessage());
+      }
+      frame.setNeedsDisconnect(disconnect);
+      return frame;
+   }
+
+   private class Header
+   {
+      public String key;
+      public String val;
+      
+      public Header(String key, String val)
+      {
+         this.key = key;
+         this.val = val;
+      }
+   }
+
+   public void setDisconnect(boolean b)
+   {
+      disconnect = b;
+   }
+}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/SimpleBytes.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,44 @@
+package org.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+
+
+public class SimpleBytes
+{
+   private int step;
+   private byte[] contents;
+   private int index;
+   
+   public SimpleBytes(int initCapacity)
+   {
+      this.step = initCapacity;
+      contents = new byte[initCapacity];
+      index = 0;
+   }
+
+   public String getString() throws UnsupportedEncodingException
+   {
+      if (index == 0) return "";
+      byte[] realData = new byte[index];
+      System.arraycopy(contents, 0, realData, 0, realData.length);
+      
+      return new String(realData, "UTF-8");
+   }
+   
+   public void reset()
+   {
+      index = 0;
+   }
+
+   public void append(byte b)
+   {
+      if (index >= contents.length)
+      {
+         //grow
+         byte[] newBuffer = new byte[contents.length + step];
+         System.arraycopy(contents, 0, newBuffer, 0, contents.length);
+         contents = newBuffer;
+      }
+      contents[index++] = b;
+   }
+}

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/Stomp.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -40,12 +40,6 @@
 
       String UNSUBSCRIBE = "UNSUBSCRIBE";
 
-      String BEGIN_TRANSACTION = "BEGIN";
-
-      String COMMIT_TRANSACTION = "COMMIT";
-
-      String ABORT_TRANSACTION = "ABORT";
-
       String BEGIN = "BEGIN";
 
       String COMMIT = "COMMIT";
@@ -53,6 +47,11 @@
       String ABORT = "ABORT";
 
       String ACK = "ACK";
+
+      //1.1
+      String NACK = "NACK";
+      
+      String STOMP = "STOMP";
    }
 
    public interface Responses
@@ -76,6 +75,10 @@
 
       String CONTENT_LENGTH = "content-length";
 
+      String ACCEPT_VERSION = "accept-version";
+
+      String CONTENT_TYPE = "content-type";
+
       public interface Response
       {
          String RECEIPT_ID = "receipt-id";
@@ -140,6 +143,8 @@
             String AUTO = "auto";
 
             String CLIENT = "client";
+            
+            String CLIENT_INDIVIDUAL = "client-individual";
          }
       }
 
@@ -159,11 +164,21 @@
          String CLIENT_ID = "client-id";
 
          String REQUEST_ID = "request-id";
+         
+         //1.1
+         String ACCEPT_VERSION = "accept-version";
+         String HOST = "host";
+
+         Object HEART_BEAT = "heart-beat";
       }
 
       public interface Error
       {
+         //1.0 only
          String MESSAGE = "message";
+         
+         //1.1
+         String VERSION = "version";
       }
 
       public interface Connected
@@ -171,11 +186,21 @@
          String SESSION = "session";
 
          String RESPONSE_ID = "response-id";
+
+         //1.1
+         String VERSION = "version";
+
+         String SERVER = "server";
+
+         String HEART_BEAT = "heart-beat";
       }
 
       public interface Ack
       {
          String MESSAGE_ID = "message-id";
+         
+         //1.1
+         String SUBSCRIPTION = "subscription";
       }
    }
 }

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompConnection.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -15,7 +15,10 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.hornetq.api.core.HornetQBuffer;
@@ -24,6 +27,8 @@
 import org.hornetq.core.logging.Logger;
 import org.hornetq.core.remoting.CloseListener;
 import org.hornetq.core.remoting.FailureListener;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
 import org.hornetq.spi.core.protocol.RemotingConnection;
 import org.hornetq.spi.core.remoting.Acceptor;
 import org.hornetq.spi.core.remoting.Connection;
@@ -37,8 +42,9 @@
  */
 public class StompConnection implements RemotingConnection
 {
-
    private static final Logger log = Logger.getLogger(StompConnection.class);
+   
+   protected static final String CONNECTION_ID_PROP = "__HQ_CID";
 
    private final StompProtocolManager manager;
 
@@ -50,13 +56,14 @@
 
    private String clientID;
 
+   //this means login is valid. (stomp connection ok)
    private boolean valid;
 
    private boolean destroyed = false;
    
    private final long creationTime;
 
-   private StompDecoder decoder = new StompDecoder();
+   private StompDecoder decoder;
    
    private final Acceptor acceptorUsed;
 
@@ -67,6 +74,17 @@
    private final Object failLock = new Object();
    
    private volatile boolean dataReceived;
+   
+   private StompVersions version;
+   
+   private VersionedStompFrameHandler frameHandler;
+   
+   //this means the version negotiation done.
+   private boolean initialized;
+   
+   private FrameEventListener stompListener;
+   
+   private final Object sendLock = new Object();
 
    public StompDecoder getDecoder()
    {
@@ -79,6 +97,8 @@
 
       this.manager = manager;
       
+      this.decoder = new StompDecoder(this);
+      
       this.creationTime = System.currentTimeMillis();
       
       this.acceptorUsed = acceptorUsed;
@@ -189,7 +209,10 @@
 
       internalClose();
 
-      callClosingListeners();
+      synchronized(sendLock)
+      {
+         callClosingListeners();
+      }
    }
    
    Acceptor getAcceptorUsed()
@@ -204,10 +227,6 @@
       manager.cleanup(this);
    }
 
-   public void disconnect()
-   {
-   }
-
    public void fail(final HornetQException me)
    {
       synchronized (failLock)
@@ -359,4 +378,356 @@
       }
    }
 
+   /*
+    * accept-version value takes form of "v1,v2,v3..."
+    * we need to return the highest supported version
+    */
+   public void negotiateVersion(StompFrame frame) throws HornetQStompException
+   {
+      String acceptVersion = frame.getHeader(Stomp.Headers.ACCEPT_VERSION);
+      
+      if (acceptVersion == null)
+      {
+         this.version = StompVersions.V1_0;
+      }
+      else
+      {
+         Set<String> requestVersions = new HashSet<String>();
+         StringTokenizer tokenizer = new StringTokenizer(acceptVersion, ",");
+         while (tokenizer.hasMoreTokens())
+         {
+            requestVersions.add(tokenizer.nextToken());
+         }
+         
+         if (requestVersions.contains("1.1"))
+         {
+            this.version = StompVersions.V1_1;
+         }
+         else if (requestVersions.contains("1.0"))
+         {
+            this.version = StompVersions.V1_0;
+         }
+         else
+         {
+            //not a supported version!
+            HornetQStompException error = new HornetQStompException("Stomp versions not supported: " + acceptVersion);
+            error.addHeader("version", acceptVersion);
+            error.addHeader("content-type", "text/plain");
+            error.setBody("Supported protocol version are " + manager.getSupportedVersionsAsString());
+            error.setDisconnect(true);
+            throw error;
+         }
+         log.error("------------------ negotiated version is " + this.version);
+      }
+      
+      this.frameHandler = VersionedStompFrameHandler.getHandler(this, this.version);
+      this.initialized = true;
+   }
+
+   //reject if the host doesn't match
+   public void setHost(String host) throws HornetQStompException
+   {
+      if (host == null)
+      {
+         HornetQStompException error = new HornetQStompException("Header host is null");
+         error.setBody("Cannot accept null as host");
+         throw error;
+      }
+      
+      String localHost = manager.getVirtualHostName();
+      if (!host.equals(localHost))
+      {
+         HornetQStompException error = new HornetQStompException("Header host doesn't match server host");
+         error.setBody("host " + host + " doesn't match server host name");
+         throw error;
+      }
+   }
+
+   public void handleFrame(StompFrame request)
+   {
+      StompFrame reply = null;
+      
+      if (stompListener != null)
+      {
+         stompListener.requestAccepted(request);
+      }
+
+      String cmd = request.getCommand();
+      try
+      {
+         if (!initialized)
+         {
+            if ( ! (Stomp.Commands.CONNECT.equals(cmd) || Stomp.Commands.STOMP.equals(cmd)))
+            {
+               throw new HornetQStompException("Connection hasn't been established.");
+            }
+            //decide version
+            negotiateVersion(request);
+         }
+         reply = frameHandler.handleFrame(request);
+      }
+      catch (HornetQStompException e)
+      {
+         reply = e.getFrame();
+      }
+      
+      if (reply != null)
+      {
+         sendFrame(reply);
+      }
+      
+      if (Stomp.Commands.DISCONNECT.equals(cmd))
+      {
+         this.disconnect();
+      }
+   }
+
+   public void sendFrame(StompFrame frame)
+   {
+      manager.sendReply(this, frame);
+   }
+
+   public boolean validateUser(String login, String passcode)
+   {
+      this.valid = manager.validateUser(login, passcode);
+      if (valid)
+      {
+         this.login = login;
+         this.passcode = passcode;
+      }
+      return valid;
+   }
+
+   public ServerMessageImpl createServerMessage()
+   {
+      return manager.createServerMessage();
+   }
+
+   public StompSession getSession(String txID) throws HornetQStompException
+   {
+      StompSession session = null;
+      try
+      {
+         if (txID == null)
+         {
+            session = manager.getSession(this);
+         }
+         else
+         {
+            session = manager.getTransactedSession(this, txID);
+         }
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Exception getting session", e);
+      }
+      
+      return session;
+   }
+
+   public void validate() throws HornetQStompException
+   {
+      if (!this.valid)
+      {
+         throw new HornetQStompException("Connection is not valid.");
+      }
+   }
+
+   public void sendServerMessage(ServerMessageImpl message, String txID) throws HornetQStompException
+   {
+      StompSession stompSession = getSession(txID);
+
+      if (stompSession.isNoLocal())
+      {
+         message.putStringProperty(CONNECTION_ID_PROP, getID().toString());
+      }
+      try
+      {
+         stompSession.getSession().send(message, true);
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error sending message " + message, e);
+      }
+   }
+
+   @Override
+   public void disconnect()
+   {
+      destroy();
+   }
+
+   public void beginTransaction(String txID) throws HornetQStompException
+   {
+      try
+      {
+         manager.beginTransaction(this, txID);
+      }
+      catch (HornetQStompException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error beginning a transaction: " + txID, e);
+      }
+   }
+
+   public void commitTransaction(String txID) throws HornetQStompException
+   {
+      try
+      {
+         manager.commitTransaction(this, txID);
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error committing " + txID, e);
+      }
+   }
+
+   public void abortTransaction(String txID) throws HornetQStompException
+   {
+      try
+      {
+         manager.abortTransaction(this, txID);
+      }
+      catch (HornetQStompException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error aborting " + txID, e);
+      }
+   }
+
+   public void subscribe(String destination, String selector, String ack,
+         String id, String durableSubscriptionName, boolean noLocal) throws HornetQStompException
+   {
+      if (noLocal)
+      {
+         String noLocalFilter = CONNECTION_ID_PROP + " <> '" + getID().toString() + "'";
+         if (selector == null)
+         {
+            selector = noLocalFilter;
+         }
+         else
+         {
+            selector += " AND " + noLocalFilter;
+         }
+      }
+
+      if (ack == null)
+      {
+         ack = Stomp.Headers.Subscribe.AckModeValues.AUTO;
+      }
+
+      String subscriptionID = null;
+      if (id != null)
+      {
+         subscriptionID = id;
+      }
+      else
+      {
+         if (destination == null)
+         {
+            throw new HornetQStompException("Client must set destination or id header to a SUBSCRIBE command");
+         }
+         subscriptionID = "subscription/" + destination;
+      }
+      
+      try
+      {
+         manager.createSubscription(this, subscriptionID, durableSubscriptionName, destination, selector, ack, noLocal);
+      }
+      catch (HornetQStompException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error creating subscription " + subscriptionID, e);
+      }
+   }
+
+   public void unsubscribe(String subscriptionID) throws HornetQStompException
+   {
+      try
+      {
+         manager.unsubscribe(this, subscriptionID);
+      }
+      catch (HornetQStompException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error unsubscripting " + subscriptionID, e);
+      }
+   }
+
+   public void acknowledge(String messageID, String subscriptionID) throws HornetQStompException
+   {
+      try
+      {
+         manager.acknowledge(this, messageID, subscriptionID);
+      }
+      catch (HornetQStompException e)
+      {
+         throw e;
+      }
+      catch (Exception e)
+      {
+         throw new HornetQStompException("Error acknowledging message " + messageID, e);
+      }
+   }
+
+   public String getVersion()
+   {
+      return String.valueOf(version);
+   }
+
+   public String getHornetQServerName()
+   {
+      //hard coded, review later.
+      return "HornetQ/2.2.5 HornetQ Messaging Engine";
+   }
+
+   public StompFrame createStompMessage(ServerMessage serverMessage,
+         StompSubscription subscription, int deliveryCount) throws Exception
+   {
+      return frameHandler.createMessageFrame(serverMessage, subscription, deliveryCount);
+   }
+
+   public void addStompEventListener(FrameEventListener listener)
+   {
+      this.stompListener = listener;
+   }
+
+   //send a ping stomp frame
+   public void ping(StompFrame pingFrame)
+   {
+      manager.sendReply(this, pingFrame);
+   }
+
+   public void physicalSend(StompFrame frame) throws Exception
+   {
+      HornetQBuffer buffer = frame.toHornetQBuffer();
+      
+      synchronized (sendLock)
+      {
+         getTransportConnection().write(buffer, false, false);
+      }
+
+      if (stompListener != null)
+      {
+         stompListener.replySent(frame);
+      }
+
+   }
+
+   public VersionedStompFrameHandler getFrameHandler()
+   {
+      return this.frameHandler;
+   }
 }

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompDecoder.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -30,116 +30,142 @@
 {
    private static final Logger log = Logger.getLogger(StompDecoder.class);
 
-   private static final boolean TRIM_LEADING_HEADER_VALUE_WHITESPACE = true;
+   public static final boolean TRIM_LEADING_HEADER_VALUE_WHITESPACE = true;
 
-   private static final String COMMAND_ABORT = "ABORT";
+   public static final String COMMAND_ABORT = "ABORT";
 
-   private static final int COMMAND_ABORT_LENGTH = COMMAND_ABORT.length();
+   public static final int COMMAND_ABORT_LENGTH = COMMAND_ABORT.length();
 
-   private static final String COMMAND_ACK = "ACK";
+   public static final String COMMAND_ACK = "ACK";
 
-   private static final int COMMAND_ACK_LENGTH = COMMAND_ACK.length();
+   public static final int COMMAND_ACK_LENGTH = COMMAND_ACK.length();
 
-   private static final String COMMAND_BEGIN = "BEGIN";
+   public static final String COMMAND_NACK = "NACK";
 
-   private static final int COMMAND_BEGIN_LENGTH = COMMAND_BEGIN.length();
+   public static final int COMMAND_NACK_LENGTH = COMMAND_NACK.length();
 
-   private static final String COMMAND_COMMIT = "COMMIT";
+   public static final String COMMAND_BEGIN = "BEGIN";
 
-   private static final int COMMAND_COMMIT_LENGTH = COMMAND_COMMIT.length();
+   public static final int COMMAND_BEGIN_LENGTH = COMMAND_BEGIN.length();
 
-   private static final String COMMAND_CONNECT = "CONNECT";
+   public static final String COMMAND_COMMIT = "COMMIT";
 
-   private static final int COMMAND_CONNECT_LENGTH = COMMAND_CONNECT.length();
+   public static final int COMMAND_COMMIT_LENGTH = COMMAND_COMMIT.length();
 
-   private static final String COMMAND_DISCONNECT = "DISCONNECT";
+   public static final String COMMAND_CONNECT = "CONNECT";
 
-   private static final int COMMAND_DISCONNECT_LENGTH = COMMAND_DISCONNECT.length();
+   public static final int COMMAND_CONNECT_LENGTH = COMMAND_CONNECT.length();
 
-   private static final String COMMAND_SEND = "SEND";
+   public static final String COMMAND_DISCONNECT = "DISCONNECT";
 
-   private static final int COMMAND_SEND_LENGTH = COMMAND_SEND.length();
+   public static final int COMMAND_DISCONNECT_LENGTH = COMMAND_DISCONNECT.length();
 
-   private static final String COMMAND_SUBSCRIBE = "SUBSCRIBE";
+   public static final String COMMAND_SEND = "SEND";
 
-   private static final int COMMAND_SUBSCRIBE_LENGTH = COMMAND_SUBSCRIBE.length();
+   public static final int COMMAND_SEND_LENGTH = COMMAND_SEND.length();
 
-   private static final String COMMAND_UNSUBSCRIBE = "UNSUBSCRIBE";
+   public static final String COMMAND_STOMP = "STOMP";
 
-   private static final int COMMAND_UNSUBSCRIBE_LENGTH = COMMAND_UNSUBSCRIBE.length();
+   public static final int COMMAND_STOMP_LENGTH = COMMAND_STOMP.length();
 
+   public static final String COMMAND_SUBSCRIBE = "SUBSCRIBE";
+
+   public static final int COMMAND_SUBSCRIBE_LENGTH = COMMAND_SUBSCRIBE.length();
+
+   public static final String COMMAND_UNSUBSCRIBE = "UNSUBSCRIBE";
+
+   public static final int COMMAND_UNSUBSCRIBE_LENGTH = COMMAND_UNSUBSCRIBE.length();
+
    /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
-   private static final String COMMAND_CONNECTED = "CONNECTED";
+   public static final String COMMAND_CONNECTED = "CONNECTED";
 
-   private static final int COMMAND_CONNECTED_LENGTH = COMMAND_CONNECTED.length();
+   public static final int COMMAND_CONNECTED_LENGTH = COMMAND_CONNECTED.length();
    
-   private static final String COMMAND_MESSAGE = "MESSAGE";
+   public static final String COMMAND_MESSAGE = "MESSAGE";
 
-   private static final int COMMAND_MESSAGE_LENGTH = COMMAND_MESSAGE.length();
+   public static final int COMMAND_MESSAGE_LENGTH = COMMAND_MESSAGE.length();
 
-   private static final String COMMAND_ERROR = "ERROR";
+   public static final String COMMAND_ERROR = "ERROR";
 
-   private static final int COMMAND_ERROR_LENGTH = COMMAND_ERROR.length();
+   public static final int COMMAND_ERROR_LENGTH = COMMAND_ERROR.length();
 
-   private static final String COMMAND_RECEIPT = "RECEIPT";
+   public static final String COMMAND_RECEIPT = "RECEIPT";
 
-   private static final int COMMAND_RECEIPT_LENGTH = COMMAND_RECEIPT.length();
+   public static final int COMMAND_RECEIPT_LENGTH = COMMAND_RECEIPT.length();
    /**** end  ****/
 
-   private static final byte A = (byte)'A';
+   public static final byte A = (byte)'A';
 
-   private static final byte B = (byte)'B';
+   public static final byte B = (byte)'B';
 
-   private static final byte C = (byte)'C';
+   public static final byte C = (byte)'C';
 
-   private static final byte D = (byte)'D';
+   public static final byte D = (byte)'D';
 
-   private static final byte E = (byte)'E';
+   public static final byte E = (byte)'E';
 
-   private static final byte M = (byte)'M';
+   public static final byte T = (byte)'T';
 
-   private static final byte S = (byte)'S';
+   public static final byte M = (byte)'M';
+
+   public static final byte S = (byte)'S';
    
-   private static final byte R = (byte)'R';
+   public static final byte R = (byte)'R';
 
-   private static final byte U = (byte)'U';
+   public static final byte U = (byte)'U';
 
-   private static final byte HEADER_SEPARATOR = (byte)':';
+   public static final byte N = (byte)'N';
+   
+   public static final byte LN = (byte)'n';
 
-   private static final byte NEW_LINE = (byte)'\n';
+   public static final byte HEADER_SEPARATOR = (byte)':';
 
-   private static final byte SPACE = (byte)' ';
+   public static final byte NEW_LINE = (byte)'\n';
 
-   private static final byte TAB = (byte)'\t';
+   public static final byte SPACE = (byte)' ';
 
-   private static String CONTENT_LENGTH_HEADER_NAME = "content-length";
+   public static final byte TAB = (byte)'\t';
 
-   private byte[] workingBuffer = new byte[1024];
+   public static final String CONTENT_TYPE_HEADER_NAME = "content-type";
 
-   private int pos;
+   public static String CONTENT_LENGTH_HEADER_NAME = "content-length";
 
-   private int data;
+   public byte[] workingBuffer = new byte[1024];
 
-   private String command;
+   public int pos;
 
-   private Map<String, Object> headers;
+   public int data;
 
-   private int headerBytesCopyStart;
+   public String command;
 
-   private boolean readingHeaders;
+   public Map<String, String> headers;
 
-   private boolean headerValueWhitespace;
+   public int headerBytesCopyStart;
 
-   private boolean inHeaderName;
+   public boolean readingHeaders;
 
-   private String headerName;
+   public boolean headerValueWhitespace;
 
-   private boolean whiteSpaceOnly;
+   public boolean inHeaderName;
 
-   private int contentLength;
+   public String headerName;
 
-   private int bodyStart;
+   public boolean whiteSpaceOnly;
 
+   public int contentLength;
+   
+   public String contentType;
+
+   public int bodyStart;
+   
+   public StompConnection connection;
+
+   public StompDecoder(StompConnection stompConnection)
+   {
+      this.connection = stompConnection;
+      init();
+   }
+
    public StompDecoder()
    {
       init();
@@ -156,13 +182,25 @@
     * followed by an empty line
     * followed by an optional message body
     * terminated with a null character
+    * 
+    * Note: to support both 1.0 and 1.1, we just assemble a
+    * standard StompFrame and let the versioned handler to do more
+    * spec specific job (like trimming, escaping etc).
     */
    public synchronized StompFrame decode(final HornetQBuffer buffer) throws Exception
    {
-      //log.info("got buff " + buffer.readableBytes());
+      if (connection != null && connection.isValid())
+      {
+         VersionedStompFrameHandler handler = connection.getFrameHandler();
+         return handler.decode(this, buffer);
+      }
       
-      long start = System.nanoTime();
-      
+      return defaultDecode(buffer);
+   }
+   
+   public StompFrame defaultDecode(final HornetQBuffer buffer) throws HornetQStompException
+   {
+
       int readable = buffer.readableBytes();
 
       if (data + readable >= workingBuffer.length)
@@ -338,6 +376,16 @@
                   // SEND
                   command = COMMAND_SEND;
                }
+               else if (workingBuffer[offset + 1] == T)
+               {
+                  if (!tryIncrement(offset + COMMAND_STOMP_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SEND
+                  command = COMMAND_STOMP;                  
+               }
                else
                {
                   if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + 1))
@@ -375,8 +423,6 @@
             throwInvalid();
          }
       }
-      
-      long commandTime = System.nanoTime() - start;
 
       if (readingHeaders)
       {
@@ -482,8 +528,6 @@
             }
          }
       }
-      
-      long headersTime = System.nanoTime() - start - commandTime;
 
       // Now the body
 
@@ -526,8 +570,6 @@
          }
       }
       
-      
-
       if (content != null)
       {
          if (data > pos)
@@ -546,34 +588,28 @@
          StompFrame ret = new StompFrame(command, headers, content);
 
          init();
-         
-        // log.info("decoded");
-         
-         long bodyTime = System.nanoTime() - start - headersTime - commandTime;
-         
-        // log.info("command: "+ commandTime + " headers: " + headersTime + " body: " + bodyTime);
 
          return ret;
       }
       else
       {
          return null;
-      }
+      }      
    }
 
-   private void throwInvalid() throws StompException
+   public void throwInvalid() throws HornetQStompException
    {
-      throw new StompException("Invalid STOMP frame: " + this.dumpByteArray(workingBuffer));
+      throw new HornetQStompException("Invalid STOMP frame: " + this.dumpByteArray(workingBuffer));
    }
 
-   private void init()
+   public void init()
    {
       pos = 0;
 
       command = null;
+      
+      headers = new HashMap<String, String>();
 
-      headers = new HashMap<String, Object>();
-
       this.headerBytesCopyStart = -1;
 
       readingHeaders = true;
@@ -588,10 +624,12 @@
 
       contentLength = -1;
 
+      contentType = null;
+      
       bodyStart = -1;
    }
 
-   private void resizeWorking(final int newSize)
+   public void resizeWorking(final int newSize)
    {
       byte[] oldBuffer = workingBuffer;
 
@@ -600,7 +638,7 @@
       System.arraycopy(oldBuffer, 0, workingBuffer, 0, oldBuffer.length);
    }
 
-   private boolean tryIncrement(final int length)
+   public boolean tryIncrement(final int length)
    {
       if (pos + length >= data)
       {

Deleted: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompException.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,57 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.hornetq.core.protocol.stomp;
-
-import java.io.IOException;
-
-/**
- * @author <a href="http://hiramchirino.com">chirino</a>
- */
-class StompException extends IOException
-{
-   private static final long serialVersionUID = -2869735532997332242L;
-
-   private final boolean fatal;
-
-   public StompException()
-   {
-      this(null);
-   }
-
-   public StompException(String s)
-   {
-      this(s, false);
-   }
-
-   public StompException(String s, boolean fatal)
-   {
-      this(s, fatal, null);
-   }
-
-   public StompException(String s, boolean fatal, Throwable cause)
-   {
-      super(s);
-      this.fatal = fatal;
-      initCause(cause);
-   }
-
-   public boolean isFatal()
-   {
-      return fatal;
-   }
-}

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompFrame.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -17,6 +17,11 @@
  */
 package org.hornetq.core.protocol.stomp;
 
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -31,36 +36,46 @@
  * @author Tim Fox
  * 
  */
-class StompFrame
+public class StompFrame
 {
-   private static final Logger log = Logger.getLogger(StompFrame.class);
+   protected static final Logger log = Logger.getLogger(StompFrame.class);
 
-   public static final byte[] NO_DATA = new byte[] {};
+   protected static final byte[] NO_DATA = new byte[] {};
 
-   private static final byte[] END_OF_FRAME = new byte[] { 0, '\n' };
+   protected static final byte[] END_OF_FRAME = new byte[] { 0, '\n' };
 
-   private final String command;
+   protected String command;
 
-   private final Map<String, Object> headers;
+   protected Map<String, String> headers;
 
-   private final byte[] content;
+   protected String body;
+   
+   protected byte[] bytesBody;
 
-   private HornetQBuffer buffer = null;
+   protected HornetQBuffer buffer = null;
 
-   private int size;
+   protected int size;
    
-   public StompFrame(String command, Map<String, Object> headers, byte[] data)
+   protected boolean disconnect;
+   
+   public StompFrame(String command)
    {
+      this(command, false);
+   }
+
+   public StompFrame(String command, boolean disconnect)
+   {
       this.command = command;
-      this.headers = headers;
-      this.content = data;
+      this.headers = new LinkedHashMap<String, String>();
+      this.disconnect = disconnect;
    }
 
-   public StompFrame(String command, Map<String, Object> headers)
+   public StompFrame(String command, Map<String, String> headers,
+         byte[] content)
    {
       this.command = command;
       this.headers = headers;
-      this.content = NO_DATA;
+      this.bytesBody = content;
    }
 
    public String getCommand()
@@ -68,16 +83,6 @@
       return command;
    }
 
-   public byte[] getContent()
-   {
-      return content;
-   }
-   
-   public Map<String, Object> getHeaders()
-   {
-      return headers;
-   }
-
    public int getEncodedSize() throws Exception
    {
       if (buffer == null)
@@ -90,33 +95,39 @@
    @Override
    public String toString()
    {
-      return "StompFrame[command=" + command + ", headers=" + headers + ", content-length=" + content.length + "]";
+      return "StompFrame[command=" + command + ", headers=" + headers + ", content= " + this.body + " bytes " + this.bytesBody;
    }
 
    public String asString()
    {
       String out = command + '\n';
-      for (Entry<String, Object> header : headers.entrySet())
+      for (Entry<String, String> header : headers.entrySet())
       {
          out += header.getKey() + ": " + header.getValue() + '\n';
       }
       out += '\n';
-      out += new String(content);
+      out += body;
       return out;
    }
-
  
    public HornetQBuffer toHornetQBuffer() throws Exception
    {
       if (buffer == null)
       {
-         buffer = HornetQBuffers.dynamicBuffer(content.length + 512);
+         if (bytesBody != null)
+         {
+            buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
+         }
+         else
+         {
+            buffer = HornetQBuffers.dynamicBuffer(512);
+         }
 
          StringBuffer head = new StringBuffer();
          head.append(command);
          head.append(Stomp.NEWLINE);
          // Output the headers.
-         for (Map.Entry<String, Object> header : headers.entrySet())
+         for (Map.Entry<String, String> header : headers.entrySet())
          {
             head.append(header.getKey());
             head.append(Stomp.Headers.SEPARATOR);
@@ -127,11 +138,132 @@
          head.append(Stomp.NEWLINE);
 
          buffer.writeBytes(head.toString().getBytes("UTF-8"));
-         buffer.writeBytes(content);
+         if (bytesBody != null)
+         {
+            buffer.writeBytes(bytesBody);
+         }
          buffer.writeBytes(END_OF_FRAME);
 
          size = buffer.writerIndex();
       }
       return buffer;
    }
+
+   public String getHeader(String key)
+   {
+      return headers.get(key);
+   }
+
+   public void addHeader(String key, String val)
+   {
+      headers.put(key, val);
+   }
+   
+   public Map<String, String> getHeadersMap()
+   {
+      return headers;
+   }
+   
+   public static class Header
+   {
+      public String key;
+      public String val;
+      
+      public Header(String key, String val)
+      {
+         this.key = key;
+         this.val = val;
+      }
+
+      public String getEscapedKey()
+      {
+         return escape(key);
+      }
+
+      public String getEscapedValue()
+      {
+         return escape(val);
+      }
+      
+      public static String escape(String str)
+      {
+         int len = str.length();
+         
+         char[] buffer = new char[2*len];
+         int iBuffer = 0;
+         for (int i = 0; i < len; i++)
+         {
+            char c = str.charAt(i);
+            if (c == '\n')
+            {
+               buffer[iBuffer++] = '\\';
+               buffer[iBuffer] = 'n';
+            }
+            else if (c == '\\')
+            {
+               buffer[iBuffer++] = '\\';
+               buffer[iBuffer] = '\\';
+            }
+            else if (c == ':')
+            {
+               buffer[iBuffer++] = '\\';
+               buffer[iBuffer] = ':';
+            }
+            else
+            {
+               buffer[iBuffer] = c;
+            }
+            iBuffer++;
+         }
+         
+         char[] total = new char[iBuffer];
+         System.arraycopy(buffer, 0, total, 0, iBuffer);
+         
+         return new String(total);
+      }
+   }
+
+   public void setBody(String body) throws UnsupportedEncodingException
+   {
+      this.body = body;
+      this.bytesBody = body.getBytes("UTF-8");
+   }
+
+   public boolean hasHeader(String key)
+   {
+      return headers.containsKey(key);
+   }
+
+   public String getBody() throws UnsupportedEncodingException
+   {
+      if (body == null)
+      {
+         if (bytesBody != null)
+         {
+            body = new String(bytesBody, "UTF-8");
+         }
+      }
+      return body;
+   }
+   
+   //Since 1.1, there is a content-type header that needs to take care of
+   public byte[] getBodyAsBytes() throws UnsupportedEncodingException
+   {
+      return bytesBody;
+   }
+
+   public boolean needsDisconnect()
+   {
+      return disconnect;
+   }
+
+   public void setByteBody(byte[] content)
+   {
+      this.bytesBody = content;
+   }
+
+   public void setNeedsDisconnect(boolean b)
+   {
+      disconnect = b;
+   }
 }

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompProtocolManager.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -13,22 +13,18 @@
 
 package org.hornetq.core.protocol.stomp;
 
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 import org.hornetq.api.core.HornetQBuffer;
 import org.hornetq.api.core.HornetQException;
 import org.hornetq.api.core.Interceptor;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.core.journal.IOAsyncTask;
 import org.hornetq.core.logging.Logger;
@@ -54,9 +50,6 @@
 
    private static final Logger log = Logger.getLogger(StompProtocolManager.class);
 
-   // TODO use same value than HornetQConnection
-   private static final String CONNECTION_ID_PROP = "__HQ_CID";
-
    // Attributes ----------------------------------------------------
 
    private final HornetQServer server;
@@ -70,36 +63,6 @@
 
    // Static --------------------------------------------------------
 
-   private static StompFrame createError(Exception e, StompFrame request)
-   {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      try
-      {
-         // Let the stomp client know about any protocol errors.
-         PrintWriter stream = new PrintWriter(new OutputStreamWriter(baos, "UTF-8"));
-         e.printStackTrace(stream);
-         stream.close();
-
-         Map<String, Object> headers = new HashMap<String, Object>();
-         headers.put(Stomp.Headers.Error.MESSAGE, e.getMessage());
-
-         final String receiptId = (String)request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED);
-         if (receiptId != null)
-         {
-            headers.put(Stomp.Headers.Response.RECEIPT_ID, receiptId);
-         }
-
-         byte[] payload = baos.toByteArray();
-         headers.put(Stomp.Headers.CONTENT_LENGTH, payload.length);
-         return new StompFrame(Stomp.Responses.ERROR, headers, payload);
-      }
-      catch (UnsupportedEncodingException ex)
-      {
-         log.warn("Unable to create ERROR frame from the exception", ex);
-         return null;
-      }
-   }
-
    // Constructors --------------------------------------------------
 
    public StompProtocolManager(final HornetQServer server, final List<Interceptor> interceptors)
@@ -114,7 +77,7 @@
    {
       StompConnection conn = new StompConnection(acceptorUsed, connection, this);
 
-      // Note that STOMP has no heartbeat, so if connection ttl is non zero, data must continue to be sent or connection
+      // Note that STOMP 1.0 has no heartbeat, so if connection ttl is non zero, data must continue to be sent or connection
       // will be timed out and closed!
 
       long ttl = server.getConfiguration().getConnectionTTLOverride();
@@ -144,19 +107,15 @@
 
    public void handleBuffer(final RemotingConnection connection, final HornetQBuffer buffer)
    {
-      long start = System.nanoTime();
       StompConnection conn = (StompConnection)connection;
       
       conn.setDataReceived();
       
       StompDecoder decoder = conn.getDecoder();
-      
-     // log.info("in handle");
 
       do
       {
          StompFrame request;
-         
          try
          {
             request = decoder.decode(buffer);
@@ -164,7 +123,6 @@
          catch (Exception e)
          {
             log.error("Failed to decode", e);
-
             return;
          }
          
@@ -175,93 +133,13 @@
 
          try
          {
-            String command = request.getCommand();
-
-            StompFrame response = null;
-
-            if (Stomp.Commands.CONNECT.equals(command))
-            {
-               response = onConnect(request, conn);
-            }
-            else if (Stomp.Commands.DISCONNECT.equals(command))
-            {
-               response = onDisconnect(request, conn);
-            }
-            else if (Stomp.Commands.SEND.equals(command))
-            {
-               response = onSend(request, conn);
-            }
-            else if (Stomp.Commands.SUBSCRIBE.equals(command))
-            {
-               response = onSubscribe(request, conn);
-            }
-            else if (Stomp.Commands.UNSUBSCRIBE.equals(command))
-            {
-               response = onUnsubscribe(request, conn);
-            }
-            else if (Stomp.Commands.ACK.equals(command))
-            {
-               response = onAck(request, conn);
-            }
-            else if (Stomp.Commands.BEGIN.equals(command))
-            {
-               response = onBegin(request, server, conn);
-            }
-            else if (Stomp.Commands.COMMIT.equals(command))
-            {
-               response = onCommit(request, conn);
-            }
-            else if (Stomp.Commands.ABORT.equals(command))
-            {
-               response = onAbort(request, conn);
-            }
-            else
-            {
-               log.error("Unsupported Stomp frame: " + request);
-               response = new StompFrame(Stomp.Responses.ERROR,
-                                         new HashMap<String, Object>(),
-                                         ("Unsupported frame: " + command).getBytes());
-            }
-
-            if (request.getHeaders().containsKey(Stomp.Headers.RECEIPT_REQUESTED))
-            {
-               if (response == null)
-               {
-                  Map<String, Object> h = new HashMap<String, Object>();
-                  response = new StompFrame(Stomp.Responses.RECEIPT, h);
-               }
-               response.getHeaders().put(Stomp.Headers.Response.RECEIPT_ID,
-                                         request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED));
-            }
-
-            if (response != null)
-            {
-               sendReply(conn, response);
-            }
-
-            if (Stomp.Commands.DISCONNECT.equals(command))
-            {
-               conn.destroy();
-            }
+            conn.handleFrame(request);
          }
-         catch (Exception e)
-         {
-            e.printStackTrace();
-            StompFrame error = createError(e, request);
-            if (error != null)
-            {
-               sendReply(conn, error);
-            }
-         }
          finally
          {
             server.getStorageManager().clearContext();
          }
       } while (decoder.hasBytes());
-      
-      long end = System.nanoTime();
-      
-     // log.info("handle took " + (end-start));
    }
 
    // Public --------------------------------------------------------
@@ -274,7 +152,7 @@
       }
       synchronized (connection)
       {
-         if (connection.isDestroyed() || !connection.isValid())
+         if (connection.isDestroyed())
          {
             log.warn("Connection closed " + connection);
             return;
@@ -282,8 +160,7 @@
 
          try
          {
-            HornetQBuffer buffer = frame.toHornetQBuffer();
-            connection.getTransportConnection().write(buffer, false, false);
+            connection.physicalSend(frame);
          }
          catch (Exception e)
          {
@@ -298,182 +175,8 @@
 
    // Private -------------------------------------------------------
 
-   private StompFrame onSubscribe(StompFrame frame, StompConnection connection) throws Exception
+   public StompSession getSession(StompConnection connection) throws Exception
    {
-      Map<String, Object> headers = frame.getHeaders();
-      String destination = (String)headers.get(Stomp.Headers.Subscribe.DESTINATION);
-      String selector = (String)headers.get(Stomp.Headers.Subscribe.SELECTOR);
-      String ack = (String)headers.get(Stomp.Headers.Subscribe.ACK_MODE);
-      String id = (String)headers.get(Stomp.Headers.Subscribe.ID);
-      String durableSubscriptionName = (String)headers.get(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
-      boolean noLocal = false;
-      if (headers.containsKey(Stomp.Headers.Subscribe.NO_LOCAL))
-      {
-         noLocal = Boolean.parseBoolean((String)headers.get(Stomp.Headers.Subscribe.NO_LOCAL));
-      }
-      if (noLocal)
-      {
-         String noLocalFilter = CONNECTION_ID_PROP + " <> '" + connection.getID().toString() + "'";
-         if (selector == null)
-         {
-            selector = noLocalFilter;
-         }
-         else
-         {
-            selector += " AND " + noLocalFilter;
-         }
-      }
-      if (ack == null)
-      {
-         ack = Stomp.Headers.Subscribe.AckModeValues.AUTO;
-      }
-      String subscriptionID = null;
-      if (id != null)
-      {
-         subscriptionID = id;
-      }
-      else
-      {
-         if (destination == null)
-         {
-            throw new StompException("Client must set destination or id header to a SUBSCRIBE command");
-         }
-         subscriptionID = "subscription/" + destination;
-      }
-      StompSession stompSession = getSession(connection);
-      stompSession.setNoLocal(noLocal);
-      if (stompSession.containsSubscription(subscriptionID))
-      {
-         throw new StompException("There already is a subscription for: " + subscriptionID +
-                                  ". Either use unique subscription IDs or do not create multiple subscriptions for the same destination");
-      }
-      long consumerID = server.getStorageManager().generateUniqueID();
-      String clientID = (connection.getClientID() != null) ? connection.getClientID() : null;
-      stompSession.addSubscription(consumerID,
-                                   subscriptionID,
-                                   clientID,
-                                   durableSubscriptionName,
-                                   destination,
-                                   selector,
-                                   ack);
-
-      return null;
-   }
-
-   private StompFrame onUnsubscribe(StompFrame frame, StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String destination = (String)headers.get(Stomp.Headers.Unsubscribe.DESTINATION);
-      String id = (String)headers.get(Stomp.Headers.Unsubscribe.ID);
-
-      String subscriptionID = null;
-      if (id != null)
-      {
-         subscriptionID = id;
-      }
-      else
-      {
-         if (destination == null)
-         {
-            throw new StompException("Must specify the subscription's id or the destination you are unsubscribing from");
-         }
-         subscriptionID = "subscription/" + destination;
-      }
-
-      StompSession stompSession = getSession(connection);
-      boolean unsubscribed = stompSession.unsubscribe(subscriptionID);
-      if (!unsubscribed)
-      {
-         throw new StompException("Cannot unsubscribe as no subscription exists for id: " + subscriptionID);
-      }
-      return null;
-   }
-
-   private StompFrame onAck(StompFrame frame, StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String messageID = (String)headers.get(Stomp.Headers.Ack.MESSAGE_ID);
-      String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
-      StompSession stompSession = null;
-      if (txID != null)
-      {
-         log.warn("Transactional acknowledgement is not supported");
-      }
-      stompSession = getSession(connection);
-      stompSession.acknowledge(messageID);
-
-      return null;
-   }
-
-   private StompFrame onBegin(StompFrame frame, HornetQServer server, StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         throw new StompException("transaction header is mandatory to BEGIN a transaction");
-      }
-      if (transactedSessions.containsKey(txID))
-      {
-         throw new StompException("Transaction already started: " + txID);
-      }
-      // create the transacted session
-      getTransactedSession(connection, txID);
-
-      return null;
-   }
-
-   private StompFrame onCommit(StompFrame frame, StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         throw new StompException("transaction header is mandatory to COMMIT a transaction");
-      }
-
-      StompSession session = getTransactedSession(connection, txID);
-      if (session == null)
-      {
-         throw new StompException("No transaction started: " + txID);
-      }
-      transactedSessions.remove(txID);
-      session.getSession().commit();
-
-      return null;
-   }
-
-   private StompFrame onAbort(StompFrame frame, StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String txID = (String)headers.get(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         throw new StompException("transaction header is mandatory to ABORT a transaction");
-      }
-
-      StompSession session = getTransactedSession(connection, txID);
-
-      if (session == null)
-      {
-         throw new StompException("No transaction started: " + txID);
-      }
-      transactedSessions.remove(txID);
-      session.getSession().rollback(false);
-
-      return null;
-   }
-
-   private void checkConnected(StompConnection connection) throws StompException
-   {
-      if (!connection.isValid())
-      {
-         throw new StompException("Not connected");
-      }
-   }
-
-   private StompSession getSession(StompConnection connection) throws Exception
-   {
       StompSession stompSession = sessions.get(connection.getID());
       if (stompSession == null)
       {
@@ -498,7 +201,7 @@
       return stompSession;
    }
 
-   private StompSession getTransactedSession(StompConnection connection, String txID) throws Exception
+   public StompSession getTransactedSession(StompConnection connection, String txID) throws Exception
    {
       StompSession stompSession = transactedSessions.get(txID);
       if (stompSession == null)
@@ -523,84 +226,6 @@
       return stompSession;
    }
 
-   private StompFrame onDisconnect(StompFrame frame, StompConnection connection) throws Exception
-   {
-      cleanup(connection);
-      return null;
-   }
-   
-   private StompFrame onSend(StompFrame frame, StompConnection connection) throws Exception
-   {
-      checkConnected(connection);
-      Map<String, Object> headers = frame.getHeaders();
-      String destination = (String)headers.remove(Stomp.Headers.Send.DESTINATION);
-      String txID = (String)headers.remove(Stomp.Headers.TRANSACTION);
-      long timestamp = System.currentTimeMillis();
-
-      ServerMessageImpl message = new ServerMessageImpl(server.getStorageManager().generateUniqueID(), 512);
-      message.setTimestamp(timestamp);
-      message.setAddress(SimpleString.toSimpleString(destination));
-      StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
-      if (headers.containsKey(Stomp.Headers.CONTENT_LENGTH))
-      {
-         message.setType(Message.BYTES_TYPE);
-         message.getBodyBuffer().writeBytes(frame.getContent());
-      }
-      else
-      {
-         message.setType(Message.TEXT_TYPE);
-         String text = new String(frame.getContent(), "UTF-8");
-         message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
-      }
-
-      StompSession stompSession = null;
-      if (txID == null)
-      {
-         stompSession = getSession(connection);
-      }
-      else
-      {
-         stompSession = getTransactedSession(connection, txID);
-      }
-      if (stompSession.isNoLocal())
-      {
-         message.putStringProperty(CONNECTION_ID_PROP, connection.getID().toString());
-      }
-      stompSession.getSession().send(message, true);           
-      
-      return null;
-   }
-
-   private StompFrame onConnect(StompFrame frame, final StompConnection connection) throws Exception
-   {
-      Map<String, Object> headers = frame.getHeaders();
-      String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
-      String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
-      String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
-      String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
-      HornetQSecurityManager sm = server.getSecurityManager();
-      
-      // The sm will be null case security is not enabled...
-      if (sm != null)
-      {
-         sm.validateUser(login, passcode);
-      }
-
-      connection.setLogin(login);
-      connection.setPasscode(passcode);
-      connection.setClientID(clientID);
-      connection.setValid(true);
-
-      HashMap<String, Object> h = new HashMap<String, Object>();
-      h.put(Stomp.Headers.Connected.SESSION, connection.getID());
-      if (requestID != null)
-      {
-         h.put(Stomp.Headers.Connected.RESPONSE_ID, requestID);
-      }
-      return new StompFrame(Stomp.Responses.CONNECTED, h);
-   }
-
    public void cleanup(final StompConnection connection)
    {
       connection.setValid(false);
@@ -648,15 +273,18 @@
       });
    }
 
-   private void sendReply(final StompConnection connection, final StompFrame frame)
+   public void sendReply(final StompConnection connection, final StompFrame frame)
    {
       server.getStorageManager().afterCompleteOperations(new IOAsyncTask()
       {
          public void onError(final int errorCode, final String errorMessage)
          {
             log.warn("Error processing IOCallback code = " + errorCode + " message = " + errorMessage);
+            
+            HornetQStompException e = new HornetQStompException("Error sending reply",
+                  new HornetQException(errorCode, errorMessage));
 
-            StompFrame error = createError(new HornetQException(errorCode, errorMessage), frame);
+            StompFrame error = e.getFrame();
             send(connection, error);
          }
 
@@ -666,5 +294,108 @@
          }
       });
    }
+
+   public String getSupportedVersionsAsString()
+   {
+      return "v1.0 v1.1";
+   }
+
+   public String getVirtualHostName()
+   {
+      return "hornetq";
+   }
+
+   public boolean validateUser(String login, String passcode)
+   {
+      boolean validated = true;
+      
+      HornetQSecurityManager sm = server.getSecurityManager();
+      
+      // The sm will be null case security is not enabled...
+      if (sm != null)
+      {
+         validated = sm.validateUser(login, passcode);
+      }
+      
+      return validated;
+   }
+
+   public ServerMessageImpl createServerMessage()
+   {
+      return new ServerMessageImpl(server.getStorageManager().generateUniqueID(), 512);
+   }
+
+   public void commitTransaction(StompConnection connection, String txID) throws Exception
+   {
+      StompSession session = getTransactedSession(connection, txID);
+      if (session == null)
+      {
+         throw new HornetQStompException("No transaction started: " + txID);
+      }
+      transactedSessions.remove(txID);
+      session.getSession().commit();
+   }
+
+   public void abortTransaction(StompConnection connection, String txID) throws Exception
+   {
+      StompSession session = getTransactedSession(connection, txID);
+      if (session == null)
+      {
+         throw new HornetQStompException("No transaction started: " + txID);
+      }
+      transactedSessions.remove(txID);
+      session.getSession().rollback(false);
+   }
    // Inner classes -------------------------------------------------
+
+   public void createSubscription(StompConnection connection,
+         String subscriptionID, String durableSubscriptionName,
+         String destination, String selector, String ack, boolean noLocal) throws Exception
+   {
+      StompSession stompSession = getSession(connection);
+      stompSession.setNoLocal(noLocal);
+      if (stompSession.containsSubscription(subscriptionID))
+      {
+         throw new HornetQStompException("There already is a subscription for: " + subscriptionID +
+                                  ". Either use unique subscription IDs or do not create multiple subscriptions for the same destination");
+      }
+      long consumerID = server.getStorageManager().generateUniqueID();
+      String clientID = (connection.getClientID() != null) ? connection.getClientID() : null;
+      stompSession.addSubscription(consumerID,
+                                   subscriptionID,
+                                   clientID,
+                                   durableSubscriptionName,
+                                   destination,
+                                   selector,
+                                   ack);
+   }
+
+   public void unsubscribe(StompConnection connection,
+         String subscriptionID) throws Exception
+   {
+      StompSession stompSession = getSession(connection);
+      boolean unsubscribed = stompSession.unsubscribe(subscriptionID);
+      if (!unsubscribed)
+      {
+         throw new HornetQStompException("Cannot unsubscribe as no subscription exists for id: " + subscriptionID);
+      }
+   }
+
+   public void acknowledge(StompConnection connection, String messageID, String subscriptionID) throws Exception
+   {
+      StompSession stompSession = getSession(connection);
+      stompSession.acknowledge(messageID, subscriptionID);
+   }
+
+   public void beginTransaction(StompConnection connection, String txID) throws Exception
+   {
+      log.error("-------------------------------begin tx: " + txID);
+      if (transactedSessions.containsKey(txID))
+      {
+         log.error("------------------------------Error, tx already exist!");
+         throw new HornetQStompException(connection, "Transaction already started: " + txID);
+      }
+      // create the transacted session
+      getTransactedSession(connection, txID);
+   }
 }

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSession.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -43,7 +43,7 @@
  *
  * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
  */
-class StompSession implements SessionCallback
+public class StompSession implements SessionCallback
 {
    private static final Logger log = Logger.getLogger(StompSession.class);
 
@@ -94,11 +94,11 @@
       {
          StompSubscription subscription = subscriptions.get(consumerID);
 
-         StompFrame frame = createFrame(serverMessage, deliveryCount, subscription);
+         StompFrame frame = connection.createStompMessage(serverMessage, subscription, deliveryCount);
 
          int length = frame.getEncodedSize();
 
-         if (subscription.isAutoACK())
+         if (subscription.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.AUTO))
          {
             session.acknowledge(consumerID, serverMessage.getMessageID());
             session.commit();
@@ -122,57 +122,6 @@
 
    }
 
-   /**
-    * @param serverMessage
-    * @param deliveryCount
-    * @param subscription
-    * @return
-    * @throws UnsupportedEncodingException
-    * @throws Exception
-    */
-   private StompFrame createFrame(ServerMessage serverMessage, int deliveryCount, StompSubscription subscription) throws UnsupportedEncodingException,
-                                                                                                                 Exception
-   {
-      synchronized (serverMessage)
-      {
-         Map<String, Object> headers = new HashMap<String, Object>();
-         headers.put(Stomp.Headers.Message.DESTINATION, serverMessage.getAddress().toString());
-         if (subscription.getID() != null)
-         {
-            headers.put(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
-         }
-         
-         HornetQBuffer buffer = serverMessage.getBodyBuffer();
-   
-         int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
-                                                                 : serverMessage.getEndOfBodyPosition();
-         int size = bodyPos - buffer.readerIndex();
-         buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
-         byte[] data = new byte[size];
-         if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) || serverMessage.getType() == Message.BYTES_TYPE)
-         {
-            headers.put(Headers.CONTENT_LENGTH, data.length);
-            buffer.readBytes(data);
-         }
-         else
-         {
-            SimpleString text = buffer.readNullableSimpleString();
-            if (text != null)
-            {
-               data = text.toString().getBytes("UTF-8");
-            }
-            else
-            {
-               data = new byte[0];
-            }
-         }
-         serverMessage.getBodyBuffer().resetReaderIndex();
-         StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE, headers, data);
-         StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame, deliveryCount);
-         return frame;
-      }
-   }
-
    public int sendLargeMessageContinuation(long consumerID, byte[] body, boolean continues, boolean requiresResponse)
    {
       return 0;
@@ -197,24 +146,44 @@
       connection.getTransportConnection().removeReadyListener(listener);
    }
 
-   public void acknowledge(String messageID) throws Exception
+   public void acknowledge(String messageID, String subscriptionID) throws Exception
    {
       long id = Long.parseLong(messageID);
       Pair<Long, Integer> pair = messagesToAck.remove(id);
 
-      if (pair != null)
+      if (pair == null)
       {
-         long consumerID = pair.getA();
-         int credits = pair.getB();
-   
-         if (this.consumerCredits != -1)
+         throw new HornetQStompException("failed to ack because no message with id: " + id);
+      }
+
+      long consumerID = pair.getA();
+      int credits = pair.getB();
+
+      StompSubscription sub = subscriptions.get(consumerID);
+
+      if (subscriptionID != null)
+      {
+         if (!sub.getID().equals(subscriptionID))
          {
-            session.receiveConsumerCredits(consumerID, credits);
+            throw new HornetQStompException("subscription id " + subscriptionID + " does not match " + sub.getID());
          }
-         
+      }
+
+      if (this.consumerCredits != -1)
+      {
+         session.receiveConsumerCredits(consumerID, credits);
+      }
+      
+      if (sub.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.CLIENT_INDIVIDUAL))
+      {
+         session.individualAcknowledge(consumerID, id);
+      }
+      else
+      {
          session.acknowledge(consumerID, id);
-         session.commit();
       }
+
+      session.commit();
    }
 
    public void addSubscription(long consumerID,
@@ -250,10 +219,10 @@
       }
       session.createConsumer(consumerID, queue, SimpleString.toSimpleString(selector), false);
 
-      StompSubscription subscription = new StompSubscription(subscriptionID, ack.equals(Stomp.Headers.Subscribe.AckModeValues.AUTO));
+      StompSubscription subscription = new StompSubscription(subscriptionID, ack);
       subscriptions.put(consumerID, subscription);
       
-      if (subscription.isAutoACK())
+      if (subscription.getAck().equals(Stomp.Headers.Subscribe.AckModeValues.AUTO))
       {
          session.receiveConsumerCredits(consumerID, -1);
       }
@@ -317,4 +286,4 @@
    {
       this.noLocal = noLocal;
    }
-}
\ No newline at end of file
+}

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompSubscription.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -28,23 +28,23 @@
 
    private final String subID;
    
-   private final boolean autoACK;
+   private final String ack;
 
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
 
-   public StompSubscription(String subID, boolean ack)
+   public StompSubscription(String subID, String ack)
    {
       this.subID = subID;
-      this.autoACK = ack;
+      this.ack = ack;
    }
 
    // Public --------------------------------------------------------
 
-   public boolean isAutoACK()
+   public String getAck()
    {
-      return autoACK;
+      return ack;
    }
 
    public String getID()
@@ -55,7 +55,7 @@
    @Override
    public String toString()
    {
-      return "StompSubscription[id=" + subID + ", autoACK=" + autoACK + "]";
+      return "StompSubscription[id=" + subID + ", ack=" + ack + "]";
    }
    
    // Package protected ---------------------------------------------

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompUtils.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -32,7 +32,7 @@
  *
  *
  */
-class StompUtils
+public class StompUtils
 {
    // Constants -----------------------------------------------------
    private static final String DEFAULT_MESSAGE_PRIORITY= "4";
@@ -46,8 +46,8 @@
 
    public static void copyStandardHeadersFromFrameToMessage(StompFrame frame, ServerMessageImpl msg) throws Exception
    {
-      Map<String, Object> headers = new HashMap<String, Object>(frame.getHeaders());
-
+      Map<String, String> headers = new HashMap<String, String>(frame.getHeadersMap());
+      
       String priority = (String)headers.remove(Stomp.Headers.Send.PRIORITY);
       if (priority != null)
       {
@@ -82,10 +82,10 @@
       }
       
       // now the general headers
-      for (Iterator<Map.Entry<String, Object>> iter = headers.entrySet().iterator(); iter.hasNext();)
+      for (Iterator<Map.Entry<String, String>> iter = headers.entrySet().iterator(); iter.hasNext();)
       {
-         Map.Entry<String, Object> entry = iter.next();
-         String name = (String)entry.getKey();
+         Map.Entry<String, String> entry = iter.next();
+         String name = entry.getKey();
          Object value = entry.getValue();
          msg.putObjectProperty(name, value);
       }
@@ -93,41 +93,42 @@
 
    public static void copyStandardHeadersFromMessageToFrame(MessageInternal message, StompFrame command, int deliveryCount) throws Exception
    {
-      final Map<String, Object> headers = command.getHeaders();
-      headers.put(Stomp.Headers.Message.DESTINATION, message.getAddress().toString());
-      headers.put(Stomp.Headers.Message.MESSAGE_ID, message.getMessageID());
+      command.addHeader(Stomp.Headers.Message.MESSAGE_ID, String.valueOf(message.getMessageID()));
+      command.addHeader(Stomp.Headers.Message.DESTINATION, message.getAddress().toString());
 
       if (message.getObjectProperty("JMSCorrelationID") != null)
       {
-         headers.put(Stomp.Headers.Message.CORRELATION_ID, message.getObjectProperty("JMSCorrelationID"));
+         command.addHeader(Stomp.Headers.Message.CORRELATION_ID, message.getObjectProperty("JMSCorrelationID").toString());
       }
-      headers.put(Stomp.Headers.Message.EXPIRATION_TIME, "" + message.getExpiration());
-      headers.put(Stomp.Headers.Message.REDELIVERED, deliveryCount > 1);
-      headers.put(Stomp.Headers.Message.PRORITY, "" + message.getPriority());
+      command.addHeader(Stomp.Headers.Message.EXPIRATION_TIME, "" + message.getExpiration());
+      command.addHeader(Stomp.Headers.Message.REDELIVERED, String.valueOf(deliveryCount > 1));
+      command.addHeader(Stomp.Headers.Message.PRORITY, "" + message.getPriority());
       if (message.getStringProperty(ClientMessageImpl.REPLYTO_HEADER_NAME) != null)
       {
-         headers.put(Stomp.Headers.Message.REPLY_TO,
+         command.addHeader(Stomp.Headers.Message.REPLY_TO,
                      message.getStringProperty(ClientMessageImpl.REPLYTO_HEADER_NAME));
       }
-      headers.put(Stomp.Headers.Message.TIMESTAMP, "" + message.getTimestamp());
+      command.addHeader(Stomp.Headers.Message.TIMESTAMP, "" + message.getTimestamp());
 
       if (message.getObjectProperty("JMSType") != null)
       {
-         headers.put(Stomp.Headers.Message.TYPE, message.getObjectProperty("JMSType"));
+         command.addHeader(Stomp.Headers.Message.TYPE, message.getObjectProperty("JMSType").toString());
       }
 
       // now lets add all the message headers
       Set<SimpleString> names = message.getPropertyNames();
       for (SimpleString name : names)
       {
+         String value = name.toString();
          if (name.equals(ClientMessageImpl.REPLYTO_HEADER_NAME) ||
-                  name.toString().equals("JMSType") ||
-                  name.toString().equals("JMSCorrelationID"))
+                  value.equals("JMSType") ||
+                  value.equals("JMSCorrelationID") ||
+                  value.equals(Stomp.Headers.Message.DESTINATION))
          {
             continue;
          }
 
-         headers.put(name.toString(), message.getObjectProperty(name));
+         command.addHeader(name.toString(), message.getObjectProperty(name).toString());
       }
    }
    // Constructors --------------------------------------------------

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/StompVersions.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp;
+
+/**
+ * Stomp Spec Versions
+ *
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public enum StompVersions
+{
+   V1_0,
+   V1_1;
+
+   public String toString()
+   {
+	   if (this == V1_0)
+      {
+         return "1.0";
+      }
+      return "1.1";
+   }
+}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/VersionedStompFrameHandler.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp;
+
+import java.io.UnsupportedEncodingException;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.protocol.stomp.v10.StompFrameHandlerV10;
+import org.hornetq.core.protocol.stomp.v11.StompFrameHandlerV11;
+import org.hornetq.core.server.ServerMessage;
+
+/**
+ *
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public abstract class VersionedStompFrameHandler
+{
+   private static final Logger log = Logger.getLogger(VersionedStompFrameHandler.class);
+
+   protected StompConnection connection;
+   
+   public static VersionedStompFrameHandler getHandler(StompConnection connection, StompVersions version)
+   {
+      if (version == StompVersions.V1_0)
+      {
+         return new StompFrameHandlerV10(connection);
+      }
+      if (version == StompVersions.V1_1)
+      {
+         return new StompFrameHandlerV11(connection);
+      }
+      return null;
+   }
+
+   public StompFrame handleFrame(StompFrame request)
+   {
+      StompFrame response = null;
+      
+      if (Stomp.Commands.SEND.equals(request.getCommand()))
+      {
+         response = onSend(request);
+      }
+      else if (Stomp.Commands.ACK.equals(request.getCommand()))
+      {
+         response = onAck(request);
+      }
+      else if (Stomp.Commands.NACK.equals(request.getCommand()))
+      {
+         response = onNack(request);
+      }
+      else if (Stomp.Commands.BEGIN.equals(request.getCommand()))
+      {
+         response = onBegin(request);
+      }
+      else if (Stomp.Commands.COMMIT.equals(request.getCommand()))
+      {
+         response = onCommit(request);
+      }
+      else if (Stomp.Commands.ABORT.equals(request.getCommand()))
+      {
+         response = onAbort(request);
+      }
+      else if (Stomp.Commands.SUBSCRIBE.equals(request.getCommand()))
+      {
+         response = onSubscribe(request);
+      }
+      else if (Stomp.Commands.UNSUBSCRIBE.equals(request.getCommand()))
+      {
+         response = onUnsubscribe(request);
+      }
+      else if (Stomp.Commands.CONNECT.equals(request.getCommand()))
+      {
+         response = onConnect(request);
+      }
+      else if (Stomp.Commands.STOMP.equals(request.getCommand()))
+      {
+         response = onStomp(request);
+      }
+      else if (Stomp.Commands.DISCONNECT.equals(request.getCommand()))
+      {
+         response = onDisconnect(request);
+      }
+      else
+      {
+         response = onUnknown(request.getCommand());
+      }
+
+      if (response == null)
+      {
+         response = postprocess(request);
+      }
+      else
+      {
+         if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+         {
+            response.addHeader(Stomp.Headers.Response.RECEIPT_ID, request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+         }
+      }
+      
+      return response;
+   }
+
+   public abstract StompFrame onConnect(StompFrame frame);
+   public abstract StompFrame onDisconnect(StompFrame frame);
+   public abstract StompFrame onSend(StompFrame frame);
+   public abstract StompFrame onAck(StompFrame request);
+   public abstract StompFrame onBegin(StompFrame frame);
+   public abstract StompFrame onCommit(StompFrame request);
+   public abstract StompFrame onAbort(StompFrame request);
+   public abstract StompFrame onSubscribe(StompFrame request);
+   public abstract StompFrame onUnsubscribe(StompFrame request);
+   public abstract StompFrame onStomp(StompFrame request);
+   public abstract StompFrame onNack(StompFrame request);
+   
+   public StompFrame onUnknown(String command)
+   {
+      StompFrame response = new HornetQStompException("Unsupported command " + command).getFrame();
+      return response;
+   }
+   
+   public StompFrame handleReceipt(String receiptID)
+   {
+      StompFrame receipt = new StompFrame(Stomp.Responses.RECEIPT);
+      receipt.addHeader(Stomp.Headers.Response.RECEIPT_ID, receiptID);
+      
+      return receipt;
+   }
+   
+   public abstract StompFrame postprocess(StompFrame request);
+
+   public abstract StompFrame createMessageFrame(ServerMessage serverMessage,
+         StompSubscription subscription, int deliveryCount) throws Exception;
+
+   public abstract StompFrame createStompFrame(String command);
+
+   public abstract StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws HornetQStompException;
+
+}

Deleted: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java
===================================================================
--- branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,415 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.core.protocol.stomp.v10;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.impl.MessageImpl;
-import org.hornetq.core.protocol.stomp.FrameEventListener;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompConnection;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompSubscription;
-import org.hornetq.core.protocol.stomp.StompUtils;
-import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
-import org.hornetq.core.protocol.stomp.Stomp.Headers;
-import org.hornetq.core.server.ServerMessage;
-import org.hornetq.core.server.impl.ServerMessageImpl;
-import org.hornetq.utils.DataConstants;
-
-/**
-*
-* @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
-*/
-public class StompFrameHandlerV10 extends VersionedStompFrameHandler implements FrameEventListener
-{
-   private static final Logger log = Logger.getLogger(StompFrameHandlerV10.class);
-   
-   public StompFrameHandlerV10(StompConnection connection)
-   {
-      this.connection = connection;
-      connection.addStompEventListener(this);
-   }
-
-   @Override
-   public StompFrame onConnect(StompFrame frame)
-   {
-      StompFrame response = null;
-      Map<String, String> headers = frame.getHeadersMap();
-      String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
-      String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
-      String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
-      String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
-      if (connection.validateUser(login, passcode))
-      {
-         connection.setClientID(clientID);
-         connection.setValid(true);
-         
-         response = new StompFrameV10(Stomp.Responses.CONNECTED);
-         
-         if (frame.hasHeader(Stomp.Headers.ACCEPT_VERSION))
-         {
-            response.addHeader(Stomp.Headers.Connected.VERSION, "1.0");
-         }
-         
-         response.addHeader(Stomp.Headers.Connected.SESSION, connection.getID().toString());
-         
-         if (requestID != null)
-         {
-            response.addHeader(Stomp.Headers.Connected.RESPONSE_ID, requestID);
-         }
-      }
-      else
-      {
-         //not valid
-         response = new StompFrameV10(Stomp.Responses.ERROR);
-         response.addHeader(Stomp.Headers.Error.MESSAGE, "Failed to connect");
-         try
-         {
-            response.setBody("The login account is not valid.");
-         }
-         catch (UnsupportedEncodingException e)
-         {
-            log.error("Encoding problem", e);
-         }
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onDisconnect(StompFrame frame)
-   {
-      return null;
-   }
-
-   @Override
-   public StompFrame onSend(StompFrame frame)
-   {
-      StompFrame response = null;
-      try
-      {
-         connection.validate();
-         String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
-         String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-
-         long timestamp = System.currentTimeMillis();
-
-         ServerMessageImpl message = connection.createServerMessage();
-         message.setTimestamp(timestamp);
-         message.setAddress(SimpleString.toSimpleString(destination));
-         StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
-         if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
-         {
-            message.setType(Message.BYTES_TYPE);
-            message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
-         }
-         else
-         {
-            message.setType(Message.TEXT_TYPE);
-            String text = frame.getBody();
-            message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
-         }
-
-         connection.sendServerMessage(message, txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      catch (Exception e)
-      {
-         response = new HornetQStompException("Error handling send", e).getFrame();
-      }
-
-      return response;
-   }
-
-   @Override
-   public StompFrame onBegin(StompFrame frame)
-   {
-      StompFrame response = null;
-      String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         response = new HornetQStompException("Need a transaction id to begin").getFrame();
-      }
-      else
-      {
-         try
-         {
-            connection.beginTransaction(txID);
-         }
-         catch (HornetQStompException e)
-         {
-            response = e.getFrame();
-         }
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onCommit(StompFrame request)
-   {
-      StompFrame response = null;
-      
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         response = new HornetQStompException("transaction header is mandatory to COMMIT a transaction").getFrame();
-         return response;
-      }
-
-      try
-      {
-         connection.commitTransaction(txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onAbort(StompFrame request)
-   {
-      StompFrame response = null;
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
-      if (txID == null)
-      {
-         response = new HornetQStompException("transaction header is mandatory to ABORT a transaction").getFrame();
-         return response;
-      }
-      
-      try
-      {
-         connection.abortTransaction(txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      
-      return response;
-   }
-
-   @Override
-   public StompFrame onSubscribe(StompFrame request)
-   {
-      StompFrame response = null;
-      String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
-      
-      String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
-      String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
-      String id = request.getHeader(Stomp.Headers.Subscribe.ID);
-      String durableSubscriptionName = request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
-      boolean noLocal = false;
-      
-      if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
-      {
-         noLocal = Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
-      }
-      
-      try
-      {
-         connection.subscribe(destination, selector, ack, id, durableSubscriptionName, noLocal);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      
-      return response;
-   }
-
-   @Override
-   public StompFrame onUnsubscribe(StompFrame request)
-   {
-      StompFrame response = null;
-      String destination = request.getHeader(Stomp.Headers.Unsubscribe.DESTINATION);
-      String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
-
-      String subscriptionID = null;
-      if (id != null)
-      {
-         subscriptionID = id;
-      }
-      else
-      {
-         if (destination == null)
-         {
-            response = new HornetQStompException("Must specify the subscription's id or " +
-            		"the destination you are unsubscribing from").getFrame();
-            return response;
-         }
-         subscriptionID = "subscription/" + destination;
-      }
-      
-      try
-      {
-         connection.unsubscribe(subscriptionID);
-      }
-      catch (HornetQStompException e)
-      {
-         return e.getFrame();
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onAck(StompFrame request)
-   {
-      StompFrame response = null;
-      
-      String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
-      if (txID != null)
-      {
-         log.warn("Transactional acknowledgement is not supported");
-      }
-      
-      try
-      {
-         connection.acknowledge(messageID, null);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-
-      return response;
-   }
-
-   @Override
-   public StompFrame onStomp(StompFrame request)
-   {
-      return onUnknown(request.getCommand());
-   }
-
-   @Override
-   public StompFrame onNack(StompFrame request)
-   {
-      return onUnknown(request.getCommand());
-   }
-
-   @Override
-   public StompFrame createMessageFrame(ServerMessage serverMessage,
-         StompSubscription subscription, int deliveryCount) throws Exception
-   {
-      StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE);
-      
-      if (subscription.getID() != null)
-      {
-         frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
-      }
-
-      synchronized(serverMessage)
-      {
-
-      HornetQBuffer buffer = serverMessage.getBodyBuffer();
-
-      int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
-                                                              : serverMessage.getEndOfBodyPosition();
-      int size = bodyPos - buffer.readerIndex();
-      buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
-      byte[] data = new byte[size];
-      
-      if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) || serverMessage.getType() == Message.BYTES_TYPE)
-      {
-         frame.addHeader(Headers.CONTENT_LENGTH, String.valueOf(data.length));
-         buffer.readBytes(data);
-      }
-      else
-      {
-         SimpleString text = buffer.readNullableSimpleString();
-         if (text != null)
-         {
-            data = text.toString().getBytes("UTF-8");
-         }
-         else
-         {
-            data = new byte[0];
-         }
-      }
-      frame.setByteBody(data);
-
-      serverMessage.getBodyBuffer().resetReaderIndex();
-
-      StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame, deliveryCount);
-      }
-      
-      return frame;
-
-   }
-
-   @Override
-   public StompFrame createStompFrame(String command)
-   {
-      return new StompFrameV10(command);
-   }
-
-   public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws HornetQStompException
-   {
-      return decoder.defaultDecode(buffer);
-   }
-
-   @Override
-   public void replySent(StompFrame reply)
-   {
-      if (reply.needsDisconnect())
-      {
-         connection.destroy();
-      }
-   }
-
-   @Override
-   public void requestAccepted(StompFrame request)
-   {
-      // TODO Auto-generated method stub
-      
-   }
-   
-   @Override
-   public StompFrame postprocess(StompFrame request)
-   {
-      StompFrame response = null;
-      if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
-      {
-         response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
-         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
-         {
-            response.setNeedsDisconnect(true);
-         }
-      }
-      else
-      {
-         //request null, disconnect if so.
-         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
-         {
-            this.connection.disconnect();
-         }         
-      }
-      return response;
-   }
-
-}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameHandlerV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp.v10;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.protocol.stomp.FrameEventListener;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompConnection;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompSubscription;
+import org.hornetq.core.protocol.stomp.StompUtils;
+import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
+import org.hornetq.core.protocol.stomp.Stomp.Headers;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
+import org.hornetq.utils.DataConstants;
+
+/**
+*
+* @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+*/
+public class StompFrameHandlerV10 extends VersionedStompFrameHandler implements FrameEventListener
+{
+   private static final Logger log = Logger.getLogger(StompFrameHandlerV10.class);
+   
+   public StompFrameHandlerV10(StompConnection connection)
+   {
+      this.connection = connection;
+      connection.addStompEventListener(this);
+   }
+
+   @Override
+   public StompFrame onConnect(StompFrame frame)
+   {
+      StompFrame response = null;
+      Map<String, String> headers = frame.getHeadersMap();
+      String login = (String)headers.get(Stomp.Headers.Connect.LOGIN);
+      String passcode = (String)headers.get(Stomp.Headers.Connect.PASSCODE);
+      String clientID = (String)headers.get(Stomp.Headers.Connect.CLIENT_ID);
+      String requestID = (String)headers.get(Stomp.Headers.Connect.REQUEST_ID);
+
+      if (connection.validateUser(login, passcode))
+      {
+         connection.setClientID(clientID);
+         connection.setValid(true);
+         
+         response = new StompFrameV10(Stomp.Responses.CONNECTED);
+         
+         if (frame.hasHeader(Stomp.Headers.ACCEPT_VERSION))
+         {
+            response.addHeader(Stomp.Headers.Connected.VERSION, "1.0");
+         }
+         
+         response.addHeader(Stomp.Headers.Connected.SESSION, connection.getID().toString());
+         
+         if (requestID != null)
+         {
+            response.addHeader(Stomp.Headers.Connected.RESPONSE_ID, requestID);
+         }
+      }
+      else
+      {
+         //not valid
+         response = new StompFrameV10(Stomp.Responses.ERROR);
+         response.addHeader(Stomp.Headers.Error.MESSAGE, "Failed to connect");
+         try
+         {
+            response.setBody("The login account is not valid.");
+         }
+         catch (UnsupportedEncodingException e)
+         {
+            log.error("Encoding problem", e);
+         }
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onDisconnect(StompFrame frame)
+   {
+      return null;
+   }
+
+   @Override
+   public StompFrame onSend(StompFrame frame)
+   {
+      StompFrame response = null;
+      try
+      {
+         connection.validate();
+         String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
+         String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+
+         long timestamp = System.currentTimeMillis();
+
+         ServerMessageImpl message = connection.createServerMessage();
+         message.setTimestamp(timestamp);
+         message.setAddress(SimpleString.toSimpleString(destination));
+         StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
+         if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
+         {
+            message.setType(Message.BYTES_TYPE);
+            message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
+         }
+         else
+         {
+            message.setType(Message.TEXT_TYPE);
+            String text = frame.getBody();
+            message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
+         }
+
+         connection.sendServerMessage(message, txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      catch (Exception e)
+      {
+         response = new HornetQStompException("Error handling send", e).getFrame();
+      }
+
+      return response;
+   }
+
+   @Override
+   public StompFrame onBegin(StompFrame frame)
+   {
+      StompFrame response = null;
+      String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+      if (txID == null)
+      {
+         response = new HornetQStompException("Need a transaction id to begin").getFrame();
+      }
+      else
+      {
+         try
+         {
+            connection.beginTransaction(txID);
+         }
+         catch (HornetQStompException e)
+         {
+            response = e.getFrame();
+         }
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onCommit(StompFrame request)
+   {
+      StompFrame response = null;
+      
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+      if (txID == null)
+      {
+         response = new HornetQStompException("transaction header is mandatory to COMMIT a transaction").getFrame();
+         return response;
+      }
+
+      try
+      {
+         connection.commitTransaction(txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onAbort(StompFrame request)
+   {
+      StompFrame response = null;
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+      if (txID == null)
+      {
+         response = new HornetQStompException("transaction header is mandatory to ABORT a transaction").getFrame();
+         return response;
+      }
+      
+      try
+      {
+         connection.abortTransaction(txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      
+      return response;
+   }
+
+   @Override
+   public StompFrame onSubscribe(StompFrame request)
+   {
+      StompFrame response = null;
+      String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
+      
+      String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
+      String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
+      String id = request.getHeader(Stomp.Headers.Subscribe.ID);
+      String durableSubscriptionName = request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
+      boolean noLocal = false;
+      
+      if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
+      {
+         noLocal = Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
+      }
+      
+      try
+      {
+         connection.subscribe(destination, selector, ack, id, durableSubscriptionName, noLocal);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      
+      return response;
+   }
+
+   @Override
+   public StompFrame onUnsubscribe(StompFrame request)
+   {
+      StompFrame response = null;
+      String destination = request.getHeader(Stomp.Headers.Unsubscribe.DESTINATION);
+      String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
+
+      String subscriptionID = null;
+      if (id != null)
+      {
+         subscriptionID = id;
+      }
+      else
+      {
+         if (destination == null)
+         {
+            response = new HornetQStompException("Must specify the subscription's id or " +
+            		"the destination you are unsubscribing from").getFrame();
+            return response;
+         }
+         subscriptionID = "subscription/" + destination;
+      }
+      
+      try
+      {
+         connection.unsubscribe(subscriptionID);
+      }
+      catch (HornetQStompException e)
+      {
+         return e.getFrame();
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onAck(StompFrame request)
+   {
+      StompFrame response = null;
+      
+      String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+      if (txID != null)
+      {
+         log.warn("Transactional acknowledgement is not supported");
+      }
+      
+      try
+      {
+         connection.acknowledge(messageID, null);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+
+      return response;
+   }
+
+   @Override
+   public StompFrame onStomp(StompFrame request)
+   {
+      return onUnknown(request.getCommand());
+   }
+
+   @Override
+   public StompFrame onNack(StompFrame request)
+   {
+      return onUnknown(request.getCommand());
+   }
+
+   @Override
+   public StompFrame createMessageFrame(ServerMessage serverMessage,
+         StompSubscription subscription, int deliveryCount) throws Exception
+   {
+      StompFrame frame = new StompFrame(Stomp.Responses.MESSAGE);
+      
+      if (subscription.getID() != null)
+      {
+         frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
+      }
+
+      synchronized(serverMessage)
+      {
+
+      HornetQBuffer buffer = serverMessage.getBodyBuffer();
+
+      int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
+                                                              : serverMessage.getEndOfBodyPosition();
+      int size = bodyPos - buffer.readerIndex();
+      buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
+      byte[] data = new byte[size];
+      
+      if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) || serverMessage.getType() == Message.BYTES_TYPE)
+      {
+         frame.addHeader(Headers.CONTENT_LENGTH, String.valueOf(data.length));
+         buffer.readBytes(data);
+      }
+      else
+      {
+         SimpleString text = buffer.readNullableSimpleString();
+         if (text != null)
+         {
+            data = text.toString().getBytes("UTF-8");
+         }
+         else
+         {
+            data = new byte[0];
+         }
+      }
+      frame.setByteBody(data);
+
+      serverMessage.getBodyBuffer().resetReaderIndex();
+
+      StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame, deliveryCount);
+      }
+      
+      return frame;
+
+   }
+
+   @Override
+   public StompFrame createStompFrame(String command)
+   {
+      return new StompFrameV10(command);
+   }
+
+   public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws HornetQStompException
+   {
+      return decoder.defaultDecode(buffer);
+   }
+
+   @Override
+   public void replySent(StompFrame reply)
+   {
+      if (reply.needsDisconnect())
+      {
+         connection.destroy();
+      }
+   }
+
+   @Override
+   public void requestAccepted(StompFrame request)
+   {
+      // TODO Auto-generated method stub
+      
+   }
+   
+   @Override
+   public StompFrame postprocess(StompFrame request)
+   {
+      StompFrame response = null;
+      if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+      {
+         response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+         {
+            response.setNeedsDisconnect(true);
+         }
+      }
+      else
+      {
+         //request null, disconnect if so.
+         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+         {
+            this.connection.disconnect();
+         }         
+      }
+      return response;
+   }
+
+}

Deleted: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java
===================================================================
--- branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,28 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.core.protocol.stomp.v10;
-
-import org.hornetq.core.protocol.stomp.StompFrame;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- */
-public class StompFrameV10 extends StompFrame
-{
-   public StompFrameV10(String command)
-   {
-      super(command);
-   }
-
-}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v10/StompFrameV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp.v10;
+
+import org.hornetq.core.protocol.stomp.StompFrame;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class StompFrameV10 extends StompFrame
+{
+   public StompFrameV10(String command)
+   {
+      super(command);
+   }
+
+}

Deleted: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java
===================================================================
--- branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,1109 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.core.protocol.stomp.v11;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.HornetQBuffers;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.impl.MessageImpl;
-import org.hornetq.core.protocol.stomp.FrameEventListener;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.SimpleBytes;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompConnection;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompSubscription;
-import org.hornetq.core.protocol.stomp.StompUtils;
-import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
-import org.hornetq.core.server.ServerMessage;
-import org.hornetq.core.server.impl.ServerMessageImpl;
-import org.hornetq.utils.DataConstants;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- */
-public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements FrameEventListener
-{
-   private static final Logger log = Logger.getLogger(StompFrameHandlerV11.class);
-   
-   private static final char ESC_CHAR = '\\';
-   
-   private HeartBeater heartBeater;
-
-   public StompFrameHandlerV11(StompConnection connection)
-   {
-      this.connection = connection;
-      connection.addStompEventListener(this);
-   }
-
-   @Override
-   public StompFrame onConnect(StompFrame frame)
-   {
-      StompFrame response = null;
-      Map<String, String> headers = frame.getHeadersMap();
-      String login = headers.get(Stomp.Headers.Connect.LOGIN);
-      String passcode = headers.get(Stomp.Headers.Connect.PASSCODE);
-      String clientID = headers.get(Stomp.Headers.Connect.CLIENT_ID);
-      String requestID = headers.get(Stomp.Headers.Connect.REQUEST_ID);
-
-      try
-      {
-         if (connection.validateUser(login, passcode))
-         {
-            connection.setClientID(clientID);
-            connection.setValid(true);
-
-            response = new StompFrameV11(Stomp.Responses.CONNECTED);
-
-            // version
-            response.addHeader(Stomp.Headers.Connected.VERSION,
-                  connection.getVersion());
-
-            // session
-            response.addHeader(Stomp.Headers.Connected.SESSION, connection
-                  .getID().toString());
-
-            // server
-            response.addHeader(Stomp.Headers.Connected.SERVER,
-                  connection.getHornetQServerName());
-
-            if (requestID != null)
-            {
-               response.addHeader(Stomp.Headers.Connected.RESPONSE_ID,
-                     requestID);
-            }
-
-            // heart-beat. We need to start after connected frame has been sent.
-            // otherwise the client may receive heart-beat before it receives
-            // connected frame.
-            String heartBeat = headers.get(Stomp.Headers.Connect.HEART_BEAT);
-
-            if (heartBeat != null)
-            {
-               handleHeartBeat(heartBeat);
-               if (heartBeater == null)
-               {
-                  response.addHeader(Stomp.Headers.Connected.HEART_BEAT, "0,0");
-               }
-               else
-               {
-                  response.addHeader(Stomp.Headers.Connected.HEART_BEAT, heartBeater.getServerHeartBeatValue());
-               }
-            }
-         }
-         else
-         {
-            // not valid
-            response = new StompFrame(Stomp.Responses.ERROR, true);
-            response.addHeader(Stomp.Headers.Error.VERSION, "1.0,1.1");
-
-            response.setBody("Supported protocol versions are 1.0 and 1.1");
-         }
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      catch (UnsupportedEncodingException e)
-      {
-         response = new HornetQStompException("Encoding error.", e).getFrame();
-      }
-      return response;
-   }
-
-   //ping parameters, hard-code for now
-   //the server can support min 20 milliseconds and receive ping at 100 milliseconds (20,100)
-   private void handleHeartBeat(String heartBeatHeader) throws HornetQStompException
-   {
-      String[] params = heartBeatHeader.split(",");
-      if (params.length != 2)
-      {
-         throw new HornetQStompException("Incorrect heartbeat header " + heartBeatHeader);
-      }
-      
-      //client ping
-      long minPingInterval = Long.valueOf(params[0]);
-      //client receive ping
-      long minAcceptInterval = Long.valueOf(params[1]);
-      
-      if ((minPingInterval != 0) || (minAcceptInterval != 0))
-      {
-         heartBeater = new HeartBeater(minPingInterval, minAcceptInterval);
-      }
-   }
-
-   @Override
-   public StompFrame onDisconnect(StompFrame frame)
-   {
-      if (this.heartBeater != null)
-      {
-         heartBeater.shutdown();
-         try
-         {
-            heartBeater.join();
-         }
-         catch (InterruptedException e)
-         {
-            log.warn("Interrupted while waiting for heart beater to die", e);
-         }
-      }
-      return null;
-   }
-   
-   @Override
-   public StompFrame postprocess(StompFrame request)
-   {
-      StompFrame response = null;
-      if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
-      {
-         response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
-         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
-         {
-            response.setNeedsDisconnect(true);
-         }
-      }
-      else
-      {
-         //request null, disconnect if so.
-         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
-         {
-            this.connection.disconnect();
-         }         
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onSend(StompFrame frame)
-   {
-      StompFrame response = null;
-      try
-      {
-         connection.validate();
-         String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
-         String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-
-         long timestamp = System.currentTimeMillis();
-
-         ServerMessageImpl message = connection.createServerMessage();
-         message.setTimestamp(timestamp);
-         message.setAddress(SimpleString.toSimpleString(destination));
-         StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
-         if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
-         {
-            message.setType(Message.BYTES_TYPE);
-            message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
-         }
-         else
-         {
-            message.setType(Message.TEXT_TYPE);
-            String text = frame.getBody();
-            message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
-         }
-
-         connection.sendServerMessage(message, txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      catch (Exception e)
-      {
-         response = new HornetQStompException("Error handling send", e).getFrame();
-      }
-
-      return response;
-   }
-
-   @Override
-   public StompFrame onBegin(StompFrame frame)
-   {
-      StompFrame response = null;
-      String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         response = new HornetQStompException("Need a transaction id to begin").getFrame();
-      }
-      else
-      {
-         try
-         {
-            connection.beginTransaction(txID);
-         }
-         catch (HornetQStompException e)
-         {
-            response = e.getFrame();
-         }
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onCommit(StompFrame request)
-   {
-      StompFrame response = null;
-      
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-      if (txID == null)
-      {
-         response = new HornetQStompException("transaction header is mandatory to COMMIT a transaction").getFrame();
-         return response;
-      }
-
-      try
-      {
-         connection.commitTransaction(txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onAbort(StompFrame request)
-   {
-      StompFrame response = null;
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-
-      if (txID == null)
-      {
-         response = new HornetQStompException("transaction header is mandatory to ABORT a transaction").getFrame();
-         return response;
-      }
-      
-      try
-      {
-         connection.abortTransaction(txID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      
-      return response;
-   }
-
-   @Override
-   public StompFrame onSubscribe(StompFrame request)
-   {
-      StompFrame response = null;
-      String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
-      
-      String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
-      String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
-      String id = request.getHeader(Stomp.Headers.Subscribe.ID);
-      String durableSubscriptionName = request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
-      boolean noLocal = false;
-      
-      if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
-      {
-         noLocal = Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
-      }
-      
-      try
-      {
-         connection.subscribe(destination, selector, ack, id, durableSubscriptionName, noLocal);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      
-      return response;
-   }
-
-   @Override
-   public StompFrame onUnsubscribe(StompFrame request)
-   {
-      StompFrame response = null;
-      //unsubscribe in 1.1 only needs id header
-      String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
-
-      String subscriptionID = null;
-      if (id != null)
-      {
-         subscriptionID = id;
-      }
-      else
-      {
-          response = new HornetQStompException("Must specify the subscription's id").getFrame();
-          return response;
-      }
-      
-      try
-      {
-         connection.unsubscribe(subscriptionID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-      return response;
-   }
-
-   @Override
-   public StompFrame onAck(StompFrame request)
-   {
-      StompFrame response = null;
-      
-      String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
-      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
-      String subscriptionID = request.getHeader(Stomp.Headers.Ack.SUBSCRIPTION);
-
-      if (txID != null)
-      {
-         log.warn("Transactional acknowledgement is not supported");
-      }
-      
-      if (subscriptionID == null)
-      {
-         response = new HornetQStompException("subscription header is required").getFrame();
-         return response;
-      }
-      
-      try
-      {
-         connection.acknowledge(messageID, subscriptionID);
-      }
-      catch (HornetQStompException e)
-      {
-         response = e.getFrame();
-      }
-
-      return response;
-   }
-
-   @Override
-   public StompFrame onStomp(StompFrame request)
-   {
-      if (!connection.isValid())
-      {
-         return onConnect(request);
-      }
-      return null;
-   }
-
-   @Override
-   public StompFrame onNack(StompFrame request)
-   {
-      //this eventually means discard the message (it never be redelivered again).
-      //we can consider supporting redeliver to a different sub.
-      return onAck(request);
-   }
-
-   @Override
-   public StompFrame createMessageFrame(ServerMessage serverMessage,
-         StompSubscription subscription, int deliveryCount)
-         throws Exception
-   {
-      StompFrame frame = new StompFrameV11(Stomp.Responses.MESSAGE);
-      
-      if (subscription.getID() != null)
-      {
-         frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
-      }
-      
-      HornetQBuffer buffer = serverMessage.getBodyBuffer();
-
-      int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
-                                                              : serverMessage.getEndOfBodyPosition();
-      int size = bodyPos - buffer.readerIndex();
-      buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
-      byte[] data = new byte[size];
-      if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) || serverMessage.getType() == Message.BYTES_TYPE)
-      {
-         frame.addHeader(Stomp.Headers.CONTENT_LENGTH, String.valueOf(data.length));
-         buffer.readBytes(data);
-      }
-      else
-      {
-         SimpleString text = buffer.readNullableSimpleString();
-         if (text != null)
-         {
-            data = text.toString().getBytes("UTF-8");
-         }
-         else
-         {
-            data = new byte[0];
-         }
-      }
-      
-      frame.setByteBody(data);
-      
-      serverMessage.getBodyBuffer().resetReaderIndex();
-
-      StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame, deliveryCount);
-      
-      return frame;
-
-   }
-
-   @Override
-   public void replySent(StompFrame reply)
-   {
-      if (reply.getCommand().equals(Stomp.Responses.CONNECTED))
-      {
-         //kick off the pinger
-         startHeartBeat();
-      }
-      
-      if (reply.needsDisconnect())
-      {
-         connection.disconnect();
-      }
-      else
-      {
-         //update ping
-         if (heartBeater != null)
-         {
-            heartBeater.pinged();
-         }
-      }
-   }
-   
-   private void startHeartBeat()
-   {
-      if (heartBeater != null)
-      {
-         heartBeater.start();
-      }
-   }
-   
-   public StompFrame createPingFrame() throws UnsupportedEncodingException
-   {
-      StompFrame frame = new StompFrame(Stomp.Commands.STOMP);
-      frame.setBody("\n");
-      return frame;
-   }
-   
-   //server heart beat 
-   //algorithm: 
-   //(a) server ping: if server hasn't sent any frame within serverPing 
-   //interval, send a ping. 
-   //(b) accept ping: if server hasn't received any frame within
-   // 2*serverAcceptPing, disconnect!
-   private class HeartBeater extends Thread
-   {
-      final int MIN_SERVER_PING = 500;
-      final int MIN_CLIENT_PING = 500;
-      
-      long serverPing = 0;
-      long serverAcceptPing = 0;
-      volatile boolean shutdown = false;
-      AtomicLong lastPingTime = new AtomicLong(0);
-      AtomicLong lastAccepted = new AtomicLong(0);
-      StompFrame pingFrame;
-
-      public HeartBeater(long clientPing, long clientAcceptPing)
-      {
-         if (clientPing != 0)
-         {
-            serverAcceptPing = clientPing > MIN_CLIENT_PING ? clientPing : MIN_CLIENT_PING;
-         }
-         
-         if (clientAcceptPing != 0)
-         {
-            serverPing = clientAcceptPing > MIN_SERVER_PING ? clientAcceptPing : MIN_SERVER_PING;
-         }
-      }
-      
-      public synchronized void shutdown()
-      {
-         shutdown = true;
-         this.notify();
-      }
-
-      public String getServerHeartBeatValue()
-      {
-         return String.valueOf(serverPing) + "," + String.valueOf(serverAcceptPing);
-      }
-
-      public void pinged()
-      {
-         lastPingTime.set(System.currentTimeMillis());
-      }
-
-      public void run()
-      {
-         lastAccepted.set(System.currentTimeMillis());
-         try
-         {
-            pingFrame = createPingFrame();
-         }
-         catch (UnsupportedEncodingException e1)
-         {
-            log.error("Cannot create ping frame due to encoding problem.", e1);
-         }
-         
-         synchronized (this)
-         {
-            while (!shutdown)
-            {
-               long dur1 = 0;
-               long dur2 = 0;
-               
-               if (serverPing != 0)
-               {
-                  dur1 = System.currentTimeMillis() - lastPingTime.get();
-                  if (dur1 >= serverPing)
-                  {
-                     lastPingTime.set(System.currentTimeMillis());
-                     connection.ping(pingFrame);
-                     dur1 = 0;
-                  }
-               }
-
-               if (serverAcceptPing != 0)
-               {
-                  dur2 = System.currentTimeMillis() - lastAccepted.get();
-                  
-                  if (dur2 > (2 * serverAcceptPing))
-                  {
-                     connection.disconnect();
-                     shutdown = true;
-                     break;
-                  }
-               }
-               
-               long waitTime1 = 0;
-               long waitTime2 = 0;
-               
-               if (serverPing > 0)
-               {
-                  waitTime1 = serverPing - dur1;
-               }
-               
-               if (serverAcceptPing > 0)
-               {
-                  waitTime2 = serverAcceptPing * 2 - dur2;
-               }
-               
-               long waitTime = 10l;
-               
-               if ((waitTime1 > 0) && (waitTime1 > 0))
-               {
-                  waitTime = waitTime1 < waitTime2 ? waitTime1 : waitTime2;
-               }
-               else if (waitTime1 > 0)
-               {
-                  waitTime = waitTime1;
-               }
-               else if (waitTime2 > 0)
-               {
-                  waitTime = waitTime2;
-               }
-               
-               try
-               {
-                  this.wait(waitTime);
-               }
-               catch (InterruptedException e)
-               {
-               }
-            }
-         }
-      }
-
-      public void pingAccepted()
-      {
-         this.lastAccepted.set(System.currentTimeMillis());
-      }
-   }
-
-   @Override
-   public void requestAccepted(StompFrame request)
-   {
-      if (heartBeater != null)
-      {
-         heartBeater.pingAccepted();
-      }
-   }
-
-   @Override
-   public StompFrame createStompFrame(String command)
-   {
-      return new StompFrameV11(command);
-   }
-   
-   //all frame except CONNECT are decoded here.
-   public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws HornetQStompException
-   {
-      int readable = buffer.readableBytes();
-
-      if (decoder.data + readable >= decoder.workingBuffer.length)
-      {
-         decoder.resizeWorking(decoder.data + readable);
-      }
-
-      buffer.readBytes(decoder.workingBuffer, decoder.data, readable);
-
-      decoder.data += readable;
-
-      if (decoder.command == null)
-      {
-         if (decoder.data < 4)
-         {
-            // Need at least four bytes to identify the command
-            // - up to 3 bytes for the command name + potentially another byte for a leading \n
-
-            return null;
-         }
-
-         int offset;
-
-         if (decoder.workingBuffer[0] == StompDecoder.NEW_LINE)
-         {
-            // Yuck, some badly behaved STOMP clients add a \n *after* the terminating NUL char at the end of the
-            // STOMP
-            // frame this can manifest as an extra \n at the beginning when the next STOMP frame is read - we need to
-            // deal
-            // with this
-            offset = 1;
-         }
-         else
-         {
-            offset = 0;
-         }
-
-         byte b = decoder.workingBuffer[offset];
-
-         switch (b)
-         {
-            case StompDecoder.A:
-            {
-               if (decoder.workingBuffer[offset + 1] == StompDecoder.B)
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ABORT_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // ABORT
-                  decoder.command = StompDecoder.COMMAND_ABORT;
-               }
-               else
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ACK_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // ACK
-                  decoder.command = StompDecoder.COMMAND_ACK;
-               }
-               break;
-            }
-            case StompDecoder.B:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_BEGIN_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // BEGIN
-               decoder.command = StompDecoder.COMMAND_BEGIN;
-
-               break;
-            }
-            case StompDecoder.C:
-            {
-               if (decoder.workingBuffer[offset + 2] == StompDecoder.M)
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_COMMIT_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // COMMIT
-                  decoder.command = StompDecoder.COMMAND_COMMIT;
-               }
-               /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
-               else if (decoder.workingBuffer[offset+7] == StompDecoder.E) 
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECTED_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // CONNECTED
-                  decoder.command = StompDecoder.COMMAND_CONNECTED;                  
-               }
-               /**** end ****/
-               else
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECT_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // CONNECT
-                  decoder.command = StompDecoder.COMMAND_CONNECT;
-               }
-               break;
-            }
-            case StompDecoder.D:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_DISCONNECT_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // DISCONNECT
-               decoder.command = StompDecoder.COMMAND_DISCONNECT;
-
-               break;
-            }
-            case StompDecoder.R:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_RECEIPT_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // RECEIPT
-               decoder.command = StompDecoder.COMMAND_RECEIPT;
-
-               break;
-            }
-            /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
-            case StompDecoder.E:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ERROR_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // ERROR
-               decoder.command = StompDecoder.COMMAND_ERROR;
-
-               break;
-            }
-            case StompDecoder.M:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_MESSAGE_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // MESSAGE
-               decoder.command = StompDecoder.COMMAND_MESSAGE;
-
-               break;
-            }
-            /**** end ****/
-            case StompDecoder.S:
-            {
-               if (decoder.workingBuffer[offset + 1] == StompDecoder.E)
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SEND_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // SEND
-                  decoder.command = StompDecoder.COMMAND_SEND;
-               }
-               else if (decoder.workingBuffer[offset + 1] == StompDecoder.U)
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SUBSCRIBE_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // SUBSCRIBE
-                  decoder.command = StompDecoder.COMMAND_SUBSCRIBE;
-               }
-               else
-               {
-                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_STOMP_LENGTH + 1))
-                  {
-                     return null;
-                  }
-
-                  // SUBSCRIBE
-                  decoder.command = StompDecoder.COMMAND_STOMP;
-               }
-               break;
-            }
-            case StompDecoder.U:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_UNSUBSCRIBE_LENGTH + 1))
-               {
-                  return null;
-               }
-
-               // UNSUBSCRIBE
-               decoder.command = StompDecoder.COMMAND_UNSUBSCRIBE;
-
-               break;
-            }
-            case StompDecoder.N:
-            {
-               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_NACK_LENGTH + 1))
-               {
-                  return null;
-               }
-               //NACK
-               decoder.command = StompDecoder.COMMAND_NACK;
-               break;
-            }
-            default:
-            {
-               decoder.throwInvalid();
-            }
-         }
-
-         // Sanity check
-
-         if (decoder.workingBuffer[decoder.pos - 1] != StompDecoder.NEW_LINE)
-         {
-            decoder.throwInvalid();
-         }
-      }
-
-      if (decoder.readingHeaders)
-      {
-         if (decoder.headerBytesCopyStart == -1)
-         {
-            decoder.headerBytesCopyStart = decoder.pos;
-         }
-
-         // Now the headers
-
-         boolean isEscaping = false;
-         SimpleBytes holder = new SimpleBytes(1024);      
-         
-         outer: while (true)
-         {
-            byte b = decoder.workingBuffer[decoder.pos++];
-
-            switch (b)
-            {
-               //escaping
-               case ESC_CHAR:
-               {
-                  if (isEscaping)
-                  {
-                     //this is a backslash
-                     holder.append(b);
-                     isEscaping = false;
-                  }
-                  else
-                  {
-                     //begin escaping
-                     isEscaping = true;
-                  }
-                  break;
-               }
-               case StompDecoder.HEADER_SEPARATOR:
-               {
-                  if (isEscaping)
-                  {
-                     //a colon
-                     holder.append(b);
-                     isEscaping = false;
-                  }
-                  else
-                  {
-                     if (decoder.inHeaderName)
-                     {
-                        try
-                        {
-                           decoder.headerName = holder.getString();
-                        }
-                        catch (UnsupportedEncodingException e)
-                        {
-                           throw new HornetQStompException("Encoding exception", e);
-                        }
-                        
-                        holder.reset();
-
-                        decoder.inHeaderName = false;
-
-                        decoder.headerBytesCopyStart = decoder.pos;
-
-                        decoder.headerValueWhitespace = true;
-                     }
-                  }
-
-                  decoder.whiteSpaceOnly = false;
-
-                  break;
-               }
-               case StompDecoder.LN:
-               {
-                  if (isEscaping)
-                  {
-                     holder.append(StompDecoder.NEW_LINE);
-                     isEscaping = false;
-                  }
-                  else
-                  {
-                     holder.append(b);
-                  }
-                  break;
-               }
-               case StompDecoder.NEW_LINE:
-               {
-                  if (decoder.whiteSpaceOnly)
-                  {
-                     // Headers are terminated by a blank line
-                     decoder.readingHeaders = false;
-
-                     break outer;
-                  }
-
-                  String headerValue;
-                  try
-                  {
-                     headerValue = holder.getString();
-                  }
-                  catch (UnsupportedEncodingException e)
-                  {
-                     throw new HornetQStompException("Encoding exception.", e);
-                  }
-                  holder.reset();
-                  
-                  decoder.headers.put(decoder.headerName, headerValue);
-
-                  if (decoder.headerName.equals(StompDecoder.CONTENT_LENGTH_HEADER_NAME))
-                  {
-                     decoder.contentLength = Integer.parseInt(headerValue);
-                  }
-                  
-                  if (decoder.headerName.equals(StompDecoder.CONTENT_TYPE_HEADER_NAME))
-                  {
-                     decoder.contentType = headerValue;
-                  }
-
-                  decoder.whiteSpaceOnly = true;
-
-                  decoder.headerBytesCopyStart = decoder.pos;
-
-                  decoder.inHeaderName = true;
-
-                  decoder.headerValueWhitespace = false;
-
-                  break;
-               }
-               default:
-               {
-                  decoder.whiteSpaceOnly = false;
-
-                  decoder.headerValueWhitespace = false;
-                  
-                  holder.append(b);
-               }
-            }
-            if (decoder.pos == decoder.data)
-            {
-               // Run out of data
-
-               return null;
-            }
-         }
-      }
-
-      // Now the body
-
-      byte[] content = null;
-
-      if (decoder.contentLength != -1)
-      {
-         if (decoder.pos + decoder.contentLength + 1 > decoder.data)
-         {
-            // Need more bytes
-         }
-         else
-         {
-            content = new byte[decoder.contentLength];
-
-            System.arraycopy(decoder.workingBuffer, decoder.pos, content, 0, decoder.contentLength);
-
-            decoder.pos += decoder.contentLength + 1;
-            
-            //drain all the rest
-            if (decoder.bodyStart == -1)
-            {
-               decoder.bodyStart = decoder.pos;
-            }
-
-            while (decoder.pos < decoder.data)
-            {
-               if (decoder.workingBuffer[decoder.pos++] == 0)
-               {
-                  break;
-               }
-            }
-         }
-      }
-      else
-      {
-         // Need to scan for terminating NUL
-
-         if (decoder.bodyStart == -1)
-         {
-            decoder.bodyStart = decoder.pos;
-         }
-
-         while (decoder.pos < decoder.data)
-         {
-            if (decoder.workingBuffer[decoder.pos++] == 0)
-            {
-               content = new byte[decoder.pos - decoder.bodyStart - 1];
-
-               System.arraycopy(decoder.workingBuffer, decoder.bodyStart, content, 0, content.length);
-
-               break;
-            }
-         }
-      }
-      
-      if (content != null)
-      {
-         if (decoder.data > decoder.pos)
-         {
-            if (decoder.workingBuffer[decoder.pos] == StompDecoder.NEW_LINE) decoder.pos++;
-
-            if (decoder.data > decoder.pos)
-              // More data still in the buffer from the next packet
-              System.arraycopy(decoder.workingBuffer, decoder.pos, decoder.workingBuffer, 0, decoder.data - decoder.pos);
-         }
-
-         decoder.data = decoder.data - decoder.pos;
-
-         // reset
-
-         StompFrame ret = new StompFrameV11(decoder.command, decoder.headers, content);
-
-         decoder.init();
-
-         return ret;
-      }
-      else
-      {
-         return null;
-      }
-   }
-   
-}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameHandlerV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,1109 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp.v11;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.protocol.stomp.FrameEventListener;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.SimpleBytes;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompConnection;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompSubscription;
+import org.hornetq.core.protocol.stomp.StompUtils;
+import org.hornetq.core.protocol.stomp.VersionedStompFrameHandler;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.ServerMessageImpl;
+import org.hornetq.utils.DataConstants;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class StompFrameHandlerV11 extends VersionedStompFrameHandler implements FrameEventListener
+{
+   private static final Logger log = Logger.getLogger(StompFrameHandlerV11.class);
+   
+   private static final char ESC_CHAR = '\\';
+   
+   private HeartBeater heartBeater;
+
+   public StompFrameHandlerV11(StompConnection connection)
+   {
+      this.connection = connection;
+      connection.addStompEventListener(this);
+   }
+
+   @Override
+   public StompFrame onConnect(StompFrame frame)
+   {
+      StompFrame response = null;
+      Map<String, String> headers = frame.getHeadersMap();
+      String login = headers.get(Stomp.Headers.Connect.LOGIN);
+      String passcode = headers.get(Stomp.Headers.Connect.PASSCODE);
+      String clientID = headers.get(Stomp.Headers.Connect.CLIENT_ID);
+      String requestID = headers.get(Stomp.Headers.Connect.REQUEST_ID);
+
+      try
+      {
+         if (connection.validateUser(login, passcode))
+         {
+            connection.setClientID(clientID);
+            connection.setValid(true);
+
+            response = new StompFrameV11(Stomp.Responses.CONNECTED);
+
+            // version
+            response.addHeader(Stomp.Headers.Connected.VERSION,
+                  connection.getVersion());
+
+            // session
+            response.addHeader(Stomp.Headers.Connected.SESSION, connection
+                  .getID().toString());
+
+            // server
+            response.addHeader(Stomp.Headers.Connected.SERVER,
+                  connection.getHornetQServerName());
+
+            if (requestID != null)
+            {
+               response.addHeader(Stomp.Headers.Connected.RESPONSE_ID,
+                     requestID);
+            }
+
+            // heart-beat. We need to start after connected frame has been sent.
+            // otherwise the client may receive heart-beat before it receives
+            // connected frame.
+            String heartBeat = headers.get(Stomp.Headers.Connect.HEART_BEAT);
+
+            if (heartBeat != null)
+            {
+               handleHeartBeat(heartBeat);
+               if (heartBeater == null)
+               {
+                  response.addHeader(Stomp.Headers.Connected.HEART_BEAT, "0,0");
+               }
+               else
+               {
+                  response.addHeader(Stomp.Headers.Connected.HEART_BEAT, heartBeater.getServerHeartBeatValue());
+               }
+            }
+         }
+         else
+         {
+            // not valid
+            response = new StompFrame(Stomp.Responses.ERROR, true);
+            response.addHeader(Stomp.Headers.Error.VERSION, "1.0,1.1");
+
+            response.setBody("Supported protocol versions are 1.0 and 1.1");
+         }
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         response = new HornetQStompException("Encoding error.", e).getFrame();
+      }
+      return response;
+   }
+
+   //ping parameters, hard-code for now
+   //the server can support min 20 milliseconds and receive ping at 100 milliseconds (20,100)
+   private void handleHeartBeat(String heartBeatHeader) throws HornetQStompException
+   {
+      String[] params = heartBeatHeader.split(",");
+      if (params.length != 2)
+      {
+         throw new HornetQStompException("Incorrect heartbeat header " + heartBeatHeader);
+      }
+      
+      //client ping
+      long minPingInterval = Long.valueOf(params[0]);
+      //client receive ping
+      long minAcceptInterval = Long.valueOf(params[1]);
+      
+      if ((minPingInterval != 0) || (minAcceptInterval != 0))
+      {
+         heartBeater = new HeartBeater(minPingInterval, minAcceptInterval);
+      }
+   }
+
+   @Override
+   public StompFrame onDisconnect(StompFrame frame)
+   {
+      if (this.heartBeater != null)
+      {
+         heartBeater.shutdown();
+         try
+         {
+            heartBeater.join();
+         }
+         catch (InterruptedException e)
+         {
+            log.warn("Interrupted while waiting for heart beater to die", e);
+         }
+      }
+      return null;
+   }
+   
+   @Override
+   public StompFrame postprocess(StompFrame request)
+   {
+      StompFrame response = null;
+      if (request.hasHeader(Stomp.Headers.RECEIPT_REQUESTED))
+      {
+         response = handleReceipt(request.getHeader(Stomp.Headers.RECEIPT_REQUESTED));
+         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+         {
+            response.setNeedsDisconnect(true);
+         }
+      }
+      else
+      {
+         //request null, disconnect if so.
+         if (request.getCommand().equals(Stomp.Commands.DISCONNECT))
+         {
+            this.connection.disconnect();
+         }         
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onSend(StompFrame frame)
+   {
+      StompFrame response = null;
+      try
+      {
+         connection.validate();
+         String destination = frame.getHeader(Stomp.Headers.Send.DESTINATION);
+         String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+
+         long timestamp = System.currentTimeMillis();
+
+         ServerMessageImpl message = connection.createServerMessage();
+         message.setTimestamp(timestamp);
+         message.setAddress(SimpleString.toSimpleString(destination));
+         StompUtils.copyStandardHeadersFromFrameToMessage(frame, message);
+         if (frame.hasHeader(Stomp.Headers.CONTENT_LENGTH))
+         {
+            message.setType(Message.BYTES_TYPE);
+            message.getBodyBuffer().writeBytes(frame.getBodyAsBytes());
+         }
+         else
+         {
+            message.setType(Message.TEXT_TYPE);
+            String text = frame.getBody();
+            message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(text));
+         }
+
+         connection.sendServerMessage(message, txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      catch (Exception e)
+      {
+         response = new HornetQStompException("Error handling send", e).getFrame();
+      }
+
+      return response;
+   }
+
+   @Override
+   public StompFrame onBegin(StompFrame frame)
+   {
+      StompFrame response = null;
+      String txID = frame.getHeader(Stomp.Headers.TRANSACTION);
+      if (txID == null)
+      {
+         response = new HornetQStompException("Need a transaction id to begin").getFrame();
+      }
+      else
+      {
+         try
+         {
+            connection.beginTransaction(txID);
+         }
+         catch (HornetQStompException e)
+         {
+            response = e.getFrame();
+         }
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onCommit(StompFrame request)
+   {
+      StompFrame response = null;
+      
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+      if (txID == null)
+      {
+         response = new HornetQStompException("transaction header is mandatory to COMMIT a transaction").getFrame();
+         return response;
+      }
+
+      try
+      {
+         connection.commitTransaction(txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onAbort(StompFrame request)
+   {
+      StompFrame response = null;
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+
+      if (txID == null)
+      {
+         response = new HornetQStompException("transaction header is mandatory to ABORT a transaction").getFrame();
+         return response;
+      }
+      
+      try
+      {
+         connection.abortTransaction(txID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      
+      return response;
+   }
+
+   @Override
+   public StompFrame onSubscribe(StompFrame request)
+   {
+      StompFrame response = null;
+      String destination = request.getHeader(Stomp.Headers.Subscribe.DESTINATION);
+      
+      String selector = request.getHeader(Stomp.Headers.Subscribe.SELECTOR);
+      String ack = request.getHeader(Stomp.Headers.Subscribe.ACK_MODE);
+      String id = request.getHeader(Stomp.Headers.Subscribe.ID);
+      String durableSubscriptionName = request.getHeader(Stomp.Headers.Subscribe.DURABLE_SUBSCRIBER_NAME);
+      boolean noLocal = false;
+      
+      if (request.hasHeader(Stomp.Headers.Subscribe.NO_LOCAL))
+      {
+         noLocal = Boolean.parseBoolean(request.getHeader(Stomp.Headers.Subscribe.NO_LOCAL));
+      }
+      
+      try
+      {
+         connection.subscribe(destination, selector, ack, id, durableSubscriptionName, noLocal);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      
+      return response;
+   }
+
+   @Override
+   public StompFrame onUnsubscribe(StompFrame request)
+   {
+      StompFrame response = null;
+      //unsubscribe in 1.1 only needs id header
+      String id = request.getHeader(Stomp.Headers.Unsubscribe.ID);
+
+      String subscriptionID = null;
+      if (id != null)
+      {
+         subscriptionID = id;
+      }
+      else
+      {
+          response = new HornetQStompException("Must specify the subscription's id").getFrame();
+          return response;
+      }
+      
+      try
+      {
+         connection.unsubscribe(subscriptionID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+      return response;
+   }
+
+   @Override
+   public StompFrame onAck(StompFrame request)
+   {
+      StompFrame response = null;
+      
+      String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID);
+      String txID = request.getHeader(Stomp.Headers.TRANSACTION);
+      String subscriptionID = request.getHeader(Stomp.Headers.Ack.SUBSCRIPTION);
+
+      if (txID != null)
+      {
+         log.warn("Transactional acknowledgement is not supported");
+      }
+      
+      if (subscriptionID == null)
+      {
+         response = new HornetQStompException("subscription header is required").getFrame();
+         return response;
+      }
+      
+      try
+      {
+         connection.acknowledge(messageID, subscriptionID);
+      }
+      catch (HornetQStompException e)
+      {
+         response = e.getFrame();
+      }
+
+      return response;
+   }
+
+   @Override
+   public StompFrame onStomp(StompFrame request)
+   {
+      if (!connection.isValid())
+      {
+         return onConnect(request);
+      }
+      return null;
+   }
+
+   @Override
+   public StompFrame onNack(StompFrame request)
+   {
+      //this eventually means discard the message (it never be redelivered again).
+      //we can consider supporting redeliver to a different sub.
+      return onAck(request);
+   }
+
+   @Override
+   public StompFrame createMessageFrame(ServerMessage serverMessage,
+         StompSubscription subscription, int deliveryCount)
+         throws Exception
+   {
+      StompFrame frame = new StompFrameV11(Stomp.Responses.MESSAGE);
+      
+      if (subscription.getID() != null)
+      {
+         frame.addHeader(Stomp.Headers.Message.SUBSCRIPTION, subscription.getID());
+      }
+      
+      HornetQBuffer buffer = serverMessage.getBodyBuffer();
+
+      int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
+                                                              : serverMessage.getEndOfBodyPosition();
+      int size = bodyPos - buffer.readerIndex();
+      buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
+      byte[] data = new byte[size];
+      if (serverMessage.containsProperty(Stomp.Headers.CONTENT_LENGTH) || serverMessage.getType() == Message.BYTES_TYPE)
+      {
+         frame.addHeader(Stomp.Headers.CONTENT_LENGTH, String.valueOf(data.length));
+         buffer.readBytes(data);
+      }
+      else
+      {
+         SimpleString text = buffer.readNullableSimpleString();
+         if (text != null)
+         {
+            data = text.toString().getBytes("UTF-8");
+         }
+         else
+         {
+            data = new byte[0];
+         }
+      }
+      
+      frame.setByteBody(data);
+      
+      serverMessage.getBodyBuffer().resetReaderIndex();
+
+      StompUtils.copyStandardHeadersFromMessageToFrame(serverMessage, frame, deliveryCount);
+      
+      return frame;
+
+   }
+
+   @Override
+   public void replySent(StompFrame reply)
+   {
+      if (reply.getCommand().equals(Stomp.Responses.CONNECTED))
+      {
+         //kick off the pinger
+         startHeartBeat();
+      }
+      
+      if (reply.needsDisconnect())
+      {
+         connection.disconnect();
+      }
+      else
+      {
+         //update ping
+         if (heartBeater != null)
+         {
+            heartBeater.pinged();
+         }
+      }
+   }
+   
+   private void startHeartBeat()
+   {
+      if (heartBeater != null)
+      {
+         heartBeater.start();
+      }
+   }
+   
+   public StompFrame createPingFrame() throws UnsupportedEncodingException
+   {
+      StompFrame frame = new StompFrame(Stomp.Commands.STOMP);
+      frame.setBody("\n");
+      return frame;
+   }
+   
+   //server heart beat 
+   //algorithm: 
+   //(a) server ping: if server hasn't sent any frame within serverPing 
+   //interval, send a ping. 
+   //(b) accept ping: if server hasn't received any frame within
+   // 2*serverAcceptPing, disconnect!
+   private class HeartBeater extends Thread
+   {
+      final int MIN_SERVER_PING = 500;
+      final int MIN_CLIENT_PING = 500;
+      
+      long serverPing = 0;
+      long serverAcceptPing = 0;
+      volatile boolean shutdown = false;
+      AtomicLong lastPingTime = new AtomicLong(0);
+      AtomicLong lastAccepted = new AtomicLong(0);
+      StompFrame pingFrame;
+
+      public HeartBeater(long clientPing, long clientAcceptPing)
+      {
+         if (clientPing != 0)
+         {
+            serverAcceptPing = clientPing > MIN_CLIENT_PING ? clientPing : MIN_CLIENT_PING;
+         }
+         
+         if (clientAcceptPing != 0)
+         {
+            serverPing = clientAcceptPing > MIN_SERVER_PING ? clientAcceptPing : MIN_SERVER_PING;
+         }
+      }
+      
+      public synchronized void shutdown()
+      {
+         shutdown = true;
+         this.notify();
+      }
+
+      public String getServerHeartBeatValue()
+      {
+         return String.valueOf(serverPing) + "," + String.valueOf(serverAcceptPing);
+      }
+
+      public void pinged()
+      {
+         lastPingTime.set(System.currentTimeMillis());
+      }
+
+      public void run()
+      {
+         lastAccepted.set(System.currentTimeMillis());
+         try
+         {
+            pingFrame = createPingFrame();
+         }
+         catch (UnsupportedEncodingException e1)
+         {
+            log.error("Cannot create ping frame due to encoding problem.", e1);
+         }
+         
+         synchronized (this)
+         {
+            while (!shutdown)
+            {
+               long dur1 = 0;
+               long dur2 = 0;
+               
+               if (serverPing != 0)
+               {
+                  dur1 = System.currentTimeMillis() - lastPingTime.get();
+                  if (dur1 >= serverPing)
+                  {
+                     lastPingTime.set(System.currentTimeMillis());
+                     connection.ping(pingFrame);
+                     dur1 = 0;
+                  }
+               }
+
+               if (serverAcceptPing != 0)
+               {
+                  dur2 = System.currentTimeMillis() - lastAccepted.get();
+                  
+                  if (dur2 > (2 * serverAcceptPing))
+                  {
+                     connection.disconnect();
+                     shutdown = true;
+                     break;
+                  }
+               }
+               
+               long waitTime1 = 0;
+               long waitTime2 = 0;
+               
+               if (serverPing > 0)
+               {
+                  waitTime1 = serverPing - dur1;
+               }
+               
+               if (serverAcceptPing > 0)
+               {
+                  waitTime2 = serverAcceptPing * 2 - dur2;
+               }
+               
+               long waitTime = 10l;
+               
+               if ((waitTime1 > 0) && (waitTime1 > 0))
+               {
+                  waitTime = waitTime1 < waitTime2 ? waitTime1 : waitTime2;
+               }
+               else if (waitTime1 > 0)
+               {
+                  waitTime = waitTime1;
+               }
+               else if (waitTime2 > 0)
+               {
+                  waitTime = waitTime2;
+               }
+               
+               try
+               {
+                  this.wait(waitTime);
+               }
+               catch (InterruptedException e)
+               {
+               }
+            }
+         }
+      }
+
+      public void pingAccepted()
+      {
+         this.lastAccepted.set(System.currentTimeMillis());
+      }
+   }
+
+   @Override
+   public void requestAccepted(StompFrame request)
+   {
+      if (heartBeater != null)
+      {
+         heartBeater.pingAccepted();
+      }
+   }
+
+   @Override
+   public StompFrame createStompFrame(String command)
+   {
+      return new StompFrameV11(command);
+   }
+   
+   //all frame except CONNECT are decoded here.
+   public StompFrame decode(StompDecoder decoder, final HornetQBuffer buffer) throws HornetQStompException
+   {
+      int readable = buffer.readableBytes();
+
+      if (decoder.data + readable >= decoder.workingBuffer.length)
+      {
+         decoder.resizeWorking(decoder.data + readable);
+      }
+
+      buffer.readBytes(decoder.workingBuffer, decoder.data, readable);
+
+      decoder.data += readable;
+
+      if (decoder.command == null)
+      {
+         if (decoder.data < 4)
+         {
+            // Need at least four bytes to identify the command
+            // - up to 3 bytes for the command name + potentially another byte for a leading \n
+
+            return null;
+         }
+
+         int offset;
+
+         if (decoder.workingBuffer[0] == StompDecoder.NEW_LINE)
+         {
+            // Yuck, some badly behaved STOMP clients add a \n *after* the terminating NUL char at the end of the
+            // STOMP
+            // frame this can manifest as an extra \n at the beginning when the next STOMP frame is read - we need to
+            // deal
+            // with this
+            offset = 1;
+         }
+         else
+         {
+            offset = 0;
+         }
+
+         byte b = decoder.workingBuffer[offset];
+
+         switch (b)
+         {
+            case StompDecoder.A:
+            {
+               if (decoder.workingBuffer[offset + 1] == StompDecoder.B)
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ABORT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // ABORT
+                  decoder.command = StompDecoder.COMMAND_ABORT;
+               }
+               else
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ACK_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // ACK
+                  decoder.command = StompDecoder.COMMAND_ACK;
+               }
+               break;
+            }
+            case StompDecoder.B:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_BEGIN_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // BEGIN
+               decoder.command = StompDecoder.COMMAND_BEGIN;
+
+               break;
+            }
+            case StompDecoder.C:
+            {
+               if (decoder.workingBuffer[offset + 2] == StompDecoder.M)
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_COMMIT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // COMMIT
+                  decoder.command = StompDecoder.COMMAND_COMMIT;
+               }
+               /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
+               else if (decoder.workingBuffer[offset+7] == StompDecoder.E) 
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECTED_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // CONNECTED
+                  decoder.command = StompDecoder.COMMAND_CONNECTED;                  
+               }
+               /**** end ****/
+               else
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_CONNECT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // CONNECT
+                  decoder.command = StompDecoder.COMMAND_CONNECT;
+               }
+               break;
+            }
+            case StompDecoder.D:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_DISCONNECT_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // DISCONNECT
+               decoder.command = StompDecoder.COMMAND_DISCONNECT;
+
+               break;
+            }
+            case StompDecoder.R:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_RECEIPT_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // RECEIPT
+               decoder.command = StompDecoder.COMMAND_RECEIPT;
+
+               break;
+            }
+            /**** added by meddy, 27 april 2011, handle header parser for reply to websocket protocol ****/
+            case StompDecoder.E:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_ERROR_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // ERROR
+               decoder.command = StompDecoder.COMMAND_ERROR;
+
+               break;
+            }
+            case StompDecoder.M:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_MESSAGE_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // MESSAGE
+               decoder.command = StompDecoder.COMMAND_MESSAGE;
+
+               break;
+            }
+            /**** end ****/
+            case StompDecoder.S:
+            {
+               if (decoder.workingBuffer[offset + 1] == StompDecoder.E)
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SEND_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SEND
+                  decoder.command = StompDecoder.COMMAND_SEND;
+               }
+               else if (decoder.workingBuffer[offset + 1] == StompDecoder.U)
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_SUBSCRIBE_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SUBSCRIBE
+                  decoder.command = StompDecoder.COMMAND_SUBSCRIBE;
+               }
+               else
+               {
+                  if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_STOMP_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SUBSCRIBE
+                  decoder.command = StompDecoder.COMMAND_STOMP;
+               }
+               break;
+            }
+            case StompDecoder.U:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_UNSUBSCRIBE_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // UNSUBSCRIBE
+               decoder.command = StompDecoder.COMMAND_UNSUBSCRIBE;
+
+               break;
+            }
+            case StompDecoder.N:
+            {
+               if (!decoder.tryIncrement(offset + StompDecoder.COMMAND_NACK_LENGTH + 1))
+               {
+                  return null;
+               }
+               //NACK
+               decoder.command = StompDecoder.COMMAND_NACK;
+               break;
+            }
+            default:
+            {
+               decoder.throwInvalid();
+            }
+         }
+
+         // Sanity check
+
+         if (decoder.workingBuffer[decoder.pos - 1] != StompDecoder.NEW_LINE)
+         {
+            decoder.throwInvalid();
+         }
+      }
+
+      if (decoder.readingHeaders)
+      {
+         if (decoder.headerBytesCopyStart == -1)
+         {
+            decoder.headerBytesCopyStart = decoder.pos;
+         }
+
+         // Now the headers
+
+         boolean isEscaping = false;
+         SimpleBytes holder = new SimpleBytes(1024);      
+         
+         outer: while (true)
+         {
+            byte b = decoder.workingBuffer[decoder.pos++];
+
+            switch (b)
+            {
+               //escaping
+               case ESC_CHAR:
+               {
+                  if (isEscaping)
+                  {
+                     //this is a backslash
+                     holder.append(b);
+                     isEscaping = false;
+                  }
+                  else
+                  {
+                     //begin escaping
+                     isEscaping = true;
+                  }
+                  break;
+               }
+               case StompDecoder.HEADER_SEPARATOR:
+               {
+                  if (isEscaping)
+                  {
+                     //a colon
+                     holder.append(b);
+                     isEscaping = false;
+                  }
+                  else
+                  {
+                     if (decoder.inHeaderName)
+                     {
+                        try
+                        {
+                           decoder.headerName = holder.getString();
+                        }
+                        catch (UnsupportedEncodingException e)
+                        {
+                           throw new HornetQStompException("Encoding exception", e);
+                        }
+                        
+                        holder.reset();
+
+                        decoder.inHeaderName = false;
+
+                        decoder.headerBytesCopyStart = decoder.pos;
+
+                        decoder.headerValueWhitespace = true;
+                     }
+                  }
+
+                  decoder.whiteSpaceOnly = false;
+
+                  break;
+               }
+               case StompDecoder.LN:
+               {
+                  if (isEscaping)
+                  {
+                     holder.append(StompDecoder.NEW_LINE);
+                     isEscaping = false;
+                  }
+                  else
+                  {
+                     holder.append(b);
+                  }
+                  break;
+               }
+               case StompDecoder.NEW_LINE:
+               {
+                  if (decoder.whiteSpaceOnly)
+                  {
+                     // Headers are terminated by a blank line
+                     decoder.readingHeaders = false;
+
+                     break outer;
+                  }
+
+                  String headerValue;
+                  try
+                  {
+                     headerValue = holder.getString();
+                  }
+                  catch (UnsupportedEncodingException e)
+                  {
+                     throw new HornetQStompException("Encoding exception.", e);
+                  }
+                  holder.reset();
+                  
+                  decoder.headers.put(decoder.headerName, headerValue);
+
+                  if (decoder.headerName.equals(StompDecoder.CONTENT_LENGTH_HEADER_NAME))
+                  {
+                     decoder.contentLength = Integer.parseInt(headerValue);
+                  }
+                  
+                  if (decoder.headerName.equals(StompDecoder.CONTENT_TYPE_HEADER_NAME))
+                  {
+                     decoder.contentType = headerValue;
+                  }
+
+                  decoder.whiteSpaceOnly = true;
+
+                  decoder.headerBytesCopyStart = decoder.pos;
+
+                  decoder.inHeaderName = true;
+
+                  decoder.headerValueWhitespace = false;
+
+                  break;
+               }
+               default:
+               {
+                  decoder.whiteSpaceOnly = false;
+
+                  decoder.headerValueWhitespace = false;
+                  
+                  holder.append(b);
+               }
+            }
+            if (decoder.pos == decoder.data)
+            {
+               // Run out of data
+
+               return null;
+            }
+         }
+      }
+
+      // Now the body
+
+      byte[] content = null;
+
+      if (decoder.contentLength != -1)
+      {
+         if (decoder.pos + decoder.contentLength + 1 > decoder.data)
+         {
+            // Need more bytes
+         }
+         else
+         {
+            content = new byte[decoder.contentLength];
+
+            System.arraycopy(decoder.workingBuffer, decoder.pos, content, 0, decoder.contentLength);
+
+            decoder.pos += decoder.contentLength + 1;
+            
+            //drain all the rest
+            if (decoder.bodyStart == -1)
+            {
+               decoder.bodyStart = decoder.pos;
+            }
+
+            while (decoder.pos < decoder.data)
+            {
+               if (decoder.workingBuffer[decoder.pos++] == 0)
+               {
+                  break;
+               }
+            }
+         }
+      }
+      else
+      {
+         // Need to scan for terminating NUL
+
+         if (decoder.bodyStart == -1)
+         {
+            decoder.bodyStart = decoder.pos;
+         }
+
+         while (decoder.pos < decoder.data)
+         {
+            if (decoder.workingBuffer[decoder.pos++] == 0)
+            {
+               content = new byte[decoder.pos - decoder.bodyStart - 1];
+
+               System.arraycopy(decoder.workingBuffer, decoder.bodyStart, content, 0, content.length);
+
+               break;
+            }
+         }
+      }
+      
+      if (content != null)
+      {
+         if (decoder.data > decoder.pos)
+         {
+            if (decoder.workingBuffer[decoder.pos] == StompDecoder.NEW_LINE) decoder.pos++;
+
+            if (decoder.data > decoder.pos)
+              // More data still in the buffer from the next packet
+              System.arraycopy(decoder.workingBuffer, decoder.pos, decoder.workingBuffer, 0, decoder.data - decoder.pos);
+         }
+
+         decoder.data = decoder.data - decoder.pos;
+
+         // reset
+
+         StompFrame ret = new StompFrameV11(decoder.command, decoder.headers, content);
+
+         decoder.init();
+
+         return ret;
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+}

Deleted: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java
===================================================================
--- branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,103 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.core.protocol.stomp.v11;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.HornetQBuffers;
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.SimpleBytes;
-import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.protocol.stomp.StompFrame;
-import org.hornetq.core.protocol.stomp.StompFrame.Header;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- */
-public class StompFrameV11 extends StompFrame
-{
-   //stomp 1.1 talks about repetitive headers.
-   private List<Header> allHeaders = new ArrayList<Header>();
-   private String contentType;
-
-   public StompFrameV11(String command, Map<String, String> headers, byte[] content)
-   {
-      super(command, headers, content);
-   }
-   
-   public StompFrameV11(String command)
-   {
-      super(command);
-   }
-   
-   @Override
-   public HornetQBuffer toHornetQBuffer() throws Exception
-   {
-      if (buffer == null)
-      {
-         if (bytesBody != null)
-         {
-            buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
-         }
-         else
-         {
-            buffer = HornetQBuffers.dynamicBuffer(512);
-         }
-
-         StringBuffer head = new StringBuffer();
-         head.append(command);
-         head.append(Stomp.NEWLINE);
-         // Output the headers.
-         for (Header h : allHeaders)
-         {
-            head.append(h.getEscapedKey());
-            head.append(Stomp.Headers.SEPARATOR);
-            head.append(h.getEscapedValue());
-            head.append(Stomp.NEWLINE);
-         }
-         // Add a newline to separate the headers from the content.
-         head.append(Stomp.NEWLINE);
-
-         buffer.writeBytes(head.toString().getBytes("UTF-8"));
-         if (bytesBody != null)
-         {
-            buffer.writeBytes(bytesBody);
-         }
-
-         buffer.writeBytes(END_OF_FRAME);
-
-         size = buffer.writerIndex();
-      }
-      return buffer;
-   }
-   
-   @Override
-   public void addHeader(String key, String val)
-   {
-      if (!headers.containsKey(key))
-      {
-         headers.put(key, val);
-         allHeaders.add(new Header(key, val));
-      }
-      else if (!key.equals(Stomp.Headers.CONTENT_LENGTH))
-      {
-         allHeaders.add(new Header(key, val));
-      }
-   }
-
-
-}

Copied: trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java (from rev 11517, branches/STOMP11/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java)
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java	                        (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/protocol/stomp/v11/StompFrameV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.core.protocol.stomp.v11;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.SimpleBytes;
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.core.protocol.stomp.StompFrame;
+import org.hornetq.core.protocol.stomp.StompFrame.Header;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class StompFrameV11 extends StompFrame
+{
+   //stomp 1.1 talks about repetitive headers.
+   private List<Header> allHeaders = new ArrayList<Header>();
+   private String contentType;
+
+   public StompFrameV11(String command, Map<String, String> headers, byte[] content)
+   {
+      super(command, headers, content);
+   }
+   
+   public StompFrameV11(String command)
+   {
+      super(command);
+   }
+   
+   @Override
+   public HornetQBuffer toHornetQBuffer() throws Exception
+   {
+      if (buffer == null)
+      {
+         if (bytesBody != null)
+         {
+            buffer = HornetQBuffers.dynamicBuffer(bytesBody.length + 512);
+         }
+         else
+         {
+            buffer = HornetQBuffers.dynamicBuffer(512);
+         }
+
+         StringBuffer head = new StringBuffer();
+         head.append(command);
+         head.append(Stomp.NEWLINE);
+         // Output the headers.
+         for (Header h : allHeaders)
+         {
+            head.append(h.getEscapedKey());
+            head.append(Stomp.Headers.SEPARATOR);
+            head.append(h.getEscapedValue());
+            head.append(Stomp.NEWLINE);
+         }
+         // Add a newline to separate the headers from the content.
+         head.append(Stomp.NEWLINE);
+
+         buffer.writeBytes(head.toString().getBytes("UTF-8"));
+         if (bytesBody != null)
+         {
+            buffer.writeBytes(bytesBody);
+         }
+
+         buffer.writeBytes(END_OF_FRAME);
+
+         size = buffer.writerIndex();
+      }
+      return buffer;
+   }
+   
+   @Override
+   public void addHeader(String key, String val)
+   {
+      if (!headers.containsKey(key))
+      {
+         headers.put(key, val);
+         allHeaders.add(new Header(key, val));
+      }
+      else if (!key.equals(Stomp.Headers.CONTENT_LENGTH))
+      {
+         allHeaders.add(new Header(key, val));
+      }
+   }
+
+
+}

Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/server/HornetQServers.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -93,4 +93,19 @@
       return server;
    }
 
+   public static HornetQServer newHornetQServer(Configuration config,
+         String defUser, String defPass)
+   {
+      HornetQSecurityManager securityManager = new HornetQSecurityManagerImpl();
+      
+      securityManager.addUser(defUser, defPass);
+
+      HornetQServer server = HornetQServers.newHornetQServer(config,
+                                                      ManagementFactory.getPlatformMBeanServer(),
+                                                      securityManager,
+                                                      config.isPersistenceEnabled());
+
+      return server;
+   }
+
 }

Modified: trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/hornetq-core/src/main/java/org/hornetq/spi/core/security/HornetQSecurityManagerImpl.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -119,6 +119,7 @@
 
    public void addUser(final String user, final String password)
    {
+      log.error("-------------------------------adding user: " + user + " password " + password);
       if (user == null)
       {
          throw new IllegalArgumentException("User cannot be null");

Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -39,6 +39,8 @@
       frame = receiveFrame(10000);
       
       //We send and consumer a message to ensure a STOMP connection and server session is created
+      
+      System.out.println("Received frame: " + frame);
 
       Assert.assertTrue(frame.startsWith("CONNECTED"));
 

Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTest.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -192,7 +192,6 @@
 
    public void testSendMessageWithReceipt() throws Exception
    {
-
       MessageConsumer consumer = session.createConsumer(queue);
 
       String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
@@ -370,12 +369,13 @@
       frame = receiveFrame(100000);
       Assert.assertTrue(frame.startsWith("CONNECTED"));
 
-      frame = "SUBSCRIBE\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n" + "ack:auto\n\n" + Stomp.NULL;
+      frame = "SUBSCRIBE\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n" + "ack:auto\n\nfff" + Stomp.NULL;
       sendFrame(frame);
 
       sendMessage(getName());
 
       frame = receiveFrame(10000);
+      System.out.println("-------- frame received: " + frame);
       Assert.assertTrue(frame.startsWith("MESSAGE"));
       Assert.assertTrue(frame.indexOf("destination:") > 0);
       Assert.assertTrue(frame.indexOf(getName()) > 0);
@@ -406,6 +406,9 @@
       sendMessage(payload, queue);
 
       frame = receiveFrame(10000);
+      
+      System.out.println("Message: " + frame);
+      
       Assert.assertTrue(frame.startsWith("MESSAGE"));
 
       Pattern cl = Pattern.compile("Content-length:\\s*(\\d+)", Pattern.CASE_INSENSITIVE);

Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java	2011-10-12 08:04:52 UTC (rev 11518)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/StompTestBase.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -39,7 +39,6 @@
 
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.core.config.Configuration;
-import org.hornetq.core.config.impl.ConfigurationImpl;
 import org.hornetq.core.logging.Logger;
 import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
 import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
@@ -80,7 +79,11 @@
 
    protected JMSServerManager server;
    
+   protected String defUser = "brianm";
    
+   protected String defPass = "wombats";
+   
+   
 
    // Implementation methods
    // -------------------------------------------------------------------------
@@ -121,7 +124,7 @@
       TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
       config.getAcceptorConfigurations().add(stompTransport);
       config.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
-      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config);
+      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser, defPass);
 
       JMSConfiguration jmsConfig = new JMSConfigurationImpl();
       jmsConfig.getQueueConfigurations()

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,184 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public class AbstractClientStompFrame implements ClientStompFrame
-{
-   protected static final String HEADER_RECEIPT = "receipt";
-   
-   protected String command;
-   protected List<Header> headers = new ArrayList<Header>();
-   protected Set<String> headerKeys = new HashSet<String>();
-   protected String body;
-
-   public AbstractClientStompFrame(String command)
-   {
-      this.command = command;
-   }
-   
-   public String toString()
-   {
-      StringBuffer sb = new StringBuffer("Frame: <" + command + ">" + "\n");
-      Iterator<Header> iter = headers.iterator();
-      while (iter.hasNext())
-      {
-         Header h = iter.next();
-         sb.append(h.key + ":" + h.val + "\n");
-      }
-      sb.append("\n");
-      sb.append("<body>" + body + "<body>");
-      return sb.toString();
-   }
-
-   @Override
-   public ByteBuffer toByteBuffer() throws UnsupportedEncodingException
-   {
-      StringBuffer sb = new StringBuffer();
-      sb.append(command + "\n");
-      int n = headers.size();
-      for (int i = 0; i < n; i++)
-      {
-         sb.append(headers.get(i).key + ":" + headers.get(i).val + "\n");
-      }
-      sb.append("\n");
-      if (body != null)
-      {
-         sb.append(body);
-      }
-      sb.append((char)0);
-      
-      String data = sb.toString();
-      
-      byte[] byteValue = data.getBytes("UTF-8");
-      
-      ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
-      buffer.put(byteValue);
-      
-      buffer.rewind();
-      return buffer;
-   }
-
-   @Override
-   public ByteBuffer toByteBufferWithExtra(String str) throws UnsupportedEncodingException
-   {
-      StringBuffer sb = new StringBuffer();
-      sb.append(command + "\n");
-      int n = headers.size();
-      for (int i = 0; i < n; i++)
-      {
-         sb.append(headers.get(i).key + ":" + headers.get(i).val + "\n");
-      }
-      sb.append("\n");
-      if (body != null)
-      {
-         sb.append(body);
-      }
-      sb.append((char)0);
-      sb.append(str);
-      
-      String data = sb.toString();
-      
-      byte[] byteValue = data.getBytes("UTF-8");
-      
-      ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
-      buffer.put(byteValue);
-      
-      buffer.rewind();
-      return buffer;
-   }
-
-   @Override
-   public boolean needsReply()
-   {
-      if ("CONNECT".equals(command) || headerKeys.contains(HEADER_RECEIPT))
-      {
-         return true;
-      }
-      return false;
-   }
-
-   @Override
-   public void setCommand(String command)
-   {
-      this.command = command;
-   }
-
-   @Override
-   public void addHeader(String key, String val)
-   {
-      headers.add(new Header(key, val));
-      headerKeys.add(key);
-   }
-
-   @Override
-   public void setBody(String body)
-   {
-      this.body = body;
-   }
-   
-   @Override
-   public String getBody()
-   {
-      return body;
-   }
-   
-   private class Header
-   {
-      public String key;
-      public String val;
-      
-      public Header(String key, String val)
-      {
-         this.key = key;
-         this.val = val;
-      }
-   }
-
-   @Override
-   public String getCommand()
-   {
-      return command;
-   }
-
-   @Override
-   public String getHeader(String header)
-   {
-      if (headerKeys.contains(header))
-      {
-         Iterator<Header> iter = headers.iterator();
-         while (iter.hasNext())
-         {
-            Header h = iter.next();
-            if (h.key.equals(header))
-            {
-               return h.val;
-            }
-         }
-      }
-      return null;
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractClientStompFrame.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class AbstractClientStompFrame implements ClientStompFrame
+{
+   protected static final String HEADER_RECEIPT = "receipt";
+   
+   protected String command;
+   protected List<Header> headers = new ArrayList<Header>();
+   protected Set<String> headerKeys = new HashSet<String>();
+   protected String body;
+
+   public AbstractClientStompFrame(String command)
+   {
+      this.command = command;
+   }
+   
+   public String toString()
+   {
+      StringBuffer sb = new StringBuffer("Frame: <" + command + ">" + "\n");
+      Iterator<Header> iter = headers.iterator();
+      while (iter.hasNext())
+      {
+         Header h = iter.next();
+         sb.append(h.key + ":" + h.val + "\n");
+      }
+      sb.append("\n");
+      sb.append("<body>" + body + "<body>");
+      return sb.toString();
+   }
+
+   @Override
+   public ByteBuffer toByteBuffer() throws UnsupportedEncodingException
+   {
+      StringBuffer sb = new StringBuffer();
+      sb.append(command + "\n");
+      int n = headers.size();
+      for (int i = 0; i < n; i++)
+      {
+         sb.append(headers.get(i).key + ":" + headers.get(i).val + "\n");
+      }
+      sb.append("\n");
+      if (body != null)
+      {
+         sb.append(body);
+      }
+      sb.append((char)0);
+      
+      String data = sb.toString();
+      
+      byte[] byteValue = data.getBytes("UTF-8");
+      
+      ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
+      buffer.put(byteValue);
+      
+      buffer.rewind();
+      return buffer;
+   }
+
+   @Override
+   public ByteBuffer toByteBufferWithExtra(String str) throws UnsupportedEncodingException
+   {
+      StringBuffer sb = new StringBuffer();
+      sb.append(command + "\n");
+      int n = headers.size();
+      for (int i = 0; i < n; i++)
+      {
+         sb.append(headers.get(i).key + ":" + headers.get(i).val + "\n");
+      }
+      sb.append("\n");
+      if (body != null)
+      {
+         sb.append(body);
+      }
+      sb.append((char)0);
+      sb.append(str);
+      
+      String data = sb.toString();
+      
+      byte[] byteValue = data.getBytes("UTF-8");
+      
+      ByteBuffer buffer = ByteBuffer.allocateDirect(byteValue.length);
+      buffer.put(byteValue);
+      
+      buffer.rewind();
+      return buffer;
+   }
+
+   @Override
+   public boolean needsReply()
+   {
+      if ("CONNECT".equals(command) || headerKeys.contains(HEADER_RECEIPT))
+      {
+         return true;
+      }
+      return false;
+   }
+
+   @Override
+   public void setCommand(String command)
+   {
+      this.command = command;
+   }
+
+   @Override
+   public void addHeader(String key, String val)
+   {
+      headers.add(new Header(key, val));
+      headerKeys.add(key);
+   }
+
+   @Override
+   public void setBody(String body)
+   {
+      this.body = body;
+   }
+   
+   @Override
+   public String getBody()
+   {
+      return body;
+   }
+   
+   private class Header
+   {
+      public String key;
+      public String val;
+      
+      public Header(String key, String val)
+      {
+         this.key = key;
+         this.val = val;
+      }
+   }
+
+   @Override
+   public String getCommand()
+   {
+      return command;
+   }
+
+   @Override
+   public String getHeader(String header)
+   {
+      if (headerKeys.contains(header))
+      {
+         Iterator<Header> iter = headers.iterator();
+         while (iter.hasNext())
+         {
+            Header h = iter.next();
+            if (h.key.equals(header))
+            {
+               return h.val;
+            }
+         }
+      }
+      return null;
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,291 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public abstract class AbstractStompClientConnection implements StompClientConnection
-{
-   protected static final String CONNECT_COMMAND = "CONNECT";
-   protected static final String CONNECTED_COMMAND = "CONNECTED";
-   protected static final String DISCONNECT_COMMAND = "DISCONNECT";
-   
-   protected static final String LOGIN_HEADER = "login";
-   protected static final String PASSCODE_HEADER = "passcode";
-   
-   //ext
-   protected static final String CLIENT_ID_HEADER = "client-id";
-   
-   
-   protected String version;
-   protected String host;
-   protected int port;
-   protected String username;
-   protected String passcode;
-   protected StompFrameFactory factory;
-   protected SocketChannel socketChannel;
-   protected ByteBuffer readBuffer;
-   
-   protected List<Byte> receiveList;
-   
-   protected BlockingQueue<ClientStompFrame> frameQueue = new LinkedBlockingQueue<ClientStompFrame>();
-   
-   protected boolean connected = false;
-
-   public AbstractStompClientConnection(String version, String host, int port) throws IOException
-   {
-      this.version = version;
-      this.host = host;
-      this.port = port;
-      this.factory = StompFrameFactoryFactory.getFactory(version);
-      
-      initSocket();
-   }
-
-   private void initSocket() throws IOException
-   {
-      socketChannel = SocketChannel.open();
-      socketChannel.configureBlocking(true);
-      InetSocketAddress remoteAddr = new InetSocketAddress(host, port);
-      socketChannel.connect(remoteAddr);
-      
-      startReaderThread();
-   }
-   
-   private void startReaderThread()
-   {
-      readBuffer = ByteBuffer.allocateDirect(10240);
-      receiveList = new ArrayList<Byte>(10240);
-      
-      new ReaderThread().start();
-   }
-   
-   public ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException, InterruptedException
-   {
-      ClientStompFrame response = null;
-      ByteBuffer buffer = frame.toByteBuffer();
-      while (buffer.remaining() > 0)
-      {
-         socketChannel.write(buffer);
-      }
-      
-      //now response
-      if (frame.needsReply())
-      {
-         response = receiveFrame();
-         
-         //filter out server ping
-         while (response != null)
-         {
-            if (response.getCommand().equals("STOMP"))
-            {
-               response = receiveFrame();
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
-      return response;
-   }
-
-   public ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException, InterruptedException
-   {
-      ClientStompFrame response = null;
-      ByteBuffer buffer = frame.toByteBufferWithExtra("\n");
-      
-      while (buffer.remaining() > 0)
-      {
-         socketChannel.write(buffer);
-      }
-      
-      //now response
-      if (frame.needsReply())
-      {
-         response = receiveFrame();
-         
-         //filter out server ping
-         while (response != null)
-         {
-            if (response.getCommand().equals("STOMP"))
-            {
-               response = receiveFrame();
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
-      return response;
-   }
-
-   public ClientStompFrame receiveFrame() throws InterruptedException
-   {
-      return frameQueue.poll(10, TimeUnit.SECONDS);
-   }
-
-   public ClientStompFrame receiveFrame(long timeout) throws InterruptedException
-   {
-      return frameQueue.poll(timeout, TimeUnit.MILLISECONDS);
-   }
-   
-   //put bytes to byte array.
-   private void receiveBytes(int n) throws UnsupportedEncodingException
-   {
-      readBuffer.rewind();
-      for (int i = 0; i < n; i++)
-      {
-         byte b = readBuffer.get();
-         if (b == 0)
-         {
-            //a new frame got.
-            int sz = receiveList.size();
-            if (sz > 0)
-            {
-               byte[] frameBytes = new byte[sz];
-               for (int j = 0; j < sz; j++)
-               {
-                  frameBytes[j] = receiveList.get(j);
-               }
-               ClientStompFrame frame = factory.createFrame(new String(frameBytes, "UTF-8"));
-               
-               if (validateFrame(frame))
-               {
-                 frameQueue.offer(frame);
-                 receiveList.clear();
-               }
-               else
-               {
-                  receiveList.add(b);
-               }
-            }
-         }
-         else
-         {
-            receiveList.add(b);
-         }
-      }
-      //clear readbuffer
-      readBuffer.rewind();
-   }
-   
-   private boolean validateFrame(ClientStompFrame f) throws UnsupportedEncodingException
-   {
-      String h = f.getHeader("content-length");
-      if (h != null)
-      {
-         int len = Integer.valueOf(h);
-         if (f.getBody().getBytes("UTF-8").length < len)
-         {
-            return false;
-         }
-      }
-      return true;
-   }
-   
-   protected void close() throws IOException
-   {
-      socketChannel.close();
-   }
-   
-   private class ReaderThread extends Thread
-   {
-      public void run()
-      {
-         try
-         {
-            int n = socketChannel.read(readBuffer);
-            
-            while (n >= 0)
-            {
-               if (n > 0)
-               {
-                  receiveBytes(n);
-               }
-               n = socketChannel.read(readBuffer);
-            }
-            //peer closed
-            close();
-         
-         } 
-         catch (IOException e)
-         {
-            try
-            {
-               close();
-            } 
-            catch (IOException e1)
-            {
-               //ignore
-            }
-         }
-      }
-   }
-
-   public void connect() throws Exception
-   {
-      connect(null, null);
-   }
-   
-   public void destroy()
-   {
-      try
-      {
-         close();
-      }
-      catch (IOException e)
-      {
-      }
-      finally
-      {
-         this.connected = false;
-      }
-   }
-   
-   public void connect(String username, String password) throws Exception
-   {
-      throw new RuntimeException("connect method not implemented!");
-   }
-   
-   public boolean isConnected()
-   {
-      return connected;
-   }
-   
-   public String getVersion()
-   {
-      return version;
-   }
-   
-   public int getFrameQueueSize()
-   {
-      return this.frameQueue.size();
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/AbstractStompClientConnection.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public abstract class AbstractStompClientConnection implements StompClientConnection
+{
+   protected static final String CONNECT_COMMAND = "CONNECT";
+   protected static final String CONNECTED_COMMAND = "CONNECTED";
+   protected static final String DISCONNECT_COMMAND = "DISCONNECT";
+   
+   protected static final String LOGIN_HEADER = "login";
+   protected static final String PASSCODE_HEADER = "passcode";
+   
+   //ext
+   protected static final String CLIENT_ID_HEADER = "client-id";
+   
+   
+   protected String version;
+   protected String host;
+   protected int port;
+   protected String username;
+   protected String passcode;
+   protected StompFrameFactory factory;
+   protected SocketChannel socketChannel;
+   protected ByteBuffer readBuffer;
+   
+   protected List<Byte> receiveList;
+   
+   protected BlockingQueue<ClientStompFrame> frameQueue = new LinkedBlockingQueue<ClientStompFrame>();
+   
+   protected boolean connected = false;
+
+   public AbstractStompClientConnection(String version, String host, int port) throws IOException
+   {
+      this.version = version;
+      this.host = host;
+      this.port = port;
+      this.factory = StompFrameFactoryFactory.getFactory(version);
+      
+      initSocket();
+   }
+
+   private void initSocket() throws IOException
+   {
+      socketChannel = SocketChannel.open();
+      socketChannel.configureBlocking(true);
+      InetSocketAddress remoteAddr = new InetSocketAddress(host, port);
+      socketChannel.connect(remoteAddr);
+      
+      startReaderThread();
+   }
+   
+   private void startReaderThread()
+   {
+      readBuffer = ByteBuffer.allocateDirect(10240);
+      receiveList = new ArrayList<Byte>(10240);
+      
+      new ReaderThread().start();
+   }
+   
+   public ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException, InterruptedException
+   {
+      ClientStompFrame response = null;
+      ByteBuffer buffer = frame.toByteBuffer();
+      while (buffer.remaining() > 0)
+      {
+         socketChannel.write(buffer);
+      }
+      
+      //now response
+      if (frame.needsReply())
+      {
+         response = receiveFrame();
+         
+         //filter out server ping
+         while (response != null)
+         {
+            if (response.getCommand().equals("STOMP"))
+            {
+               response = receiveFrame();
+            }
+            else
+            {
+               break;
+            }
+         }
+      }
+      return response;
+   }
+
+   public ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException, InterruptedException
+   {
+      ClientStompFrame response = null;
+      ByteBuffer buffer = frame.toByteBufferWithExtra("\n");
+      
+      while (buffer.remaining() > 0)
+      {
+         socketChannel.write(buffer);
+      }
+      
+      //now response
+      if (frame.needsReply())
+      {
+         response = receiveFrame();
+         
+         //filter out server ping
+         while (response != null)
+         {
+            if (response.getCommand().equals("STOMP"))
+            {
+               response = receiveFrame();
+            }
+            else
+            {
+               break;
+            }
+         }
+      }
+      return response;
+   }
+
+   public ClientStompFrame receiveFrame() throws InterruptedException
+   {
+      return frameQueue.poll(10, TimeUnit.SECONDS);
+   }
+
+   public ClientStompFrame receiveFrame(long timeout) throws InterruptedException
+   {
+      return frameQueue.poll(timeout, TimeUnit.MILLISECONDS);
+   }
+   
+   //put bytes to byte array.
+   private void receiveBytes(int n) throws UnsupportedEncodingException
+   {
+      readBuffer.rewind();
+      for (int i = 0; i < n; i++)
+      {
+         byte b = readBuffer.get();
+         if (b == 0)
+         {
+            //a new frame got.
+            int sz = receiveList.size();
+            if (sz > 0)
+            {
+               byte[] frameBytes = new byte[sz];
+               for (int j = 0; j < sz; j++)
+               {
+                  frameBytes[j] = receiveList.get(j);
+               }
+               ClientStompFrame frame = factory.createFrame(new String(frameBytes, "UTF-8"));
+               
+               if (validateFrame(frame))
+               {
+                 frameQueue.offer(frame);
+                 receiveList.clear();
+               }
+               else
+               {
+                  receiveList.add(b);
+               }
+            }
+         }
+         else
+         {
+            receiveList.add(b);
+         }
+      }
+      //clear readbuffer
+      readBuffer.rewind();
+   }
+   
+   private boolean validateFrame(ClientStompFrame f) throws UnsupportedEncodingException
+   {
+      String h = f.getHeader("content-length");
+      if (h != null)
+      {
+         int len = Integer.valueOf(h);
+         if (f.getBody().getBytes("UTF-8").length < len)
+         {
+            return false;
+         }
+      }
+      return true;
+   }
+   
+   protected void close() throws IOException
+   {
+      socketChannel.close();
+   }
+   
+   private class ReaderThread extends Thread
+   {
+      public void run()
+      {
+         try
+         {
+            int n = socketChannel.read(readBuffer);
+            
+            while (n >= 0)
+            {
+               if (n > 0)
+               {
+                  receiveBytes(n);
+               }
+               n = socketChannel.read(readBuffer);
+            }
+            //peer closed
+            close();
+         
+         } 
+         catch (IOException e)
+         {
+            try
+            {
+               close();
+            } 
+            catch (IOException e1)
+            {
+               //ignore
+            }
+         }
+      }
+   }
+
+   public void connect() throws Exception
+   {
+      connect(null, null);
+   }
+   
+   public void destroy()
+   {
+      try
+      {
+         close();
+      }
+      catch (IOException e)
+      {
+      }
+      finally
+      {
+         this.connected = false;
+      }
+   }
+   
+   public void connect(String username, String password) throws Exception
+   {
+      throw new RuntimeException("connect method not implemented!");
+   }
+   
+   public boolean isConnected()
+   {
+      return connected;
+   }
+   
+   public String getVersion()
+   {
+      return version;
+   }
+   
+   public int getFrameQueueSize()
+   {
+      return this.frameQueue.size();
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public interface ClientStompFrame
-{
-
-   public ByteBuffer toByteBuffer() throws UnsupportedEncodingException;
-
-   public boolean needsReply();
-
-   public void setCommand(String command);
-
-   public void addHeader(String string, String string2);
-
-   public void setBody(String string);
-
-   public String getCommand();
-
-   public String getHeader(String header);
-
-   public String getBody();
-
-   public ByteBuffer toByteBufferWithExtra(String str)  throws UnsupportedEncodingException;
-   
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrame.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public interface ClientStompFrame
+{
+
+   public ByteBuffer toByteBuffer() throws UnsupportedEncodingException;
+
+   public boolean needsReply();
+
+   public void setCommand(String command);
+
+   public void addHeader(String string, String string2);
+
+   public void setBody(String string);
+
+   public String getCommand();
+
+   public String getHeader(String header);
+
+   public String getBody();
+
+   public ByteBuffer toByteBufferWithExtra(String str)  throws UnsupportedEncodingException;
+   
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,29 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class ClientStompFrameV10 extends AbstractClientStompFrame
-{
-
-   public ClientStompFrameV10(String command)
-   {
-      super(command);
-   }
-   
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class ClientStompFrameV10 extends AbstractClientStompFrame
+{
+
+   public ClientStompFrameV10(String command)
+   {
+      super(command);
+   }
+   
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class ClientStompFrameV11 extends AbstractClientStompFrame
-{
-   boolean forceOneway = false;
-   
-   public ClientStompFrameV11(String command)
-   {
-      super(command);
-   }
-   
-   public void setForceOneway()
-   {
-      forceOneway = true;
-   }
-
-   @Override
-   public boolean needsReply()
-   {
-      if (forceOneway) return false;
-      
-      if ("CONNECT".equals(command) || "STOMP".equals(command) || headerKeys.contains(HEADER_RECEIPT))
-      {
-         return true;
-      }
-      return false;
-   }
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/ClientStompFrameV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class ClientStompFrameV11 extends AbstractClientStompFrame
+{
+   boolean forceOneway = false;
+   
+   public ClientStompFrameV11(String command)
+   {
+      super(command);
+   }
+   
+   public void setForceOneway()
+   {
+      forceOneway = true;
+   }
+
+   @Override
+   public boolean needsReply()
+   {
+      if (forceOneway) return false;
+      
+      if ("CONNECT".equals(command) || "STOMP".equals(command) || headerKeys.contains(HEADER_RECEIPT))
+      {
+         return true;
+      }
+      return false;
+   }
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public interface StompClientConnection
-{
-   ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException, InterruptedException;
-   
-   ClientStompFrame receiveFrame() throws InterruptedException;
-
-   ClientStompFrame receiveFrame(long timeout) throws InterruptedException;;
-
-   void connect() throws Exception;
-
-   void disconnect() throws IOException, InterruptedException;
-
-   void connect(String defUser, String defPass) throws Exception;
-
-   void connect(String defUser, String defPass, String clientId) throws Exception;
-
-   boolean isConnected();
-
-   String getVersion();
-
-   ClientStompFrame createFrame(String command);
-
-   //number of frames at the queue
-   int getFrameQueueSize();
-
-   void startPinger(long interval);
-
-   void stopPinger();
-
-   void destroy();
-
-   ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException, InterruptedException;
-   
-}
-

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnection.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public interface StompClientConnection
+{
+   ClientStompFrame sendFrame(ClientStompFrame frame) throws IOException, InterruptedException;
+   
+   ClientStompFrame receiveFrame() throws InterruptedException;
+
+   ClientStompFrame receiveFrame(long timeout) throws InterruptedException;;
+
+   void connect() throws Exception;
+
+   void disconnect() throws IOException, InterruptedException;
+
+   void connect(String defUser, String defPass) throws Exception;
+
+   void connect(String defUser, String defPass, String clientId) throws Exception;
+
+   boolean isConnected();
+
+   String getVersion();
+
+   ClientStompFrame createFrame(String command);
+
+   //number of frames at the queue
+   int getFrameQueueSize();
+
+   void startPinger(long interval);
+
+   void stopPinger();
+
+   void destroy();
+
+   ClientStompFrame sendWickedFrame(ClientStompFrame frame) throws IOException, InterruptedException;
+   
+}
+

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public class StompClientConnectionFactory
-{
-   //create a raw connection to the host.
-   public static StompClientConnection createClientConnection(String version, String host, int port) throws IOException
-   {
-      if ("1.0".equals(version))
-      {
-         return new StompClientConnectionV10(host, port);
-      }
-      if ("1.1".equals(version))
-      {
-         return new StompClientConnectionV11(host, port);
-      }
-      return null;
-   }
-
-   public static void main(String[] args) throws Exception
-   {
-      StompClientConnection connection = StompClientConnectionFactory.createClientConnection("1.0", "localhost", 61613);
-      
-      System.out.println("created a new connection: " + connection);
-      
-      connection.connect();
-      
-      System.out.println("connected.");
-      
-      connection.disconnect();
-      System.out.println("Simple stomp client works.");
-      
-   }
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class StompClientConnectionFactory
+{
+   //create a raw connection to the host.
+   public static StompClientConnection createClientConnection(String version, String host, int port) throws IOException
+   {
+      if ("1.0".equals(version))
+      {
+         return new StompClientConnectionV10(host, port);
+      }
+      if ("1.1".equals(version))
+      {
+         return new StompClientConnectionV11(host, port);
+      }
+      return null;
+   }
+
+   public static void main(String[] args) throws Exception
+   {
+      StompClientConnection connection = StompClientConnectionFactory.createClientConnection("1.0", "localhost", 61613);
+      
+      System.out.println("created a new connection: " + connection);
+      
+      connection.connect();
+      
+      System.out.println("connected.");
+      
+      connection.disconnect();
+      System.out.println("Simple stomp client works.");
+      
+   }
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,101 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * pls use factory to create frames.
- */
-public class StompClientConnectionV10 extends AbstractStompClientConnection
-{
-
-   public StompClientConnectionV10(String host, int port) throws IOException
-   {
-      super("1.0", host, port);
-   }
-
-   public void connect(String username, String passcode) throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
-      frame.addHeader(LOGIN_HEADER, username);
-      frame.addHeader(PASSCODE_HEADER, passcode);
-      
-      ClientStompFrame response = this.sendFrame(frame);
-      
-      if (response.getCommand().equals(CONNECTED_COMMAND))
-      {
-         connected = true;
-      }
-      else
-      {
-         System.out.println("Connection failed with: " + response);
-         connected = false;
-      }
-   }
-
-   public void connect(String username, String passcode, String clientID) throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
-      frame.addHeader(LOGIN_HEADER, username);
-      frame.addHeader(PASSCODE_HEADER, passcode);
-      frame.addHeader(CLIENT_ID_HEADER, clientID);
-      
-      ClientStompFrame response = this.sendFrame(frame);
-      
-      if (response.getCommand().equals(CONNECTED_COMMAND))
-      {
-         connected = true;
-      }
-      else
-      {
-         System.out.println("Connection failed with: " + response);
-         connected = false;
-      }
-   }
-
-   @Override
-   public void disconnect() throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
-      this.sendFrame(frame);
-      
-      close();
-      
-      connected = false;
-   }
-
-   @Override
-   public ClientStompFrame createFrame(
-         String command)
-   {
-      return new ClientStompFrameV10(command);
-   }
-
-   @Override
-   public void startPinger(long interval)
-   {
-      // TODO Auto-generated method stub
-      
-   }
-
-   @Override
-   public void stopPinger()
-   {
-      // TODO Auto-generated method stub
-      
-   }
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * pls use factory to create frames.
+ */
+public class StompClientConnectionV10 extends AbstractStompClientConnection
+{
+
+   public StompClientConnectionV10(String host, int port) throws IOException
+   {
+      super("1.0", host, port);
+   }
+
+   public void connect(String username, String passcode) throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+      frame.addHeader(LOGIN_HEADER, username);
+      frame.addHeader(PASSCODE_HEADER, passcode);
+      
+      ClientStompFrame response = this.sendFrame(frame);
+      
+      if (response.getCommand().equals(CONNECTED_COMMAND))
+      {
+         connected = true;
+      }
+      else
+      {
+         System.out.println("Connection failed with: " + response);
+         connected = false;
+      }
+   }
+
+   public void connect(String username, String passcode, String clientID) throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+      frame.addHeader(LOGIN_HEADER, username);
+      frame.addHeader(PASSCODE_HEADER, passcode);
+      frame.addHeader(CLIENT_ID_HEADER, clientID);
+      
+      ClientStompFrame response = this.sendFrame(frame);
+      
+      if (response.getCommand().equals(CONNECTED_COMMAND))
+      {
+         connected = true;
+      }
+      else
+      {
+         System.out.println("Connection failed with: " + response);
+         connected = false;
+      }
+   }
+
+   @Override
+   public void disconnect() throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
+      this.sendFrame(frame);
+      
+      close();
+      
+      connected = false;
+   }
+
+   @Override
+   public ClientStompFrame createFrame(
+         String command)
+   {
+      return new ClientStompFrameV10(command);
+   }
+
+   @Override
+   public void startPinger(long interval)
+   {
+      // TODO Auto-generated method stub
+      
+   }
+
+   @Override
+   public void stopPinger()
+   {
+      // TODO Auto-generated method stub
+      
+   }
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,227 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.IOException;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public class StompClientConnectionV11 extends AbstractStompClientConnection
-{
-   public static final String STOMP_COMMAND = "STOMP";
-   
-   public static final String ACCEPT_HEADER = "accept-version";
-   public static final String HOST_HEADER = "host";
-   public static final String VERSION_HEADER = "version";
-   public static final String RECEIPT_HEADER = "receipt";
-   
-   private Pinger pinger;
-
-   public StompClientConnectionV11(String host, int port) throws IOException
-   {
-      super("1.1", host, port);
-   }
-
-   public void connect(String username, String passcode) throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
-      frame.addHeader(ACCEPT_HEADER, "1.1");
-      frame.addHeader(HOST_HEADER, "localhost");
-      if (username != null)
-      {
-         frame.addHeader(LOGIN_HEADER, username);
-         frame.addHeader(PASSCODE_HEADER, passcode);
-      }
-
-      ClientStompFrame response = this.sendFrame(frame);
-      
-      if (response.getCommand().equals(CONNECTED_COMMAND))
-      {
-         String version = response.getHeader(VERSION_HEADER);
-         assert(version.equals("1.1"));
-         
-         this.username = username;
-         this.passcode = passcode;
-         this.connected = true;
-      }
-      else
-      {
-         connected = false;
-      }
-   }
-   
-   public void connect(String username, String passcode, String clientID) throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
-      frame.addHeader(ACCEPT_HEADER, "1.1");
-      frame.addHeader(HOST_HEADER, "localhost");
-      frame.addHeader(CLIENT_ID_HEADER, clientID);
-      
-      if (username != null)
-      {
-         frame.addHeader(LOGIN_HEADER, username);
-         frame.addHeader(PASSCODE_HEADER, passcode);
-      }
-
-      ClientStompFrame response = this.sendFrame(frame);
-      
-      if (response.getCommand().equals(CONNECTED_COMMAND))
-      {
-         String version = response.getHeader(VERSION_HEADER);
-         assert(version.equals("1.1"));
-         
-         this.username = username;
-         this.passcode = passcode;
-         this.connected = true;
-      }
-      else
-      {
-         connected = false;
-      }
-   }
-
-   public void connect1(String username, String passcode) throws IOException, InterruptedException
-   {
-      ClientStompFrame frame = factory.newFrame(STOMP_COMMAND);
-      frame.addHeader(ACCEPT_HEADER, "1.0,1.1");
-      frame.addHeader(HOST_HEADER, "127.0.0.1");
-      if (username != null)
-      {
-         frame.addHeader(LOGIN_HEADER, username);
-         frame.addHeader(PASSCODE_HEADER, passcode);
-      }
-
-      ClientStompFrame response = this.sendFrame(frame);
-      
-      if (response.getCommand().equals(CONNECTED_COMMAND))
-      {
-         String version = response.getHeader(VERSION_HEADER);
-         assert(version.equals("1.1"));
-         
-         this.username = username;
-         this.passcode = passcode;
-         this.connected = true;
-      }
-      else
-      {
-         System.out.println("Connection failed with frame " + response);
-         connected = false;
-      }
-   }
-
-   @Override
-   public void disconnect() throws IOException, InterruptedException
-   {
-      stopPinger();
-      ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
-      frame.addHeader("receipt", "1");
-      
-      ClientStompFrame result = this.sendFrame(frame);
-      
-      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
-      {
-         throw new IOException("Disconnect failed! " + result);
-      }
-      
-      close();
-      
-      connected = false;
-   }
-
-   @Override
-   public ClientStompFrame createFrame(String command)
-   {
-      return new ClientStompFrameV11(command);
-   }
-
-   @Override
-   public void startPinger(long interval)
-   {
-      pinger = new Pinger(interval);
-      pinger.startPing();
-   }
-
-   @Override
-   public void stopPinger()
-   {
-      if (pinger != null)
-      {
-         pinger.stopPing();
-         try
-         {
-            pinger.join();
-         }
-         catch (InterruptedException e)
-         {
-            e.printStackTrace();
-         }
-         pinger = null;
-      }
-   }
-   
-   private class Pinger extends Thread
-   {
-      long pingInterval;
-      ClientStompFrameV11 pingFrame;
-      volatile boolean stop = false;
-      
-      public Pinger(long interval)
-      {
-         this.pingInterval = interval;
-         pingFrame = (ClientStompFrameV11) createFrame("STOMP");
-         pingFrame.setBody("\n");
-         pingFrame.setForceOneway();
-      }
-      
-      public void startPing()
-      {
-         start();
-      }
-      
-      public synchronized void stopPing()
-      {
-         stop = true;
-         this.notify();
-      }
-      
-      public void run()
-      {
-         synchronized (this)
-         {
-            while (!stop)
-            {
-               try
-               {
-                  System.out.println("============sending ping");
-                  
-                  sendFrame(pingFrame);
-                  
-                  System.out.println("Pinged " + pingFrame);
-                  
-                  this.wait(pingInterval);
-               }
-               catch (Exception e)
-               {
-                  stop = true;
-                  e.printStackTrace();
-               }
-            }
-            System.out.println("Pinger stopped");
-         }
-      }
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompClientConnectionV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.IOException;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class StompClientConnectionV11 extends AbstractStompClientConnection
+{
+   public static final String STOMP_COMMAND = "STOMP";
+   
+   public static final String ACCEPT_HEADER = "accept-version";
+   public static final String HOST_HEADER = "host";
+   public static final String VERSION_HEADER = "version";
+   public static final String RECEIPT_HEADER = "receipt";
+   
+   private Pinger pinger;
+
+   public StompClientConnectionV11(String host, int port) throws IOException
+   {
+      super("1.1", host, port);
+   }
+
+   public void connect(String username, String passcode) throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+      frame.addHeader(ACCEPT_HEADER, "1.1");
+      frame.addHeader(HOST_HEADER, "localhost");
+      if (username != null)
+      {
+         frame.addHeader(LOGIN_HEADER, username);
+         frame.addHeader(PASSCODE_HEADER, passcode);
+      }
+
+      ClientStompFrame response = this.sendFrame(frame);
+      
+      if (response.getCommand().equals(CONNECTED_COMMAND))
+      {
+         String version = response.getHeader(VERSION_HEADER);
+         assert(version.equals("1.1"));
+         
+         this.username = username;
+         this.passcode = passcode;
+         this.connected = true;
+      }
+      else
+      {
+         connected = false;
+      }
+   }
+   
+   public void connect(String username, String passcode, String clientID) throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(CONNECT_COMMAND);
+      frame.addHeader(ACCEPT_HEADER, "1.1");
+      frame.addHeader(HOST_HEADER, "localhost");
+      frame.addHeader(CLIENT_ID_HEADER, clientID);
+      
+      if (username != null)
+      {
+         frame.addHeader(LOGIN_HEADER, username);
+         frame.addHeader(PASSCODE_HEADER, passcode);
+      }
+
+      ClientStompFrame response = this.sendFrame(frame);
+      
+      if (response.getCommand().equals(CONNECTED_COMMAND))
+      {
+         String version = response.getHeader(VERSION_HEADER);
+         assert(version.equals("1.1"));
+         
+         this.username = username;
+         this.passcode = passcode;
+         this.connected = true;
+      }
+      else
+      {
+         connected = false;
+      }
+   }
+
+   public void connect1(String username, String passcode) throws IOException, InterruptedException
+   {
+      ClientStompFrame frame = factory.newFrame(STOMP_COMMAND);
+      frame.addHeader(ACCEPT_HEADER, "1.0,1.1");
+      frame.addHeader(HOST_HEADER, "127.0.0.1");
+      if (username != null)
+      {
+         frame.addHeader(LOGIN_HEADER, username);
+         frame.addHeader(PASSCODE_HEADER, passcode);
+      }
+
+      ClientStompFrame response = this.sendFrame(frame);
+      
+      if (response.getCommand().equals(CONNECTED_COMMAND))
+      {
+         String version = response.getHeader(VERSION_HEADER);
+         assert(version.equals("1.1"));
+         
+         this.username = username;
+         this.passcode = passcode;
+         this.connected = true;
+      }
+      else
+      {
+         System.out.println("Connection failed with frame " + response);
+         connected = false;
+      }
+   }
+
+   @Override
+   public void disconnect() throws IOException, InterruptedException
+   {
+      stopPinger();
+      ClientStompFrame frame = factory.newFrame(DISCONNECT_COMMAND);
+      frame.addHeader("receipt", "1");
+      
+      ClientStompFrame result = this.sendFrame(frame);
+      
+      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
+      {
+         throw new IOException("Disconnect failed! " + result);
+      }
+      
+      close();
+      
+      connected = false;
+   }
+
+   @Override
+   public ClientStompFrame createFrame(String command)
+   {
+      return new ClientStompFrameV11(command);
+   }
+
+   @Override
+   public void startPinger(long interval)
+   {
+      pinger = new Pinger(interval);
+      pinger.startPing();
+   }
+
+   @Override
+   public void stopPinger()
+   {
+      if (pinger != null)
+      {
+         pinger.stopPing();
+         try
+         {
+            pinger.join();
+         }
+         catch (InterruptedException e)
+         {
+            e.printStackTrace();
+         }
+         pinger = null;
+      }
+   }
+   
+   private class Pinger extends Thread
+   {
+      long pingInterval;
+      ClientStompFrameV11 pingFrame;
+      volatile boolean stop = false;
+      
+      public Pinger(long interval)
+      {
+         this.pingInterval = interval;
+         pingFrame = (ClientStompFrameV11) createFrame("STOMP");
+         pingFrame.setBody("\n");
+         pingFrame.setForceOneway();
+      }
+      
+      public void startPing()
+      {
+         start();
+      }
+      
+      public synchronized void stopPing()
+      {
+         stop = true;
+         this.notify();
+      }
+      
+      public void run()
+      {
+         synchronized (this)
+         {
+            while (!stop)
+            {
+               try
+               {
+                  System.out.println("============sending ping");
+                  
+                  sendFrame(pingFrame);
+                  
+                  System.out.println("Pinged " + pingFrame);
+                  
+                  this.wait(pingInterval);
+               }
+               catch (Exception e)
+               {
+                  stop = true;
+                  e.printStackTrace();
+               }
+            }
+            System.out.println("Pinger stopped");
+         }
+      }
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,27 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public interface StompFrameFactory
-{
-
-   ClientStompFrame createFrame(String data);
-
-   ClientStompFrame newFrame(String command);
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public interface StompFrameFactory
+{
+
+   ClientStompFrame createFrame(String data);
+
+   ClientStompFrame newFrame(String command);
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,37 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- */
-public class StompFrameFactoryFactory
-{
-   public static StompFrameFactory getFactory(String version)
-   {
-      if ("1.0".equals(version))
-      {
-         return new StompFrameFactoryV10();
-      }
-      
-      if ("1.1".equals(version))
-      {
-         return new StompFrameFactoryV11();
-      }
-      
-      return null;
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryFactory.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class StompFrameFactoryFactory
+{
+   public static StompFrameFactory getFactory(String version)
+   {
+      if ("1.0".equals(version))
+      {
+         return new StompFrameFactoryV10();
+      }
+      
+      if ("1.1".equals(version))
+      {
+         return new StompFrameFactoryV11();
+      }
+      
+      return null;
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,71 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.util.StringTokenizer;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * 1.0 frames
- * 
- * 1. CONNECT
- * 2. CONNECTED
- * 3. SEND
- * 4. SUBSCRIBE
- * 5. UNSUBSCRIBE
- * 6. BEGIN
- * 7. COMMIT
- * 8. ACK
- * 9. ABORT
- * 10. DISCONNECT
- * 11. MESSAGE
- * 12. RECEIPT
- * 13. ERROR
- */
-public class StompFrameFactoryV10 implements StompFrameFactory
-{
-
-   public ClientStompFrame createFrame(String data)
-   {
-      //split the string at "\n\n"
-      String[] dataFields = data.split("\n\n");
-      
-      StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
-      
-      String command = tokenizer.nextToken();
-      ClientStompFrame frame = new ClientStompFrameV10(command);
-      
-      while (tokenizer.hasMoreTokens())
-      {
-         String header = tokenizer.nextToken();
-         String[] fields = header.split(":");
-         frame.addHeader(fields[0], fields[1]);
-      }
-      
-      //body (without null byte)
-      if (dataFields.length == 2)
-      {
-         frame.setBody(dataFields[1]);      
-      }
-      return frame;
-   }
-
-   @Override
-   public ClientStompFrame newFrame(String command)
-   {
-      return new ClientStompFrameV10(command);
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV10.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.util.StringTokenizer;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * 1.0 frames
+ * 
+ * 1. CONNECT
+ * 2. CONNECTED
+ * 3. SEND
+ * 4. SUBSCRIBE
+ * 5. UNSUBSCRIBE
+ * 6. BEGIN
+ * 7. COMMIT
+ * 8. ACK
+ * 9. ABORT
+ * 10. DISCONNECT
+ * 11. MESSAGE
+ * 12. RECEIPT
+ * 13. ERROR
+ */
+public class StompFrameFactoryV10 implements StompFrameFactory
+{
+
+   public ClientStompFrame createFrame(String data)
+   {
+      //split the string at "\n\n"
+      String[] dataFields = data.split("\n\n");
+      
+      StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
+      
+      String command = tokenizer.nextToken();
+      ClientStompFrame frame = new ClientStompFrameV10(command);
+      
+      while (tokenizer.hasMoreTokens())
+      {
+         String header = tokenizer.nextToken();
+         String[] fields = header.split(":");
+         frame.addHeader(fields[0], fields[1]);
+      }
+      
+      //body (without null byte)
+      if (dataFields.length == 2)
+      {
+         frame.setBody(dataFields[1]);      
+      }
+      return frame;
+   }
+
+   @Override
+   public ClientStompFrame newFrame(String command)
+   {
+      return new ClientStompFrameV10(command);
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,182 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *    http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.hornetq.tests.integration.stomp.util;
-
-import java.io.UnsupportedEncodingException;
-import java.util.StringTokenizer;
-
-import org.hornetq.core.protocol.stomp.HornetQStompException;
-import org.hornetq.core.protocol.stomp.StompDecoder;
-
-/**
- * 
- * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
- *
- * 1.1 frames
- * 
- * 1. CONNECT/STOMP(new)
- * 2. CONNECTED
- * 3. SEND
- * 4. SUBSCRIBE
- * 5. UNSUBSCRIBE
- * 6. BEGIN
- * 7. COMMIT
- * 8. ACK
- * 9. NACK (new)
- * 10. ABORT
- * 11. DISCONNECT
- * 12. MESSAGE
- * 13. RECEIPT
- * 14. ERROR
- */
-public class StompFrameFactoryV11 implements StompFrameFactory
-{
-
-   @Override
-
-   public ClientStompFrame createFrame(final String data)
-   {
-      //split the string at "\n\n"
-      String[] dataFields = data.split("\n\n");
-      
-      StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
-      
-      String command = tokenizer.nextToken();
-      ClientStompFrame frame = new ClientStompFrameV11(command);
-      
-      while (tokenizer.hasMoreTokens())
-      {
-         String header = tokenizer.nextToken();
-         String[] fields = splitHeader(header);
-         frame.addHeader(fields[0], fields[1]);
-      }
-      
-      //body (without null byte)
-      if (dataFields.length == 2)
-      {
-         frame.setBody(dataFields[1]);      
-      }
-      return frame;
-   }
-   
-   //find true :
-   private String[] splitHeader(String header)
-   {
-      StringBuffer sbKey = new StringBuffer();
-      StringBuffer sbVal = new StringBuffer();
-      boolean isEsc = false;
-      boolean isKey = true;
-      
-      for (int i = 0; i < header.length(); i++)
-      {
-         char b = header.charAt(i);
-
-         switch (b)
-         {
-            //escaping
-            case '\\':
-            {
-               if (isEsc)
-               {
-                  //this is a backslash
-                  if (isKey)
-                  {
-                     sbKey.append(b);
-                  }
-                  else
-                  {
-                     sbVal.append(b);
-                  }
-                  isEsc = false;
-               }
-               else
-               {
-                  //begin escaping
-                  isEsc = true;
-               }
-               break;
-            }
-            case ':':
-            {
-               if (isEsc)
-               {
-                  if (isKey)
-                  {
-                     sbKey.append(b);
-                  }
-                  else
-                  {
-                     sbVal.append(b);
-                  }
-                  isEsc = false;
-               }
-               else
-               {
-                  isKey = false;
-               }
-               break;
-            }
-            case 'n':
-            {
-               if (isEsc)
-               {
-                  if (isKey)
-                  {
-                     sbKey.append('\n');
-                  }
-                  else
-                  {
-                     sbVal.append('\n');
-                  }
-                  isEsc = false;
-               }
-               else
-               {
-                  if (isKey)
-                  {
-                     sbKey.append(b);
-                  }
-                  else
-                  {
-                     sbVal.append(b);
-                  }
-               }
-               break;
-            }
-            default:
-            {
-               if (isKey)
-               {
-                  sbKey.append(b);
-               }
-               else
-               {
-                  sbVal.append(b);
-               }
-            }
-         }
-      }
-      String[] result = new String[2];
-      result[0] = sbKey.toString();
-      result[1] = sbVal.toString();
-      
-      return result;
-   }
-
-   @Override
-   public ClientStompFrame newFrame(String command)
-   {
-      return new ClientStompFrameV11(command);
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/util/StompFrameFactoryV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.util;
+
+import java.io.UnsupportedEncodingException;
+import java.util.StringTokenizer;
+
+import org.hornetq.core.protocol.stomp.HornetQStompException;
+import org.hornetq.core.protocol.stomp.StompDecoder;
+
+/**
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ * 1.1 frames
+ * 
+ * 1. CONNECT/STOMP(new)
+ * 2. CONNECTED
+ * 3. SEND
+ * 4. SUBSCRIBE
+ * 5. UNSUBSCRIBE
+ * 6. BEGIN
+ * 7. COMMIT
+ * 8. ACK
+ * 9. NACK (new)
+ * 10. ABORT
+ * 11. DISCONNECT
+ * 12. MESSAGE
+ * 13. RECEIPT
+ * 14. ERROR
+ */
+public class StompFrameFactoryV11 implements StompFrameFactory
+{
+
+   @Override
+
+   public ClientStompFrame createFrame(final String data)
+   {
+      //split the string at "\n\n"
+      String[] dataFields = data.split("\n\n");
+      
+      StringTokenizer tokenizer = new StringTokenizer(dataFields[0], "\n");
+      
+      String command = tokenizer.nextToken();
+      ClientStompFrame frame = new ClientStompFrameV11(command);
+      
+      while (tokenizer.hasMoreTokens())
+      {
+         String header = tokenizer.nextToken();
+         String[] fields = splitHeader(header);
+         frame.addHeader(fields[0], fields[1]);
+      }
+      
+      //body (without null byte)
+      if (dataFields.length == 2)
+      {
+         frame.setBody(dataFields[1]);      
+      }
+      return frame;
+   }
+   
+   //find true :
+   private String[] splitHeader(String header)
+   {
+      StringBuffer sbKey = new StringBuffer();
+      StringBuffer sbVal = new StringBuffer();
+      boolean isEsc = false;
+      boolean isKey = true;
+      
+      for (int i = 0; i < header.length(); i++)
+      {
+         char b = header.charAt(i);
+
+         switch (b)
+         {
+            //escaping
+            case '\\':
+            {
+               if (isEsc)
+               {
+                  //this is a backslash
+                  if (isKey)
+                  {
+                     sbKey.append(b);
+                  }
+                  else
+                  {
+                     sbVal.append(b);
+                  }
+                  isEsc = false;
+               }
+               else
+               {
+                  //begin escaping
+                  isEsc = true;
+               }
+               break;
+            }
+            case ':':
+            {
+               if (isEsc)
+               {
+                  if (isKey)
+                  {
+                     sbKey.append(b);
+                  }
+                  else
+                  {
+                     sbVal.append(b);
+                  }
+                  isEsc = false;
+               }
+               else
+               {
+                  isKey = false;
+               }
+               break;
+            }
+            case 'n':
+            {
+               if (isEsc)
+               {
+                  if (isKey)
+                  {
+                     sbKey.append('\n');
+                  }
+                  else
+                  {
+                     sbVal.append('\n');
+                  }
+                  isEsc = false;
+               }
+               else
+               {
+                  if (isKey)
+                  {
+                     sbKey.append(b);
+                  }
+                  else
+                  {
+                     sbVal.append(b);
+                  }
+               }
+               break;
+            }
+            default:
+            {
+               if (isKey)
+               {
+                  sbKey.append(b);
+               }
+               else
+               {
+                  sbVal.append(b);
+               }
+            }
+         }
+      }
+      String[] result = new String[2];
+      result[0] = sbKey.toString();
+      result[1] = sbVal.toString();
+      
+      return result;
+   }
+
+   @Override
+   public ClientStompFrame newFrame(String command)
+   {
+      return new ClientStompFrameV11(command);
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,188 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.hornetq.tests.integration.stomp.v11;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Destination;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-
-import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.core.config.Configuration;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
-import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
-import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
-import org.hornetq.core.remoting.impl.netty.TransportConstants;
-import org.hornetq.core.server.HornetQServer;
-import org.hornetq.core.server.HornetQServers;
-import org.hornetq.jms.client.HornetQJMSConnectionFactory;
-import org.hornetq.jms.server.JMSServerManager;
-import org.hornetq.jms.server.config.JMSConfiguration;
-import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
-import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
-import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
-import org.hornetq.jms.server.impl.JMSServerManagerImpl;
-import org.hornetq.spi.core.protocol.ProtocolType;
-import org.hornetq.tests.unit.util.InVMContext;
-import org.hornetq.tests.util.UnitTestCase;
-
-public abstract class StompTestBase2 extends UnitTestCase
-{
-   private static final transient Logger log = Logger.getLogger(StompTestBase2.class);
-
-   protected String hostname = "127.0.0.1";
-   
-   protected int port = 61613;
-
-   private ConnectionFactory connectionFactory;
-
-   private Connection connection;
-
-   protected Session session;
-
-   protected Queue queue;
-
-   protected Topic topic;
-
-   protected JMSServerManager server;
-   
-   protected String defUser = "brianm";
-   
-   protected String defPass = "wombats";
-   
-   
-
-   // Implementation methods
-   // -------------------------------------------------------------------------
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      server = createServer();
-      server.start();
-      connectionFactory = createConnectionFactory();
-
-      connection = connectionFactory.createConnection();
-      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      queue = session.createQueue(getQueueName());
-      topic = session.createTopic(getTopicName());
-      connection.start();
-   }
-
-   /**
-   * @return
-   * @throws Exception 
-   */
-   protected JMSServerManager createServer() throws Exception
-   {
-      Configuration config = createBasicConfig();
-      config.setSecurityEnabled(false);
-      config.setPersistenceEnabled(false);
-
-      Map<String, Object> params = new HashMap<String, Object>();
-      params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
-      params.put(TransportConstants.PORT_PROP_NAME, TransportConstants.DEFAULT_STOMP_PORT);
-      TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
-      config.getAcceptorConfigurations().add(stompTransport);
-      config.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
-      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser, defPass);
-
-      JMSConfiguration jmsConfig = new JMSConfigurationImpl();
-      jmsConfig.getQueueConfigurations()
-               .add(new JMSQueueConfigurationImpl(getQueueName(), null, false, getQueueName()));
-      jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(), getTopicName()));
-      server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
-      server.setContext(new InVMContext());
-      return server;
-   }
-
-   protected void tearDown() throws Exception
-   {
-      connection.close();
-
-      server.stop();
-
-      super.tearDown();
-   }
-
-   protected ConnectionFactory createConnectionFactory()
-   {
-      return new HornetQJMSConnectionFactory(false, new TransportConfiguration(InVMConnectorFactory.class.getName()));
-   }
-
-   protected String getQueueName()
-   {
-      return "test";
-   }
-
-   protected String getQueuePrefix()
-   {
-      return "jms.queue.";
-   }
-
-   protected String getTopicName()
-   {
-      return "testtopic";
-   }
-
-   protected String getTopicPrefix()
-   {
-      return "jms.topic.";
-   }
-
-   public void sendMessage(String msg) throws Exception
-   {
-      sendMessage(msg, queue);
-   }
-
-   public void sendMessage(String msg, Destination destination) throws Exception
-   {
-      MessageProducer producer = session.createProducer(destination);
-      TextMessage message = session.createTextMessage(msg);
-      producer.send(message);
-   }
-
-   public void sendMessage(byte[] data, Destination destination) throws Exception
-   {
-      sendMessage(data, "foo", "xyz", destination);
-   }
-
-   public void sendMessage(String msg, String propertyName, String propertyValue) throws Exception
-   {
-      sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
-   }
-
-   public void sendMessage(byte[] data, String propertyName, String propertyValue, Destination destination) throws Exception
-   {
-      MessageProducer producer = session.createProducer(destination);
-      BytesMessage message = session.createBytesMessage();
-      message.setStringProperty(propertyName, propertyValue);
-      message.writeBytes(data);
-      producer.send(message);
-   }
-
-}

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestBase2.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,188 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.hornetq.tests.integration.stomp.v11;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.config.JMSConfiguration;
+import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
+import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
+import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
+import org.hornetq.jms.server.impl.JMSServerManagerImpl;
+import org.hornetq.spi.core.protocol.ProtocolType;
+import org.hornetq.tests.unit.util.InVMContext;
+import org.hornetq.tests.util.UnitTestCase;
+
+public abstract class StompTestBase2 extends UnitTestCase
+{
+   private static final transient Logger log = Logger.getLogger(StompTestBase2.class);
+
+   protected String hostname = "127.0.0.1";
+   
+   protected int port = 61613;
+
+   private ConnectionFactory connectionFactory;
+
+   private Connection connection;
+
+   protected Session session;
+
+   protected Queue queue;
+
+   protected Topic topic;
+
+   protected JMSServerManager server;
+   
+   protected String defUser = "brianm";
+   
+   protected String defPass = "wombats";
+   
+   
+
+   // Implementation methods
+   // -------------------------------------------------------------------------
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      server = createServer();
+      server.start();
+      connectionFactory = createConnectionFactory();
+
+      connection = connectionFactory.createConnection();
+      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      queue = session.createQueue(getQueueName());
+      topic = session.createTopic(getTopicName());
+      connection.start();
+   }
+
+   /**
+   * @return
+   * @throws Exception 
+   */
+   protected JMSServerManager createServer() throws Exception
+   {
+      Configuration config = createBasicConfig();
+      config.setSecurityEnabled(false);
+      config.setPersistenceEnabled(false);
+
+      Map<String, Object> params = new HashMap<String, Object>();
+      params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
+      params.put(TransportConstants.PORT_PROP_NAME, TransportConstants.DEFAULT_STOMP_PORT);
+      TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
+      config.getAcceptorConfigurations().add(stompTransport);
+      config.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
+      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config, defUser, defPass);
+
+      JMSConfiguration jmsConfig = new JMSConfigurationImpl();
+      jmsConfig.getQueueConfigurations()
+               .add(new JMSQueueConfigurationImpl(getQueueName(), null, false, getQueueName()));
+      jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(), getTopicName()));
+      server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
+      server.setContext(new InVMContext());
+      return server;
+   }
+
+   protected void tearDown() throws Exception
+   {
+      connection.close();
+
+      server.stop();
+
+      super.tearDown();
+   }
+
+   protected ConnectionFactory createConnectionFactory()
+   {
+      return new HornetQJMSConnectionFactory(false, new TransportConfiguration(InVMConnectorFactory.class.getName()));
+   }
+
+   protected String getQueueName()
+   {
+      return "test";
+   }
+
+   protected String getQueuePrefix()
+   {
+      return "jms.queue.";
+   }
+
+   protected String getTopicName()
+   {
+      return "testtopic";
+   }
+
+   protected String getTopicPrefix()
+   {
+      return "jms.topic.";
+   }
+
+   public void sendMessage(String msg) throws Exception
+   {
+      sendMessage(msg, queue);
+   }
+
+   public void sendMessage(String msg, Destination destination) throws Exception
+   {
+      MessageProducer producer = session.createProducer(destination);
+      TextMessage message = session.createTextMessage(msg);
+      producer.send(message);
+   }
+
+   public void sendMessage(byte[] data, Destination destination) throws Exception
+   {
+      sendMessage(data, "foo", "xyz", destination);
+   }
+
+   public void sendMessage(String msg, String propertyName, String propertyValue) throws Exception
+   {
+      sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
+   }
+
+   public void sendMessage(byte[] data, String propertyName, String propertyValue, Destination destination) throws Exception
+   {
+      MessageProducer producer = session.createProducer(destination);
+      BytesMessage message = session.createBytesMessage();
+      message.setStringProperty(propertyName, propertyValue);
+      message.writeBytes(data);
+      producer.send(message);
+   }
+
+}

Deleted: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java
===================================================================
--- branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java	2011-10-12 02:27:00 UTC (rev 11517)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -1,2021 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.hornetq.tests.integration.stomp.v11;
-
-import java.io.IOException;
-import java.nio.channels.ClosedChannelException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.BytesMessage;
-import javax.jms.DeliveryMode;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.TextMessage;
-
-import junit.framework.Assert;
-
-import org.hornetq.core.logging.Logger;
-import org.hornetq.tests.integration.stomp.util.ClientStompFrame;
-import org.hornetq.tests.integration.stomp.util.StompClientConnection;
-import org.hornetq.tests.integration.stomp.util.StompClientConnectionFactory;
-import org.hornetq.tests.integration.stomp.util.StompClientConnectionV11;
-
-/*
- * 
- */
-public class StompTestV11 extends StompTestBase2
-{
-   private static final transient Logger log = Logger.getLogger(StompTestV11.class);
-   
-   private StompClientConnection connV11;
-   
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-   }
-   
-   protected void tearDown() throws Exception
-   {
-      if (connV11.isConnected())
-      {
-         connV11.disconnect();
-      }
-      super.tearDown();
-   }
-   
-   public void testConnection() throws Exception
-   {
-      StompClientConnection connection = StompClientConnectionFactory.createClientConnection("1.0", hostname, port);
-      
-      connection.connect(defUser, defPass);
-      
-      assertTrue(connection.isConnected());
-      
-      assertEquals("1.0", connection.getVersion());
-      
-      connection.disconnect();
-
-      connection = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      
-      connection.connect(defUser, defPass);
-      
-      assertTrue(connection.isConnected());
-      
-      assertEquals("1.1", connection.getVersion());
-      
-      connection.disconnect();
-      
-      connection = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      
-      connection.connect();
-      
-      assertFalse(connection.isConnected());
-      
-      //new way of connection
-      StompClientConnectionV11 conn = (StompClientConnectionV11) StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      conn.connect1(defUser, defPass);
-      
-      assertTrue(conn.isConnected());
-      
-      conn.disconnect();
-   }
-   
-   public void testNegotiation() throws Exception
-   {
-      // case 1 accept-version absent. It is a 1.0 connect
-      ClientStompFrame frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      ClientStompFrame reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      //reply headers: version, session, server
-      assertEquals(null, reply.getHeader("version"));
-
-      connV11.disconnect();
-
-      // case 2 accept-version=1.0, result: 1.0
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("accept-version", "1.0");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      //reply headers: version, session, server
-      assertEquals("1.0", reply.getHeader("version"));
-      
-      connV11.disconnect();
-
-      // case 3 accept-version=1.1, result: 1.1
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("accept-version", "1.1");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      //reply headers: version, session, server
-      assertEquals("1.1", reply.getHeader("version"));
-      
-      connV11.disconnect();
-
-      // case 4 accept-version=1.0,1.1,1.2, result 1.1
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("accept-version", "1.0,1.1,1.2");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      //reply headers: version, session, server
-      assertEquals("1.1", reply.getHeader("version"));
-      
-      connV11.disconnect();
-
-      // case 5 accept-version=1.2, result error
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("accept-version", "1.2");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("ERROR", reply.getCommand());
-      
-      System.out.println("Got error frame " + reply);
-      
-   }
-   
-   public void testSendAndReceive() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "text/plain");
-      frame.setBody("Hello World 1!");
-      
-      ClientStompFrame response = connV11.sendFrame(frame);
-      
-      assertNull(response);
-      
-      frame.addHeader("receipt", "1234");
-      frame.setBody("Hello World 2!");
-      
-      response = connV11.sendFrame(frame);
-      
-      assertNotNull(response);
-      
-      assertEquals("RECEIPT", response.getCommand());
-      
-      assertEquals("1234", response.getHeader("receipt-id"));
-      
-      //subscribe
-      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      newConn.connect(defUser, defPass);
-      
-      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", "a-sub");
-      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      subFrame.addHeader("ack", "auto");
-      
-      newConn.sendFrame(subFrame);
-      
-      frame = newConn.receiveFrame();
-      
-      System.out.println("received " + frame);
-      
-      assertEquals("MESSAGE", frame.getCommand());
-      
-      assertEquals("a-sub", frame.getHeader("subscription"));
-      
-      assertNotNull(frame.getHeader("message-id"));
-      
-      assertEquals(getQueuePrefix() + getQueueName(), frame.getHeader("destination"));
-      
-      assertEquals("Hello World 1!", frame.getBody());
-      
-      frame = newConn.receiveFrame();
-      
-      System.out.println("received " + frame);      
-      
-      //unsub
-      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
-      unsubFrame.addHeader("id", "a-sub");
-      
-      newConn.disconnect();
-   }
-
-   public void testHeaderContentType() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "application/xml");
-      frame.setBody("Hello World 1!");
-      
-      connV11.sendFrame(frame);
-      
-      //subscribe
-      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      newConn.connect(defUser, defPass);
-      
-      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", "a-sub");
-      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      subFrame.addHeader("ack", "auto");
-      
-      newConn.sendFrame(subFrame);
-      
-      frame = newConn.receiveFrame();
-      
-      System.out.println("received " + frame);
-      
-      assertEquals("MESSAGE", frame.getCommand());
-      
-      assertEquals("application/xml", frame.getHeader("content-type"));
-      
-      //unsub
-      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
-      unsubFrame.addHeader("id", "a-sub");
-      
-      newConn.disconnect();
-   }
-
-   public void testHeaderContentLength() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      
-      String body = "Hello World 1!";
-      String cLen = String.valueOf(body.getBytes("UTF-8").length);
-      
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "application/xml");
-      frame.addHeader("content-length", cLen);
-      frame.setBody(body + "extra");
-      
-      connV11.sendFrame(frame);
-      
-      //subscribe
-      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      newConn.connect(defUser, defPass);
-      
-      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", "a-sub");
-      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      subFrame.addHeader("ack", "auto");
-      
-      newConn.sendFrame(subFrame);
-      
-      frame = newConn.receiveFrame();
-      
-      System.out.println("received " + frame);
-      
-      assertEquals("MESSAGE", frame.getCommand());
-      
-      assertEquals(cLen, frame.getHeader("content-length"));
-      
-      //unsub
-      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
-      unsubFrame.addHeader("id", "a-sub");
-      
-      newConn.disconnect();
-   }
-
-   public void testHeaderEncoding() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      
-      String body = "Hello World 1!";
-      String cLen = String.valueOf(body.getBytes("UTF-8").length);
-      
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "application/xml");
-      frame.addHeader("content-length", cLen);
-      String hKey = "special-header\\\\\\n\\:";
-      String hVal = "\\:\\\\\\ngood";
-      frame.addHeader(hKey, hVal);
-      
-      System.out.println("key: |" + hKey + "| val: |" + hVal);
-      
-      frame.setBody(body);
-      
-      connV11.sendFrame(frame);
-      
-      //subscribe
-      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      newConn.connect(defUser, defPass);
-      
-      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", "a-sub");
-      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      subFrame.addHeader("ack", "auto");
-      
-      newConn.sendFrame(subFrame);
-      
-      frame = newConn.receiveFrame();
-      
-      System.out.println("received " + frame);
-      
-      assertEquals("MESSAGE", frame.getCommand());
-      
-      String value = frame.getHeader("special-header" + "\\" + "\n" + ":");
-      
-      assertEquals(":" + "\\" + "\n" + "good", value);
-      
-      //unsub
-      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
-      unsubFrame.addHeader("id", "a-sub");
-      
-      newConn.disconnect();
-   }
-   
-   public void testHeartBeat() throws Exception
-   {
-      //no heart beat at all if heat-beat absent
-      ClientStompFrame frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      
-      ClientStompFrame reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      Thread.sleep(5000);
-      
-      assertEquals(0, connV11.getFrameQueueSize());
-      
-      connV11.disconnect();
-      
-      //no heart beat for (0,0)
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      frame.addHeader("heart-beat", "0,0");
-      frame.addHeader("accept-version", "1.0,1.1");
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      assertEquals("0,0", reply.getHeader("heart-beat"));
-      
-      Thread.sleep(5000);
-      
-      assertEquals(0, connV11.getFrameQueueSize());
-      
-      connV11.disconnect();
-
-      //heart-beat (1,0), should receive a min client ping accepted by server
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      frame.addHeader("heart-beat", "1,0");
-      frame.addHeader("accept-version", "1.0,1.1");
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      assertEquals("0,500", reply.getHeader("heart-beat"));
-      
-      Thread.sleep(2000);
-      
-      //now server side should be disconnected because we didn't send ping for 2 sec
-      frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "text/plain");
-      frame.setBody("Hello World");
-
-      //send will fail
-      try
-      {
-         connV11.sendFrame(frame);
-         fail("connection should have been destroyed by now");
-      }
-      catch (IOException e)
-      {
-         //ignore
-      }
-      
-      //heart-beat (1,0), start a ping, then send a message, should be ok.
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      frame.addHeader("heart-beat", "1,0");
-      frame.addHeader("accept-version", "1.0,1.1");
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      assertEquals("0,500", reply.getHeader("heart-beat"));
-      
-      System.out.println("========== start pinger!");
-      
-      connV11.startPinger(500);
-      
-      Thread.sleep(2000);
-      
-      //now server side should be disconnected because we didn't send ping for 2 sec
-      frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "text/plain");
-      frame.setBody("Hello World");
-
-      //send will be ok
-      connV11.sendFrame(frame);
-      
-      connV11.stopPinger();
-      
-      connV11.disconnect();
-
-   }
-   
-   //server ping
-   public void testHeartBeat2() throws Exception
-   {
-      //heart-beat (1,1)
-      ClientStompFrame frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      frame.addHeader("heart-beat", "1,1");
-      frame.addHeader("accept-version", "1.0,1.1");
-      
-      ClientStompFrame reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      assertEquals("500,500", reply.getHeader("heart-beat"));
-      
-      connV11.disconnect();
-      
-      //heart-beat (500,1000)
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      frame = connV11.createFrame("CONNECT");
-      frame.addHeader("host", "127.0.0.1");
-      frame.addHeader("login", this.defUser);
-      frame.addHeader("passcode", this.defPass);
-      frame.addHeader("heart-beat", "500,1000");
-      frame.addHeader("accept-version", "1.0,1.1");
-      
-      reply = connV11.sendFrame(frame);
-      
-      assertEquals("CONNECTED", reply.getCommand());
-      
-      assertEquals("1000,500", reply.getHeader("heart-beat"));
-      
-      System.out.println("========== start pinger!");
-      
-      connV11.startPinger(500);
-      
-      Thread.sleep(10000);
-      
-      //now check the frame size
-      int size = connV11.getFrameQueueSize();
-      
-      System.out.println("ping received: " + size);
-      
-      assertTrue(size > 5);
-      
-      //now server side should be disconnected because we didn't send ping for 2 sec
-      frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("content-type", "text/plain");
-      frame.setBody("Hello World");
-
-      //send will be ok
-      connV11.sendFrame(frame);
-      
-      connV11.stopPinger();
-      
-      connV11.disconnect();
-
-   }
-   
-   public void testNack() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      nack(connV11, "sub1", messageID);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //Nack makes the message be dropped.
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-
-   public void testNackWithWrongSubId() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      nack(connV11, "sub2", messageID);
-      
-      ClientStompFrame error = connV11.receiveFrame();
-      
-      System.out.println("Receiver error: " + error);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should be still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-   }
-
-   public void testNackWithWrongMessageId() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      nack(connV11, "sub2", "someother");
-      
-      ClientStompFrame error = connV11.receiveFrame();
-      
-      System.out.println("Receiver error: " + error);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-   }
-   
-   
-   public void testAck() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      ack(connV11, "sub1", messageID, null);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //Nack makes the message be dropped.
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-
-   public void testAckWithWrongSubId() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      ack(connV11, "sub2", messageID, null);
-      
-      ClientStompFrame error = connV11.receiveFrame();
-      
-      System.out.println("Receiver error: " + error);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should be still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-   }
-
-   public void testAckWithWrongMessageId() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      ack(connV11, "sub2", "someother", null);
-      
-      ClientStompFrame error = connV11.receiveFrame();
-      
-      System.out.println("Receiver error: " + error);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-   }
-   
-   public void testErrorWithReceipt() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      ClientStompFrame ackFrame = connV11.createFrame("ACK");
-      //give it a wrong sub id
-      ackFrame.addHeader("subscription", "sub2");
-      ackFrame.addHeader("message-id", messageID);
-      ackFrame.addHeader("receipt", "answer-me");
-      
-      ClientStompFrame error = connV11.sendFrame(ackFrame);
-      
-      System.out.println("Receiver error: " + error);
-      
-      assertEquals("ERROR", error.getCommand());
-      
-      assertEquals("answer-me", error.getHeader("receipt-id"));
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);      
-   }
-   
-   public void testErrorWithReceipt2() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      String messageID = frame.getHeader("message-id");
-      
-      System.out.println("Received message with id " + messageID);
-      
-      ClientStompFrame ackFrame = connV11.createFrame("ACK");
-      //give it a wrong sub id
-      ackFrame.addHeader("subscription", "sub1");
-      ackFrame.addHeader("message-id", String.valueOf(Long.valueOf(messageID) + 1));
-      ackFrame.addHeader("receipt", "answer-me");
-      
-      ClientStompFrame error = connV11.sendFrame(ackFrame);
-      
-      System.out.println("Receiver error: " + error);
-      
-      assertEquals("ERROR", error.getCommand());
-      
-      assertEquals("answer-me", error.getHeader("receipt-id"));
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-
-      //message should still there
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);      
-   }
-   
-   public void testAckModeClient() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-      
-      int num = 50;
-      //send a bunch of messages
-      for (int i = 0; i < num; i++)
-      {
-         this.sendMessage("client-ack" + i);
-      }
-      
-      ClientStompFrame frame = null;
-      
-      for (int i = 0; i < num; i++)
-      {
-         frame = connV11.receiveFrame();
-         assertNotNull(frame);
-      }
-      
-      //ack the last
-      this.ack(connV11, "sub1", frame);
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-      
-      //no messages can be received.
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-   
-   public void testAckModeClient2() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client");
-      
-      int num = 50;
-      //send a bunch of messages
-      for (int i = 0; i < num; i++)
-      {
-         this.sendMessage("client-ack" + i);
-      }
-      
-      ClientStompFrame frame = null;
-      
-      for (int i = 0; i < num; i++)
-      {
-         frame = connV11.receiveFrame();
-         assertNotNull(frame);
-
-         //ack the 49th
-         if (i == num - 2)
-         {
-            this.ack(connV11, "sub1", frame);
-         }
-      }
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-      
-      //no messages can be received.
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-      message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-   
-   public void testAckModeAuto() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "auto");
-      
-      int num = 50;
-      //send a bunch of messages
-      for (int i = 0; i < num; i++)
-      {
-         this.sendMessage("auto-ack" + i);
-      }
-      
-      ClientStompFrame frame = null;
-      
-      for (int i = 0; i < num; i++)
-      {
-         frame = connV11.receiveFrame();
-         assertNotNull(frame);
-      }
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-      
-      //no messages can be received.
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-   
-   public void testAckModeClientIndividual() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      subscribe(connV11, "sub1", "client-individual");
-      
-      int num = 50;
-      //send a bunch of messages
-      for (int i = 0; i < num; i++)
-      {
-         this.sendMessage("client-individual-ack" + i);
-      }
-      
-      ClientStompFrame frame = null;
-      
-      for (int i = 0; i < num; i++)
-      {
-         frame = connV11.receiveFrame();
-         assertNotNull(frame);
-         
-         System.out.println(i + " == received: " + frame);
-         //ack on even numbers
-         if (i%2 == 0)
-         {
-            this.ack(connV11, "sub1", frame);
-         }
-      }
-      
-      unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-      
-      //no messages can be received.
-      MessageConsumer consumer = session.createConsumer(queue);
-      
-      TextMessage message = null;
-      for (int i = 0; i < num/2; i++)
-      {
-         message = (TextMessage) consumer.receive(1000);
-         Assert.assertNotNull(message);
-         System.out.println("Legal: " + message.getText());
-      }
-      
-      message = (TextMessage) consumer.receive(1000);
-      
-      Assert.assertNull(message);
-   }
-   
-   public void testTwoSubscribers() throws Exception
-   {
-      connV11.connect(defUser, defPass, "myclientid");
-
-      this.subscribeTopic(connV11, "sub1", "auto", null);
-      
-      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      newConn.connect(defUser, defPass, "myclientid2");
-      
-      this.subscribeTopic(newConn, "sub2", "auto", null);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getTopicPrefix() + getTopicName());
-      
-      frame.setBody("Hello World");
-      
-      connV11.sendFrame(frame);
-      
-      // receive message from socket
-      frame = connV11.receiveFrame(1000);
-      
-      System.out.println("received frame : " + frame);
-      assertEquals("Hello World", frame.getBody());
-      assertEquals("sub1", frame.getHeader("subscription"));
-      
-      frame = newConn.receiveFrame(1000);
-      
-      System.out.println("received 2 frame : " + frame);
-      assertEquals("Hello World", frame.getBody());
-      assertEquals("sub2", frame.getHeader("subscription"));
-      
-      // remove suscription
-      this.unsubscribe(connV11, "sub1", true);
-      this.unsubscribe(newConn, "sub2", true);
-      
-      connV11.disconnect();
-      newConn.disconnect();
-   }
-   
-   public void testSendAndReceiveOnDifferentConnections() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      ClientStompFrame sendFrame = connV11.createFrame("SEND");
-      sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      sendFrame.setBody("Hello World");
-
-      connV11.sendFrame(sendFrame);
-      
-      StompClientConnection connV11_2 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      connV11_2.connect(defUser, defPass);
-      
-      this.subscribe(connV11_2, "sub1", "auto");
-      
-      ClientStompFrame frame = connV11_2.receiveFrame(2000);
-      
-      assertEquals("MESSAGE", frame.getCommand());
-      assertEquals("Hello World", frame.getBody());
-      
-      connV11.disconnect();
-      connV11_2.disconnect();
-   }
-
-   //----------------Note: tests below are adapted from StompTest
-   
-   public void testBeginSameTransactionTwice() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      beginTransaction(connV11, "tx1");
-      
-      beginTransaction(connV11, "tx1");
-      
-      ClientStompFrame f = connV11.receiveFrame();
-      Assert.assertTrue(f.getCommand().equals("ERROR"));
-   }
-
-   public void testBodyWithUTF8() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, getName(), "auto");
-
-      String text = "A" + "\u00ea" + "\u00f1" + "\u00fc" + "C";
-      System.out.println(text);
-      sendMessage(text);
-
-      ClientStompFrame frame = connV11.receiveFrame();
-      System.out.println(frame);
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertNotNull(frame.getHeader("destination"));
-      Assert.assertTrue(frame.getBody().equals(text));
-      
-      connV11.disconnect();
-   }
-   
-   public void testClientAckNotPartOfTransaction() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, getName(), "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertNotNull(frame.getHeader("destination"));
-      Assert.assertTrue(frame.getBody().equals(getName()));
-      Assert.assertNotNull(frame.getHeader("message-id"));
-
-      String messageID = frame.getHeader("message-id");
-
-      beginTransaction(connV11, "tx1");
-
-      this.ack(connV11, getName(), messageID, "tx1");
-
-      abortTransaction(connV11, "tx1");
-
-      frame = connV11.receiveFrame();
-      
-      assertNull(frame);
-
-      this.unsubscribe(connV11, getName());
-
-      connV11.disconnect();
-   }
-
-   public void testDisconnectAndError() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, getName(), "client");
-
-      ClientStompFrame frame = connV11.createFrame("DISCONNECT");
-      frame.addHeader("receipt", "1");
-      
-      ClientStompFrame result = connV11.sendFrame(frame);
-      
-      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
-      {
-         fail("Disconnect failed! " + result);
-      }
-
-      // sending a message will result in an error
-      ClientStompFrame sendFrame = connV11.createFrame("SEND");
-      sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      sendFrame.setBody("Hello World");
-      
-      try
-      {
-         connV11.sendFrame(sendFrame);
-         fail("connection should have been closed by server.");
-      }
-      catch (ClosedChannelException e)
-      {
-         //ok.
-      }
-      
-      connV11.destroy();
-   }
-
-   public void testDurableSubscriber() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "sub1", "client", getName());
-
-      this.subscribe(connV11, "sub1", "client", getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-      Assert.assertTrue(frame.getCommand().equals("ERROR"));
-
-      connV11.disconnect();
-   }
-
-   public void testDurableSubscriberWithReconnection() throws Exception
-   {
-      connV11.connect(defUser, defPass, "myclientid");
-
-      this.subscribeTopic(connV11, "sub1", "auto", getName());
-
-      ClientStompFrame frame = connV11.createFrame("DISCONNECT");
-      frame.addHeader("receipt", "1");
-      
-      ClientStompFrame result = connV11.sendFrame(frame);
-      
-      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
-      {
-         fail("Disconnect failed! " + result);
-      }
-
-      // send the message when the durable subscriber is disconnected
-      sendMessage(getName(), topic);
-
-      connV11.destroy();
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      connV11.connect(defUser, defPass, "myclientid");
-
-      this.subscribeTopic(connV11, "sub1", "auto", getName());
-
-      // we must have received the message
-      frame = connV11.receiveFrame();
-
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertNotNull(frame.getHeader("destination"));
-      Assert.assertEquals(getName(), frame.getBody());
-
-      this.unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-   }
-
-   public void testJMSXGroupIdCanBeSet() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("JMSXGroupID", "TEST");
-      frame.setBody("Hello World");
-      
-      connV11.sendFrame(frame);
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-      // differ from StompConnect
-      Assert.assertEquals("TEST", message.getStringProperty("JMSXGroupID"));
-   }
-
-   public void testMessagesAreInOrder() throws Exception
-   {
-      int ctr = 10;
-      String[] data = new String[ctr];
-
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", "auto");
-
-      for (int i = 0; i < ctr; ++i)
-      {
-         data[i] = getName() + i;
-         sendMessage(data[i]);
-      }
-
-      ClientStompFrame frame = null;
-      
-      for (int i = 0; i < ctr; ++i)
-      {
-         frame = connV11.receiveFrame();
-         Assert.assertTrue("Message not in order", frame.getBody().equals(data[i]));
-      }
-
-      for (int i = 0; i < ctr; ++i)
-      {
-         data[i] = getName() + ":second:" + i;
-         sendMessage(data[i]);
-      }
-
-      for (int i = 0; i < ctr; ++i)
-      {
-         frame = connV11.receiveFrame();
-         Assert.assertTrue("Message not in order", frame.getBody().equals(data[i]));
-      }
-
-      connV11.disconnect();
-   }
-
-   public void testSubscribeWithAutoAckAndSelector() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", "auto", null, "foo = 'zzz'");
-
-      sendMessage("Ignored message", "foo", "1234");
-      sendMessage("Real message", "foo", "zzz");
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertTrue("Should have received the real message but got: " + frame, frame.getBody().equals("Real message"));
-
-      connV11.disconnect();
-   }
-
-   public void testRedeliveryWithClientAck() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "subId", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-      
-      assertTrue(frame.getCommand().equals("MESSAGE"));
-
-      connV11.disconnect();
-
-      // message should be received since message was not acknowledged
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertTrue(message.getJMSRedelivered());
-   }
-
-   public void testSendManyMessages() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      int count = 1000;
-      final CountDownLatch latch = new CountDownLatch(count);
-      consumer.setMessageListener(new MessageListener()
-      {
-         public void onMessage(Message arg0)
-         {
-            latch.countDown();
-         }
-      });
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.setBody("Hello World");
-
-      for (int i = 1; i <= count; i++)
-      {
-         connV11.sendFrame(frame);
-      }
-
-      assertTrue(latch.await(60, TimeUnit.SECONDS));
-      
-      connV11.disconnect();
-   }
-
-   public void testSendMessage() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.setBody("Hello World");
-      
-      connV11.sendFrame(frame);
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-      // Assert default priority 4 is used when priority header is not set
-      Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority());
-
-      // Make sure that the timestamp is valid - should
-      // be very close to the current time.
-      long tnow = System.currentTimeMillis();
-      long tmsg = message.getJMSTimestamp();
-      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
-   }
-
-   public void testSendMessageWithContentLength() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      byte[] data = new byte[] { 1, 0, 0, 4 };
-      
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.setBody(new String(data, "UTF-8"));
-      
-      frame.addHeader("content-length", String.valueOf(data.length));
-
-      connV11.sendFrame(frame);
-      
-      BytesMessage message = (BytesMessage)consumer.receive(10000);
-      Assert.assertNotNull(message);
-
-      assertEquals(data.length, message.getBodyLength());
-      assertEquals(data[0], message.readByte());
-      assertEquals(data[1], message.readByte());
-      assertEquals(data[2], message.readByte());
-      assertEquals(data[3], message.readByte());
-   }
-
-   public void testSendMessageWithCustomHeadersAndSelector() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue, "foo = 'abc'");
-
-      connV11.connect(defUser, defPass);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("foo", "abc");
-      frame.addHeader("bar", "123");
-      
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.setBody("Hello World");
-      
-      connV11.sendFrame(frame);
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-      Assert.assertEquals("foo", "abc", message.getStringProperty("foo"));
-      Assert.assertEquals("bar", "123", message.getStringProperty("bar"));
-   }
-   
-   public void testSendMessageWithLeadingNewLine() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-      
-      ClientStompFrame frame = connV11.createFrame("SEND");
-
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.setBody("Hello World");
-
-      connV11.sendWickedFrame(frame);
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-
-      // Make sure that the timestamp is valid - should
-      // be very close to the current time.
-      long tnow = System.currentTimeMillis();
-      long tmsg = message.getJMSTimestamp();
-      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
-      
-      assertNull(consumer.receive(1000));
-      
-      connV11.disconnect();
-   }
-
-   public void testSendMessageWithReceipt() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("receipt", "1234");
-      frame.setBody("Hello World");
-
-      frame = connV11.sendFrame(frame);
-      
-      assertTrue(frame.getCommand().equals("RECEIPT"));
-      assertEquals("1234", frame.getHeader("receipt-id"));
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-
-      // Make sure that the timestamp is valid - should
-      // be very close to the current time.
-      long tnow = System.currentTimeMillis();
-      long tmsg = message.getJMSTimestamp();
-      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
-      
-      connV11.disconnect();
-   }
-
-   public void testSendMessageWithStandardHeaders() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("correlation-id", "c123");
-      frame.addHeader("persistent", "true");
-      frame.addHeader("priority", "3");
-      frame.addHeader("type", "t345");
-      frame.addHeader("JMSXGroupID", "abc");
-      frame.addHeader("foo", "abc");
-      frame.addHeader("bar", "123");
-
-      frame.setBody("Hello World");
-
-      frame = connV11.sendFrame(frame);
-
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("Hello World", message.getText());
-      Assert.assertEquals("JMSCorrelationID", "c123", message.getJMSCorrelationID());
-      Assert.assertEquals("getJMSType", "t345", message.getJMSType());
-      Assert.assertEquals("getJMSPriority", 3, message.getJMSPriority());
-      Assert.assertEquals(DeliveryMode.PERSISTENT, message.getJMSDeliveryMode());
-      Assert.assertEquals("foo", "abc", message.getStringProperty("foo"));
-      Assert.assertEquals("bar", "123", message.getStringProperty("bar"));
-
-      Assert.assertEquals("JMSXGroupID", "abc", message.getStringProperty("JMSXGroupID"));
-      
-      connV11.disconnect();
-   }
-
-   public void testSubscribeToTopic() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribeTopic(connV11, "sub1", null, null, true);
-
-      sendMessage(getName(), topic);
-      
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix() + getTopicName()));
-      Assert.assertTrue(frame.getBody().equals(getName()));
-
-      this.unsubscribe(connV11, "sub1", true);
-
-      sendMessage(getName(), topic);
-
-      frame = connV11.receiveFrame(1000);
-      assertNull(frame);
-
-      connV11.disconnect();
-   }
-
-   public void testSubscribeToTopicWithNoLocal() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribeTopic(connV11, "sub1", null, null, true, true);
-
-      // send a message on the same connection => it should not be received
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getTopicPrefix() + getTopicName());
-
-      frame.setBody("Hello World");
-
-      connV11.sendFrame(frame);
-
-      frame = connV11.receiveFrame(2000);
-      
-      assertNull(frame);
-
-      // send message on another JMS connection => it should be received
-      sendMessage(getName(), topic);
-
-      frame = connV11.receiveFrame();
-
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix() + getTopicName()));
-      Assert.assertTrue(frame.getBody().equals(getName()));
-      
-      this.unsubscribe(connV11, "sub1");
-      
-      connV11.disconnect();
-   }
-
-   public void testSubscribeWithAutoAck() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "sub1", "auto");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertEquals("MESSAGE", frame.getCommand());
-      Assert.assertNotNull(frame.getHeader("destination"));
-      Assert.assertEquals(getName(), frame.getBody());
-
-      connV11.disconnect();
-      
-      // message should not be received as it was auto-acked
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-
-   public void testSubscribeWithAutoAckAndBytesMessage() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", "auto");
-
-      byte[] payload = new byte[] { 1, 2, 3, 4, 5 };
-      sendMessage(payload, queue);
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      assertEquals("MESSAGE", frame.getCommand());
-      
-      System.out.println("Message: " + frame);
-
-      assertEquals("5", frame.getHeader("content-length"));
-
-      assertEquals(null, frame.getHeader("type"));
-      
-      assertEquals(frame.getBody(), new String(payload, "UTF-8"));
-      
-      connV11.disconnect();
-   }
-
-   public void testSubscribeWithClientAck() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      this.ack(connV11, "sub1", frame);
-
-      connV11.disconnect();
-
-      // message should not be received since message was acknowledged by the client
-      MessageConsumer consumer = session.createConsumer(queue);
-      Message message = consumer.receive(1000);
-      Assert.assertNull(message);
-   }
-
-   public void testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithExplicitDisconnect() throws Exception
-   {
-      assertSubscribeWithClientAckThenConsumeWithAutoAck(true);
-   }
-
-   public void testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithNoDisconnectFrame() throws Exception
-   {
-      assertSubscribeWithClientAckThenConsumeWithAutoAck(false);
-   }
-
-   public void testSubscribeWithID() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "mysubid", "auto");
-
-      sendMessage(getName());
-
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertTrue(frame.getHeader("subscription") != null);
-
-      connV11.disconnect();
-   }
-
-   public void testSubscribeWithMessageSentWithProperties() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", "auto");
-
-      MessageProducer producer = session.createProducer(queue);
-      BytesMessage message = session.createBytesMessage();
-      message.setStringProperty("S", "value");
-      message.setBooleanProperty("n", false);
-      message.setByteProperty("byte", (byte)9);
-      message.setDoubleProperty("d", 2.0);
-      message.setFloatProperty("f", (float)6.0);
-      message.setIntProperty("i", 10);
-      message.setLongProperty("l", 121);
-      message.setShortProperty("s", (short)12);
-      message.writeBytes("Hello World".getBytes("UTF-8"));
-      producer.send(message);
-
-      ClientStompFrame frame = connV11.receiveFrame();
-      Assert.assertNotNull(frame);
-      
-      Assert.assertTrue(frame.getHeader("S") != null);
-      Assert.assertTrue(frame.getHeader("n") != null);
-      Assert.assertTrue(frame.getHeader("byte") != null);
-      Assert.assertTrue(frame.getHeader("d") != null);
-      Assert.assertTrue(frame.getHeader("f") != null);
-      Assert.assertTrue(frame.getHeader("i") != null);
-      Assert.assertTrue(frame.getHeader("l") != null);
-      Assert.assertTrue(frame.getHeader("s") != null);
-      Assert.assertEquals("Hello World", frame.getBody());
-
-      connV11.disconnect();
-   }
-
-   public void testSuccessiveTransactionsWithSameID() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      // first tx
-      this.beginTransaction(connV11, "tx1");
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("transaction", "tx1");
-      frame.setBody("Hello World");
-
-      connV11.sendFrame(frame);
-
-      this.commitTransaction(connV11, "tx1");
-
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull("Should have received a message", message);
-
-      // 2nd tx with same tx ID
-      this.beginTransaction(connV11, "tx1");
-
-      frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("transaction", "tx1");
-      
-      frame.setBody("Hello World");
-      
-      connV11.sendFrame(frame);
-
-      this.commitTransaction(connV11, "tx1");
-
-      message = consumer.receive(1000);
-      Assert.assertNotNull("Should have received a message", message);
-      
-      connV11.disconnect();
-   }
-
-   public void testTransactionCommit() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-
-      this.beginTransaction(connV11, "tx1");
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("transaction", "tx1");
-      frame.addHeader("receipt", "123");
-      frame.setBody("Hello World");
-
-      frame = connV11.sendFrame(frame);
-      
-      assertEquals("123", frame.getHeader("receipt-id"));
-      
-      // check the message is not committed
-      assertNull(consumer.receive(100));
-      
-      this.commitTransaction(connV11, "tx1", true);
-
-      Message message = consumer.receive(1000);
-      Assert.assertNotNull("Should have received a message", message);
-      
-      connV11.disconnect();
-   }
-
-   public void testTransactionRollback() throws Exception
-   {
-      MessageConsumer consumer = session.createConsumer(queue);
-
-      connV11.connect(defUser, defPass);
-      
-      this.beginTransaction(connV11, "tx1");
-
-      ClientStompFrame frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("transaction", "tx1");
-
-      frame.setBody("first message");
-      
-      connV11.sendFrame(frame);
-
-      // rollback first message
-      this.abortTransaction(connV11, "tx1");
-
-      this.beginTransaction(connV11, "tx1");
-
-      frame = connV11.createFrame("SEND");
-      frame.addHeader("destination", getQueuePrefix() + getQueueName());
-      frame.addHeader("transaction", "tx1");
-
-      frame.setBody("second message");
-      
-      connV11.sendFrame(frame);
-
-      this.commitTransaction(connV11, "tx1", true);
-
-      // only second msg should be received since first msg was rolled back
-      TextMessage message = (TextMessage)consumer.receive(1000);
-      Assert.assertNotNull(message);
-      Assert.assertEquals("second message", message.getText());
-      
-      connV11.disconnect();
-   }
-
-   public void testUnsubscribe() throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "sub1", "auto");
-
-      // send a message to our queue
-      sendMessage("first message");
-
-      // receive message from socket
-      ClientStompFrame frame = connV11.receiveFrame();
-      
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-
-      // remove suscription
-      this.unsubscribe(connV11, "sub1", true);
-
-      // send a message to our queue
-      sendMessage("second message");
-
-      frame = connV11.receiveFrame(1000);
-      assertNull(frame);
-      
-      connV11.disconnect();
-   }
-
-   //-----------------private help methods
-
-   private void abortTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
-   {
-      ClientStompFrame abortFrame = conn.createFrame("ABORT");
-      abortFrame.addHeader("transaction", txID);
-
-      conn.sendFrame(abortFrame);
-   }
-
-   private void beginTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
-   {
-      ClientStompFrame beginFrame = conn.createFrame("BEGIN");
-      beginFrame.addHeader("transaction", txID);
-      
-      conn.sendFrame(beginFrame);
-   }
-
-   private void commitTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
-   {
-      commitTransaction(conn, txID, false);
-   }
-
-   private void commitTransaction(StompClientConnection conn, String txID, boolean receipt) throws IOException, InterruptedException
-   {
-      ClientStompFrame beginFrame = conn.createFrame("COMMIT");
-      beginFrame.addHeader("transaction", txID);
-      if (receipt)
-      {
-         beginFrame.addHeader("receipt", "1234");
-      }
-      ClientStompFrame resp = conn.sendFrame(beginFrame);
-      if (receipt)
-      {
-         assertEquals("1234", resp.getHeader("receipt-id"));
-      }
-   }
-
-   private void ack(StompClientConnection conn, String subId,
-         ClientStompFrame frame) throws IOException, InterruptedException
-   {
-      String messageID = frame.getHeader("message-id");
-      
-      ClientStompFrame ackFrame = conn.createFrame("ACK");
-
-      ackFrame.addHeader("subscription", subId);
-      ackFrame.addHeader("message-id", messageID);
-      
-      ClientStompFrame response = conn.sendFrame(ackFrame);
-      if (response != null)
-      {
-         throw new IOException("failed to ack " + response);
-      }
-   }
-
-   private void ack(StompClientConnection conn, String subId, String mid, String txID) throws IOException, InterruptedException
-   {
-      ClientStompFrame ackFrame = conn.createFrame("ACK");
-      ackFrame.addHeader("subscription", subId);
-      ackFrame.addHeader("message-id", mid);
-      if (txID != null)
-      {
-         ackFrame.addHeader("transaction", txID);
-      }
-      
-      conn.sendFrame(ackFrame);
-   }
-
-   private void nack(StompClientConnection conn, String subId, String mid) throws IOException, InterruptedException
-   {
-      ClientStompFrame ackFrame = conn.createFrame("NACK");
-      ackFrame.addHeader("subscription", subId);
-      ackFrame.addHeader("message-id", mid);
-      
-      conn.sendFrame(ackFrame);
-   }
-   
-   private void subscribe(StompClientConnection conn, String subId, String ack) throws IOException, InterruptedException
-   {
-      subscribe(conn, subId, ack, null, null);
-   }
-
-   private void subscribe(StompClientConnection conn, String subId,
-         String ack, String durableId) throws IOException, InterruptedException
-   {
-      subscribe(conn, subId, ack, durableId, null);
-   }
-
-   private void subscribe(StompClientConnection conn, String subId,
-         String ack, String durableId, boolean receipt) throws IOException, InterruptedException
-   {
-      subscribe(conn, subId, ack, durableId, null, receipt);
-   }
-
-   private void subscribe(StompClientConnection conn, String subId, String ack,
-         String durableId, String selector) throws IOException,
-         InterruptedException
-   {
-      subscribe(conn, subId, ack, durableId, selector, false);
-   }
-   
-   private void subscribe(StompClientConnection conn, String subId,
-         String ack, String durableId, String selector, boolean receipt) throws IOException, InterruptedException
-   {
-      ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", subId);
-      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
-      if (ack != null)
-      {
-         subFrame.addHeader("ack", ack);
-      }
-      if (durableId != null)
-      {
-         subFrame.addHeader("durable-subscriber-name", durableId);
-      }
-      if (selector != null)
-      {
-         subFrame.addHeader("selector", selector);
-      }
-      if (receipt)
-      {
-         subFrame.addHeader("receipt", "1234");
-      }
-      
-      subFrame = conn.sendFrame(subFrame);
-      
-      if (receipt)
-      {
-         assertEquals("1234", subFrame.getHeader("receipt-id"));
-      }
-   }
-
-   private void subscribeTopic(StompClientConnection conn, String subId,
-         String ack, String durableId) throws IOException, InterruptedException
-   {
-      subscribeTopic(conn, subId, ack, durableId, false);
-   }
-
-   private void subscribeTopic(StompClientConnection conn, String subId,
-         String ack, String durableId, boolean receipt) throws IOException, InterruptedException
-   {
-      subscribeTopic(conn, subId, ack, durableId, receipt, false);
-   }
-
-   private void subscribeTopic(StompClientConnection conn, String subId,
-         String ack, String durableId, boolean receipt, boolean noLocal) throws IOException, InterruptedException
-   {
-      ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
-      subFrame.addHeader("id", subId);
-      subFrame.addHeader("destination", getTopicPrefix() + getTopicName());
-      if (ack != null)
-      {
-         subFrame.addHeader("ack", ack);
-      }
-      if (durableId != null)
-      {
-         subFrame.addHeader("durable-subscriber-name", durableId);
-      }
-      if (receipt)
-      {
-         subFrame.addHeader("receipt", "1234");
-      }
-      if (noLocal)
-      {
-         subFrame.addHeader("no-local", "true");
-      }
-      
-      ClientStompFrame frame = conn.sendFrame(subFrame);
-      
-      if (receipt)
-      {
-         assertTrue(frame.getHeader("receipt-id").equals("1234"));
-      }
-   }
-
-   private void unsubscribe(StompClientConnection conn, String subId) throws IOException, InterruptedException
-   {
-      ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
-      subFrame.addHeader("id", subId);
-      
-      conn.sendFrame(subFrame);
-   }
-   
-   private void unsubscribe(StompClientConnection conn, String subId,
-         boolean receipt) throws IOException, InterruptedException
-   {
-      ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
-      subFrame.addHeader("id", subId);
-      
-      if (receipt)
-      {
-         subFrame.addHeader("receipt", "4321");
-      }
-      
-      ClientStompFrame f = conn.sendFrame(subFrame);
-      
-      if (receipt)
-      {
-         System.out.println("response: " + f);
-         assertEquals("RECEIPT", f.getCommand());
-         assertEquals("4321", f.getHeader("receipt-id"));
-      }
-   }
-
-   protected void assertSubscribeWithClientAckThenConsumeWithAutoAck(boolean sendDisconnect) throws Exception
-   {
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "sub1", "client");
-
-      sendMessage(getName());
-      
-      ClientStompFrame frame = connV11.receiveFrame();
-
-      Assert.assertEquals("MESSAGE", frame.getCommand());
-
-      log.info("Reconnecting!");
-
-      if (sendDisconnect)
-      {
-         connV11.disconnect();
-         connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      }
-      else
-      {
-         connV11.destroy();
-         connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      }
-
-      // message should be received since message was not acknowledged
-      connV11.connect(defUser, defPass);
-
-      this.subscribe(connV11, "sub1", null);
-
-      frame = connV11.receiveFrame();
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-
-      connV11.disconnect();
-
-      // now lets make sure we don't see the message again
-      connV11.destroy();
-      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
-      connV11.connect(defUser, defPass);
-      
-      this.subscribe(connV11, "sub1", null, null, true);
-
-      sendMessage("shouldBeNextMessage");
-
-      frame = connV11.receiveFrame();
-      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
-      Assert.assertEquals("shouldBeNextMessage", frame.getBody());
-   }
-
-}
-
-
-
-
-

Copied: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java (from rev 11517, branches/STOMP11/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java)
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java	                        (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/stomp/v11/StompTestV11.java	2011-10-12 08:32:14 UTC (rev 11519)
@@ -0,0 +1,2021 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.hornetq.tests.integration.stomp.v11;
+
+import java.io.IOException;
+import java.nio.channels.ClosedChannelException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.jms.BytesMessage;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+
+import org.hornetq.core.logging.Logger;
+import org.hornetq.tests.integration.stomp.util.ClientStompFrame;
+import org.hornetq.tests.integration.stomp.util.StompClientConnection;
+import org.hornetq.tests.integration.stomp.util.StompClientConnectionFactory;
+import org.hornetq.tests.integration.stomp.util.StompClientConnectionV11;
+
+/*
+ * 
+ */
+public class StompTestV11 extends StompTestBase2
+{
+   private static final transient Logger log = Logger.getLogger(StompTestV11.class);
+   
+   private StompClientConnection connV11;
+   
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      if (connV11.isConnected())
+      {
+         connV11.disconnect();
+      }
+      super.tearDown();
+   }
+   
+   public void testConnection() throws Exception
+   {
+      StompClientConnection connection = StompClientConnectionFactory.createClientConnection("1.0", hostname, port);
+      
+      connection.connect(defUser, defPass);
+      
+      assertTrue(connection.isConnected());
+      
+      assertEquals("1.0", connection.getVersion());
+      
+      connection.disconnect();
+
+      connection = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      
+      connection.connect(defUser, defPass);
+      
+      assertTrue(connection.isConnected());
+      
+      assertEquals("1.1", connection.getVersion());
+      
+      connection.disconnect();
+      
+      connection = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      
+      connection.connect();
+      
+      assertFalse(connection.isConnected());
+      
+      //new way of connection
+      StompClientConnectionV11 conn = (StompClientConnectionV11) StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      conn.connect1(defUser, defPass);
+      
+      assertTrue(conn.isConnected());
+      
+      conn.disconnect();
+   }
+   
+   public void testNegotiation() throws Exception
+   {
+      // case 1 accept-version absent. It is a 1.0 connect
+      ClientStompFrame frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      ClientStompFrame reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      //reply headers: version, session, server
+      assertEquals(null, reply.getHeader("version"));
+
+      connV11.disconnect();
+
+      // case 2 accept-version=1.0, result: 1.0
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("accept-version", "1.0");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      //reply headers: version, session, server
+      assertEquals("1.0", reply.getHeader("version"));
+      
+      connV11.disconnect();
+
+      // case 3 accept-version=1.1, result: 1.1
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("accept-version", "1.1");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      //reply headers: version, session, server
+      assertEquals("1.1", reply.getHeader("version"));
+      
+      connV11.disconnect();
+
+      // case 4 accept-version=1.0,1.1,1.2, result 1.1
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("accept-version", "1.0,1.1,1.2");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      //reply headers: version, session, server
+      assertEquals("1.1", reply.getHeader("version"));
+      
+      connV11.disconnect();
+
+      // case 5 accept-version=1.2, result error
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("accept-version", "1.2");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("ERROR", reply.getCommand());
+      
+      System.out.println("Got error frame " + reply);
+      
+   }
+   
+   public void testSendAndReceive() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "text/plain");
+      frame.setBody("Hello World 1!");
+      
+      ClientStompFrame response = connV11.sendFrame(frame);
+      
+      assertNull(response);
+      
+      frame.addHeader("receipt", "1234");
+      frame.setBody("Hello World 2!");
+      
+      response = connV11.sendFrame(frame);
+      
+      assertNotNull(response);
+      
+      assertEquals("RECEIPT", response.getCommand());
+      
+      assertEquals("1234", response.getHeader("receipt-id"));
+      
+      //subscribe
+      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      newConn.connect(defUser, defPass);
+      
+      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", "a-sub");
+      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      subFrame.addHeader("ack", "auto");
+      
+      newConn.sendFrame(subFrame);
+      
+      frame = newConn.receiveFrame();
+      
+      System.out.println("received " + frame);
+      
+      assertEquals("MESSAGE", frame.getCommand());
+      
+      assertEquals("a-sub", frame.getHeader("subscription"));
+      
+      assertNotNull(frame.getHeader("message-id"));
+      
+      assertEquals(getQueuePrefix() + getQueueName(), frame.getHeader("destination"));
+      
+      assertEquals("Hello World 1!", frame.getBody());
+      
+      frame = newConn.receiveFrame();
+      
+      System.out.println("received " + frame);      
+      
+      //unsub
+      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+      unsubFrame.addHeader("id", "a-sub");
+      
+      newConn.disconnect();
+   }
+
+   public void testHeaderContentType() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "application/xml");
+      frame.setBody("Hello World 1!");
+      
+      connV11.sendFrame(frame);
+      
+      //subscribe
+      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      newConn.connect(defUser, defPass);
+      
+      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", "a-sub");
+      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      subFrame.addHeader("ack", "auto");
+      
+      newConn.sendFrame(subFrame);
+      
+      frame = newConn.receiveFrame();
+      
+      System.out.println("received " + frame);
+      
+      assertEquals("MESSAGE", frame.getCommand());
+      
+      assertEquals("application/xml", frame.getHeader("content-type"));
+      
+      //unsub
+      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+      unsubFrame.addHeader("id", "a-sub");
+      
+      newConn.disconnect();
+   }
+
+   public void testHeaderContentLength() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      
+      String body = "Hello World 1!";
+      String cLen = String.valueOf(body.getBytes("UTF-8").length);
+      
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "application/xml");
+      frame.addHeader("content-length", cLen);
+      frame.setBody(body + "extra");
+      
+      connV11.sendFrame(frame);
+      
+      //subscribe
+      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      newConn.connect(defUser, defPass);
+      
+      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", "a-sub");
+      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      subFrame.addHeader("ack", "auto");
+      
+      newConn.sendFrame(subFrame);
+      
+      frame = newConn.receiveFrame();
+      
+      System.out.println("received " + frame);
+      
+      assertEquals("MESSAGE", frame.getCommand());
+      
+      assertEquals(cLen, frame.getHeader("content-length"));
+      
+      //unsub
+      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+      unsubFrame.addHeader("id", "a-sub");
+      
+      newConn.disconnect();
+   }
+
+   public void testHeaderEncoding() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      
+      String body = "Hello World 1!";
+      String cLen = String.valueOf(body.getBytes("UTF-8").length);
+      
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "application/xml");
+      frame.addHeader("content-length", cLen);
+      String hKey = "special-header\\\\\\n\\:";
+      String hVal = "\\:\\\\\\ngood";
+      frame.addHeader(hKey, hVal);
+      
+      System.out.println("key: |" + hKey + "| val: |" + hVal);
+      
+      frame.setBody(body);
+      
+      connV11.sendFrame(frame);
+      
+      //subscribe
+      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      newConn.connect(defUser, defPass);
+      
+      ClientStompFrame subFrame = newConn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", "a-sub");
+      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      subFrame.addHeader("ack", "auto");
+      
+      newConn.sendFrame(subFrame);
+      
+      frame = newConn.receiveFrame();
+      
+      System.out.println("received " + frame);
+      
+      assertEquals("MESSAGE", frame.getCommand());
+      
+      String value = frame.getHeader("special-header" + "\\" + "\n" + ":");
+      
+      assertEquals(":" + "\\" + "\n" + "good", value);
+      
+      //unsub
+      ClientStompFrame unsubFrame = newConn.createFrame("UNSUBSCRIBE");
+      unsubFrame.addHeader("id", "a-sub");
+      
+      newConn.disconnect();
+   }
+   
+   public void testHeartBeat() throws Exception
+   {
+      //no heart beat at all if heat-beat absent
+      ClientStompFrame frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      
+      ClientStompFrame reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      Thread.sleep(5000);
+      
+      assertEquals(0, connV11.getFrameQueueSize());
+      
+      connV11.disconnect();
+      
+      //no heart beat for (0,0)
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      frame.addHeader("heart-beat", "0,0");
+      frame.addHeader("accept-version", "1.0,1.1");
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      assertEquals("0,0", reply.getHeader("heart-beat"));
+      
+      Thread.sleep(5000);
+      
+      assertEquals(0, connV11.getFrameQueueSize());
+      
+      connV11.disconnect();
+
+      //heart-beat (1,0), should receive a min client ping accepted by server
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      frame.addHeader("heart-beat", "1,0");
+      frame.addHeader("accept-version", "1.0,1.1");
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      assertEquals("0,500", reply.getHeader("heart-beat"));
+      
+      Thread.sleep(2000);
+      
+      //now server side should be disconnected because we didn't send ping for 2 sec
+      frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "text/plain");
+      frame.setBody("Hello World");
+
+      //send will fail
+      try
+      {
+         connV11.sendFrame(frame);
+         fail("connection should have been destroyed by now");
+      }
+      catch (IOException e)
+      {
+         //ignore
+      }
+      
+      //heart-beat (1,0), start a ping, then send a message, should be ok.
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      frame.addHeader("heart-beat", "1,0");
+      frame.addHeader("accept-version", "1.0,1.1");
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      assertEquals("0,500", reply.getHeader("heart-beat"));
+      
+      System.out.println("========== start pinger!");
+      
+      connV11.startPinger(500);
+      
+      Thread.sleep(2000);
+      
+      //now server side should be disconnected because we didn't send ping for 2 sec
+      frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "text/plain");
+      frame.setBody("Hello World");
+
+      //send will be ok
+      connV11.sendFrame(frame);
+      
+      connV11.stopPinger();
+      
+      connV11.disconnect();
+
+   }
+   
+   //server ping
+   public void testHeartBeat2() throws Exception
+   {
+      //heart-beat (1,1)
+      ClientStompFrame frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      frame.addHeader("heart-beat", "1,1");
+      frame.addHeader("accept-version", "1.0,1.1");
+      
+      ClientStompFrame reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      assertEquals("500,500", reply.getHeader("heart-beat"));
+      
+      connV11.disconnect();
+      
+      //heart-beat (500,1000)
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      frame = connV11.createFrame("CONNECT");
+      frame.addHeader("host", "127.0.0.1");
+      frame.addHeader("login", this.defUser);
+      frame.addHeader("passcode", this.defPass);
+      frame.addHeader("heart-beat", "500,1000");
+      frame.addHeader("accept-version", "1.0,1.1");
+      
+      reply = connV11.sendFrame(frame);
+      
+      assertEquals("CONNECTED", reply.getCommand());
+      
+      assertEquals("1000,500", reply.getHeader("heart-beat"));
+      
+      System.out.println("========== start pinger!");
+      
+      connV11.startPinger(500);
+      
+      Thread.sleep(10000);
+      
+      //now check the frame size
+      int size = connV11.getFrameQueueSize();
+      
+      System.out.println("ping received: " + size);
+      
+      assertTrue(size > 5);
+      
+      //now server side should be disconnected because we didn't send ping for 2 sec
+      frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("content-type", "text/plain");
+      frame.setBody("Hello World");
+
+      //send will be ok
+      connV11.sendFrame(frame);
+      
+      connV11.stopPinger();
+      
+      connV11.disconnect();
+
+   }
+   
+   public void testNack() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      nack(connV11, "sub1", messageID);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //Nack makes the message be dropped.
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+
+   public void testNackWithWrongSubId() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      nack(connV11, "sub2", messageID);
+      
+      ClientStompFrame error = connV11.receiveFrame();
+      
+      System.out.println("Receiver error: " + error);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should be still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+   }
+
+   public void testNackWithWrongMessageId() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      nack(connV11, "sub2", "someother");
+      
+      ClientStompFrame error = connV11.receiveFrame();
+      
+      System.out.println("Receiver error: " + error);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+   }
+   
+   
+   public void testAck() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      ack(connV11, "sub1", messageID, null);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //Nack makes the message be dropped.
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+
+   public void testAckWithWrongSubId() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      ack(connV11, "sub2", messageID, null);
+      
+      ClientStompFrame error = connV11.receiveFrame();
+      
+      System.out.println("Receiver error: " + error);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should be still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+   }
+
+   public void testAckWithWrongMessageId() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      ack(connV11, "sub2", "someother", null);
+      
+      ClientStompFrame error = connV11.receiveFrame();
+      
+      System.out.println("Receiver error: " + error);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+   }
+   
+   public void testErrorWithReceipt() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      ClientStompFrame ackFrame = connV11.createFrame("ACK");
+      //give it a wrong sub id
+      ackFrame.addHeader("subscription", "sub2");
+      ackFrame.addHeader("message-id", messageID);
+      ackFrame.addHeader("receipt", "answer-me");
+      
+      ClientStompFrame error = connV11.sendFrame(ackFrame);
+      
+      System.out.println("Receiver error: " + error);
+      
+      assertEquals("ERROR", error.getCommand());
+      
+      assertEquals("answer-me", error.getHeader("receipt-id"));
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);      
+   }
+   
+   public void testErrorWithReceipt2() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      String messageID = frame.getHeader("message-id");
+      
+      System.out.println("Received message with id " + messageID);
+      
+      ClientStompFrame ackFrame = connV11.createFrame("ACK");
+      //give it a wrong sub id
+      ackFrame.addHeader("subscription", "sub1");
+      ackFrame.addHeader("message-id", String.valueOf(Long.valueOf(messageID) + 1));
+      ackFrame.addHeader("receipt", "answer-me");
+      
+      ClientStompFrame error = connV11.sendFrame(ackFrame);
+      
+      System.out.println("Receiver error: " + error);
+      
+      assertEquals("ERROR", error.getCommand());
+      
+      assertEquals("answer-me", error.getHeader("receipt-id"));
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+
+      //message should still there
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);      
+   }
+   
+   public void testAckModeClient() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+      
+      int num = 50;
+      //send a bunch of messages
+      for (int i = 0; i < num; i++)
+      {
+         this.sendMessage("client-ack" + i);
+      }
+      
+      ClientStompFrame frame = null;
+      
+      for (int i = 0; i < num; i++)
+      {
+         frame = connV11.receiveFrame();
+         assertNotNull(frame);
+      }
+      
+      //ack the last
+      this.ack(connV11, "sub1", frame);
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+      
+      //no messages can be received.
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+   
+   public void testAckModeClient2() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client");
+      
+      int num = 50;
+      //send a bunch of messages
+      for (int i = 0; i < num; i++)
+      {
+         this.sendMessage("client-ack" + i);
+      }
+      
+      ClientStompFrame frame = null;
+      
+      for (int i = 0; i < num; i++)
+      {
+         frame = connV11.receiveFrame();
+         assertNotNull(frame);
+
+         //ack the 49th
+         if (i == num - 2)
+         {
+            this.ack(connV11, "sub1", frame);
+         }
+      }
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+      
+      //no messages can be received.
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+      message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+   
+   public void testAckModeAuto() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "auto");
+      
+      int num = 50;
+      //send a bunch of messages
+      for (int i = 0; i < num; i++)
+      {
+         this.sendMessage("auto-ack" + i);
+      }
+      
+      ClientStompFrame frame = null;
+      
+      for (int i = 0; i < num; i++)
+      {
+         frame = connV11.receiveFrame();
+         assertNotNull(frame);
+      }
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+      
+      //no messages can be received.
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+   
+   public void testAckModeClientIndividual() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      subscribe(connV11, "sub1", "client-individual");
+      
+      int num = 50;
+      //send a bunch of messages
+      for (int i = 0; i < num; i++)
+      {
+         this.sendMessage("client-individual-ack" + i);
+      }
+      
+      ClientStompFrame frame = null;
+      
+      for (int i = 0; i < num; i++)
+      {
+         frame = connV11.receiveFrame();
+         assertNotNull(frame);
+         
+         System.out.println(i + " == received: " + frame);
+         //ack on even numbers
+         if (i%2 == 0)
+         {
+            this.ack(connV11, "sub1", frame);
+         }
+      }
+      
+      unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+      
+      //no messages can be received.
+      MessageConsumer consumer = session.createConsumer(queue);
+      
+      TextMessage message = null;
+      for (int i = 0; i < num/2; i++)
+      {
+         message = (TextMessage) consumer.receive(1000);
+         Assert.assertNotNull(message);
+         System.out.println("Legal: " + message.getText());
+      }
+      
+      message = (TextMessage) consumer.receive(1000);
+      
+      Assert.assertNull(message);
+   }
+   
+   public void testTwoSubscribers() throws Exception
+   {
+      connV11.connect(defUser, defPass, "myclientid");
+
+      this.subscribeTopic(connV11, "sub1", "auto", null);
+      
+      StompClientConnection newConn = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      newConn.connect(defUser, defPass, "myclientid2");
+      
+      this.subscribeTopic(newConn, "sub2", "auto", null);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getTopicPrefix() + getTopicName());
+      
+      frame.setBody("Hello World");
+      
+      connV11.sendFrame(frame);
+      
+      // receive message from socket
+      frame = connV11.receiveFrame(1000);
+      
+      System.out.println("received frame : " + frame);
+      assertEquals("Hello World", frame.getBody());
+      assertEquals("sub1", frame.getHeader("subscription"));
+      
+      frame = newConn.receiveFrame(1000);
+      
+      System.out.println("received 2 frame : " + frame);
+      assertEquals("Hello World", frame.getBody());
+      assertEquals("sub2", frame.getHeader("subscription"));
+      
+      // remove suscription
+      this.unsubscribe(connV11, "sub1", true);
+      this.unsubscribe(newConn, "sub2", true);
+      
+      connV11.disconnect();
+      newConn.disconnect();
+   }
+   
+   public void testSendAndReceiveOnDifferentConnections() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      ClientStompFrame sendFrame = connV11.createFrame("SEND");
+      sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      sendFrame.setBody("Hello World");
+
+      connV11.sendFrame(sendFrame);
+      
+      StompClientConnection connV11_2 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      connV11_2.connect(defUser, defPass);
+      
+      this.subscribe(connV11_2, "sub1", "auto");
+      
+      ClientStompFrame frame = connV11_2.receiveFrame(2000);
+      
+      assertEquals("MESSAGE", frame.getCommand());
+      assertEquals("Hello World", frame.getBody());
+      
+      connV11.disconnect();
+      connV11_2.disconnect();
+   }
+
+   //----------------Note: tests below are adapted from StompTest
+   
+   public void testBeginSameTransactionTwice() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      beginTransaction(connV11, "tx1");
+      
+      beginTransaction(connV11, "tx1");
+      
+      ClientStompFrame f = connV11.receiveFrame();
+      Assert.assertTrue(f.getCommand().equals("ERROR"));
+   }
+
+   public void testBodyWithUTF8() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, getName(), "auto");
+
+      String text = "A" + "\u00ea" + "\u00f1" + "\u00fc" + "C";
+      System.out.println(text);
+      sendMessage(text);
+
+      ClientStompFrame frame = connV11.receiveFrame();
+      System.out.println(frame);
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertNotNull(frame.getHeader("destination"));
+      Assert.assertTrue(frame.getBody().equals(text));
+      
+      connV11.disconnect();
+   }
+   
+   public void testClientAckNotPartOfTransaction() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, getName(), "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertNotNull(frame.getHeader("destination"));
+      Assert.assertTrue(frame.getBody().equals(getName()));
+      Assert.assertNotNull(frame.getHeader("message-id"));
+
+      String messageID = frame.getHeader("message-id");
+
+      beginTransaction(connV11, "tx1");
+
+      this.ack(connV11, getName(), messageID, "tx1");
+
+      abortTransaction(connV11, "tx1");
+
+      frame = connV11.receiveFrame();
+      
+      assertNull(frame);
+
+      this.unsubscribe(connV11, getName());
+
+      connV11.disconnect();
+   }
+
+   public void testDisconnectAndError() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, getName(), "client");
+
+      ClientStompFrame frame = connV11.createFrame("DISCONNECT");
+      frame.addHeader("receipt", "1");
+      
+      ClientStompFrame result = connV11.sendFrame(frame);
+      
+      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
+      {
+         fail("Disconnect failed! " + result);
+      }
+
+      // sending a message will result in an error
+      ClientStompFrame sendFrame = connV11.createFrame("SEND");
+      sendFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      sendFrame.setBody("Hello World");
+      
+      try
+      {
+         connV11.sendFrame(sendFrame);
+         fail("connection should have been closed by server.");
+      }
+      catch (ClosedChannelException e)
+      {
+         //ok.
+      }
+      
+      connV11.destroy();
+   }
+
+   public void testDurableSubscriber() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "sub1", "client", getName());
+
+      this.subscribe(connV11, "sub1", "client", getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+      Assert.assertTrue(frame.getCommand().equals("ERROR"));
+
+      connV11.disconnect();
+   }
+
+   public void testDurableSubscriberWithReconnection() throws Exception
+   {
+      connV11.connect(defUser, defPass, "myclientid");
+
+      this.subscribeTopic(connV11, "sub1", "auto", getName());
+
+      ClientStompFrame frame = connV11.createFrame("DISCONNECT");
+      frame.addHeader("receipt", "1");
+      
+      ClientStompFrame result = connV11.sendFrame(frame);
+      
+      if (result == null || (!"RECEIPT".equals(result.getCommand())) || (!"1".equals(result.getHeader("receipt-id"))))
+      {
+         fail("Disconnect failed! " + result);
+      }
+
+      // send the message when the durable subscriber is disconnected
+      sendMessage(getName(), topic);
+
+      connV11.destroy();
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      connV11.connect(defUser, defPass, "myclientid");
+
+      this.subscribeTopic(connV11, "sub1", "auto", getName());
+
+      // we must have received the message
+      frame = connV11.receiveFrame();
+
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertNotNull(frame.getHeader("destination"));
+      Assert.assertEquals(getName(), frame.getBody());
+
+      this.unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+   }
+
+   public void testJMSXGroupIdCanBeSet() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("JMSXGroupID", "TEST");
+      frame.setBody("Hello World");
+      
+      connV11.sendFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+      // differ from StompConnect
+      Assert.assertEquals("TEST", message.getStringProperty("JMSXGroupID"));
+   }
+
+   public void testMessagesAreInOrder() throws Exception
+   {
+      int ctr = 10;
+      String[] data = new String[ctr];
+
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", "auto");
+
+      for (int i = 0; i < ctr; ++i)
+      {
+         data[i] = getName() + i;
+         sendMessage(data[i]);
+      }
+
+      ClientStompFrame frame = null;
+      
+      for (int i = 0; i < ctr; ++i)
+      {
+         frame = connV11.receiveFrame();
+         Assert.assertTrue("Message not in order", frame.getBody().equals(data[i]));
+      }
+
+      for (int i = 0; i < ctr; ++i)
+      {
+         data[i] = getName() + ":second:" + i;
+         sendMessage(data[i]);
+      }
+
+      for (int i = 0; i < ctr; ++i)
+      {
+         frame = connV11.receiveFrame();
+         Assert.assertTrue("Message not in order", frame.getBody().equals(data[i]));
+      }
+
+      connV11.disconnect();
+   }
+
+   public void testSubscribeWithAutoAckAndSelector() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", "auto", null, "foo = 'zzz'");
+
+      sendMessage("Ignored message", "foo", "1234");
+      sendMessage("Real message", "foo", "zzz");
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertTrue("Should have received the real message but got: " + frame, frame.getBody().equals("Real message"));
+
+      connV11.disconnect();
+   }
+
+   public void testRedeliveryWithClientAck() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "subId", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+      
+      assertTrue(frame.getCommand().equals("MESSAGE"));
+
+      connV11.disconnect();
+
+      // message should be received since message was not acknowledged
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertTrue(message.getJMSRedelivered());
+   }
+
+   public void testSendManyMessages() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      int count = 1000;
+      final CountDownLatch latch = new CountDownLatch(count);
+      consumer.setMessageListener(new MessageListener()
+      {
+         public void onMessage(Message arg0)
+         {
+            latch.countDown();
+         }
+      });
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.setBody("Hello World");
+
+      for (int i = 1; i <= count; i++)
+      {
+         connV11.sendFrame(frame);
+      }
+
+      assertTrue(latch.await(60, TimeUnit.SECONDS));
+      
+      connV11.disconnect();
+   }
+
+   public void testSendMessage() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.setBody("Hello World");
+      
+      connV11.sendFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+      // Assert default priority 4 is used when priority header is not set
+      Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority());
+
+      // Make sure that the timestamp is valid - should
+      // be very close to the current time.
+      long tnow = System.currentTimeMillis();
+      long tmsg = message.getJMSTimestamp();
+      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+   }
+
+   public void testSendMessageWithContentLength() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      byte[] data = new byte[] { 1, 0, 0, 4 };
+      
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.setBody(new String(data, "UTF-8"));
+      
+      frame.addHeader("content-length", String.valueOf(data.length));
+
+      connV11.sendFrame(frame);
+      
+      BytesMessage message = (BytesMessage)consumer.receive(10000);
+      Assert.assertNotNull(message);
+
+      assertEquals(data.length, message.getBodyLength());
+      assertEquals(data[0], message.readByte());
+      assertEquals(data[1], message.readByte());
+      assertEquals(data[2], message.readByte());
+      assertEquals(data[3], message.readByte());
+   }
+
+   public void testSendMessageWithCustomHeadersAndSelector() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue, "foo = 'abc'");
+
+      connV11.connect(defUser, defPass);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("foo", "abc");
+      frame.addHeader("bar", "123");
+      
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.setBody("Hello World");
+      
+      connV11.sendFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+      Assert.assertEquals("foo", "abc", message.getStringProperty("foo"));
+      Assert.assertEquals("bar", "123", message.getStringProperty("bar"));
+   }
+   
+   public void testSendMessageWithLeadingNewLine() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+      
+      ClientStompFrame frame = connV11.createFrame("SEND");
+
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.setBody("Hello World");
+
+      connV11.sendWickedFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+
+      // Make sure that the timestamp is valid - should
+      // be very close to the current time.
+      long tnow = System.currentTimeMillis();
+      long tmsg = message.getJMSTimestamp();
+      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+      
+      assertNull(consumer.receive(1000));
+      
+      connV11.disconnect();
+   }
+
+   public void testSendMessageWithReceipt() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("receipt", "1234");
+      frame.setBody("Hello World");
+
+      frame = connV11.sendFrame(frame);
+      
+      assertTrue(frame.getCommand().equals("RECEIPT"));
+      assertEquals("1234", frame.getHeader("receipt-id"));
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+
+      // Make sure that the timestamp is valid - should
+      // be very close to the current time.
+      long tnow = System.currentTimeMillis();
+      long tmsg = message.getJMSTimestamp();
+      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+      
+      connV11.disconnect();
+   }
+
+   public void testSendMessageWithStandardHeaders() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("correlation-id", "c123");
+      frame.addHeader("persistent", "true");
+      frame.addHeader("priority", "3");
+      frame.addHeader("type", "t345");
+      frame.addHeader("JMSXGroupID", "abc");
+      frame.addHeader("foo", "abc");
+      frame.addHeader("bar", "123");
+
+      frame.setBody("Hello World");
+
+      frame = connV11.sendFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+      Assert.assertEquals("JMSCorrelationID", "c123", message.getJMSCorrelationID());
+      Assert.assertEquals("getJMSType", "t345", message.getJMSType());
+      Assert.assertEquals("getJMSPriority", 3, message.getJMSPriority());
+      Assert.assertEquals(DeliveryMode.PERSISTENT, message.getJMSDeliveryMode());
+      Assert.assertEquals("foo", "abc", message.getStringProperty("foo"));
+      Assert.assertEquals("bar", "123", message.getStringProperty("bar"));
+
+      Assert.assertEquals("JMSXGroupID", "abc", message.getStringProperty("JMSXGroupID"));
+      
+      connV11.disconnect();
+   }
+
+   public void testSubscribeToTopic() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribeTopic(connV11, "sub1", null, null, true);
+
+      sendMessage(getName(), topic);
+      
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix() + getTopicName()));
+      Assert.assertTrue(frame.getBody().equals(getName()));
+
+      this.unsubscribe(connV11, "sub1", true);
+
+      sendMessage(getName(), topic);
+
+      frame = connV11.receiveFrame(1000);
+      assertNull(frame);
+
+      connV11.disconnect();
+   }
+
+   public void testSubscribeToTopicWithNoLocal() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribeTopic(connV11, "sub1", null, null, true, true);
+
+      // send a message on the same connection => it should not be received
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getTopicPrefix() + getTopicName());
+
+      frame.setBody("Hello World");
+
+      connV11.sendFrame(frame);
+
+      frame = connV11.receiveFrame(2000);
+      
+      assertNull(frame);
+
+      // send message on another JMS connection => it should be received
+      sendMessage(getName(), topic);
+
+      frame = connV11.receiveFrame();
+
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertTrue(frame.getHeader("destination").equals(getTopicPrefix() + getTopicName()));
+      Assert.assertTrue(frame.getBody().equals(getName()));
+      
+      this.unsubscribe(connV11, "sub1");
+      
+      connV11.disconnect();
+   }
+
+   public void testSubscribeWithAutoAck() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "sub1", "auto");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertEquals("MESSAGE", frame.getCommand());
+      Assert.assertNotNull(frame.getHeader("destination"));
+      Assert.assertEquals(getName(), frame.getBody());
+
+      connV11.disconnect();
+      
+      // message should not be received as it was auto-acked
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+
+   public void testSubscribeWithAutoAckAndBytesMessage() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", "auto");
+
+      byte[] payload = new byte[] { 1, 2, 3, 4, 5 };
+      sendMessage(payload, queue);
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      assertEquals("MESSAGE", frame.getCommand());
+      
+      System.out.println("Message: " + frame);
+
+      assertEquals("5", frame.getHeader("content-length"));
+
+      assertEquals(null, frame.getHeader("type"));
+      
+      assertEquals(frame.getBody(), new String(payload, "UTF-8"));
+      
+      connV11.disconnect();
+   }
+
+   public void testSubscribeWithClientAck() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      this.ack(connV11, "sub1", frame);
+
+      connV11.disconnect();
+
+      // message should not be received since message was acknowledged by the client
+      MessageConsumer consumer = session.createConsumer(queue);
+      Message message = consumer.receive(1000);
+      Assert.assertNull(message);
+   }
+
+   public void testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithExplicitDisconnect() throws Exception
+   {
+      assertSubscribeWithClientAckThenConsumeWithAutoAck(true);
+   }
+
+   public void testSubscribeWithClientAckThenConsumingAgainWithAutoAckWithNoDisconnectFrame() throws Exception
+   {
+      assertSubscribeWithClientAckThenConsumeWithAutoAck(false);
+   }
+
+   public void testSubscribeWithID() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "mysubid", "auto");
+
+      sendMessage(getName());
+
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertTrue(frame.getHeader("subscription") != null);
+
+      connV11.disconnect();
+   }
+
+   public void testSubscribeWithMessageSentWithProperties() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", "auto");
+
+      MessageProducer producer = session.createProducer(queue);
+      BytesMessage message = session.createBytesMessage();
+      message.setStringProperty("S", "value");
+      message.setBooleanProperty("n", false);
+      message.setByteProperty("byte", (byte)9);
+      message.setDoubleProperty("d", 2.0);
+      message.setFloatProperty("f", (float)6.0);
+      message.setIntProperty("i", 10);
+      message.setLongProperty("l", 121);
+      message.setShortProperty("s", (short)12);
+      message.writeBytes("Hello World".getBytes("UTF-8"));
+      producer.send(message);
+
+      ClientStompFrame frame = connV11.receiveFrame();
+      Assert.assertNotNull(frame);
+      
+      Assert.assertTrue(frame.getHeader("S") != null);
+      Assert.assertTrue(frame.getHeader("n") != null);
+      Assert.assertTrue(frame.getHeader("byte") != null);
+      Assert.assertTrue(frame.getHeader("d") != null);
+      Assert.assertTrue(frame.getHeader("f") != null);
+      Assert.assertTrue(frame.getHeader("i") != null);
+      Assert.assertTrue(frame.getHeader("l") != null);
+      Assert.assertTrue(frame.getHeader("s") != null);
+      Assert.assertEquals("Hello World", frame.getBody());
+
+      connV11.disconnect();
+   }
+
+   public void testSuccessiveTransactionsWithSameID() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      // first tx
+      this.beginTransaction(connV11, "tx1");
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("transaction", "tx1");
+      frame.setBody("Hello World");
+
+      connV11.sendFrame(frame);
+
+      this.commitTransaction(connV11, "tx1");
+
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull("Should have received a message", message);
+
+      // 2nd tx with same tx ID
+      this.beginTransaction(connV11, "tx1");
+
+      frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("transaction", "tx1");
+      
+      frame.setBody("Hello World");
+      
+      connV11.sendFrame(frame);
+
+      this.commitTransaction(connV11, "tx1");
+
+      message = consumer.receive(1000);
+      Assert.assertNotNull("Should have received a message", message);
+      
+      connV11.disconnect();
+   }
+
+   public void testTransactionCommit() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+
+      this.beginTransaction(connV11, "tx1");
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("transaction", "tx1");
+      frame.addHeader("receipt", "123");
+      frame.setBody("Hello World");
+
+      frame = connV11.sendFrame(frame);
+      
+      assertEquals("123", frame.getHeader("receipt-id"));
+      
+      // check the message is not committed
+      assertNull(consumer.receive(100));
+      
+      this.commitTransaction(connV11, "tx1", true);
+
+      Message message = consumer.receive(1000);
+      Assert.assertNotNull("Should have received a message", message);
+      
+      connV11.disconnect();
+   }
+
+   public void testTransactionRollback() throws Exception
+   {
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      connV11.connect(defUser, defPass);
+      
+      this.beginTransaction(connV11, "tx1");
+
+      ClientStompFrame frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("transaction", "tx1");
+
+      frame.setBody("first message");
+      
+      connV11.sendFrame(frame);
+
+      // rollback first message
+      this.abortTransaction(connV11, "tx1");
+
+      this.beginTransaction(connV11, "tx1");
+
+      frame = connV11.createFrame("SEND");
+      frame.addHeader("destination", getQueuePrefix() + getQueueName());
+      frame.addHeader("transaction", "tx1");
+
+      frame.setBody("second message");
+      
+      connV11.sendFrame(frame);
+
+      this.commitTransaction(connV11, "tx1", true);
+
+      // only second msg should be received since first msg was rolled back
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("second message", message.getText());
+      
+      connV11.disconnect();
+   }
+
+   public void testUnsubscribe() throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "sub1", "auto");
+
+      // send a message to our queue
+      sendMessage("first message");
+
+      // receive message from socket
+      ClientStompFrame frame = connV11.receiveFrame();
+      
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+
+      // remove suscription
+      this.unsubscribe(connV11, "sub1", true);
+
+      // send a message to our queue
+      sendMessage("second message");
+
+      frame = connV11.receiveFrame(1000);
+      assertNull(frame);
+      
+      connV11.disconnect();
+   }
+
+   //-----------------private help methods
+
+   private void abortTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
+   {
+      ClientStompFrame abortFrame = conn.createFrame("ABORT");
+      abortFrame.addHeader("transaction", txID);
+
+      conn.sendFrame(abortFrame);
+   }
+
+   private void beginTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
+   {
+      ClientStompFrame beginFrame = conn.createFrame("BEGIN");
+      beginFrame.addHeader("transaction", txID);
+      
+      conn.sendFrame(beginFrame);
+   }
+
+   private void commitTransaction(StompClientConnection conn, String txID) throws IOException, InterruptedException
+   {
+      commitTransaction(conn, txID, false);
+   }
+
+   private void commitTransaction(StompClientConnection conn, String txID, boolean receipt) throws IOException, InterruptedException
+   {
+      ClientStompFrame beginFrame = conn.createFrame("COMMIT");
+      beginFrame.addHeader("transaction", txID);
+      if (receipt)
+      {
+         beginFrame.addHeader("receipt", "1234");
+      }
+      ClientStompFrame resp = conn.sendFrame(beginFrame);
+      if (receipt)
+      {
+         assertEquals("1234", resp.getHeader("receipt-id"));
+      }
+   }
+
+   private void ack(StompClientConnection conn, String subId,
+         ClientStompFrame frame) throws IOException, InterruptedException
+   {
+      String messageID = frame.getHeader("message-id");
+      
+      ClientStompFrame ackFrame = conn.createFrame("ACK");
+
+      ackFrame.addHeader("subscription", subId);
+      ackFrame.addHeader("message-id", messageID);
+      
+      ClientStompFrame response = conn.sendFrame(ackFrame);
+      if (response != null)
+      {
+         throw new IOException("failed to ack " + response);
+      }
+   }
+
+   private void ack(StompClientConnection conn, String subId, String mid, String txID) throws IOException, InterruptedException
+   {
+      ClientStompFrame ackFrame = conn.createFrame("ACK");
+      ackFrame.addHeader("subscription", subId);
+      ackFrame.addHeader("message-id", mid);
+      if (txID != null)
+      {
+         ackFrame.addHeader("transaction", txID);
+      }
+      
+      conn.sendFrame(ackFrame);
+   }
+
+   private void nack(StompClientConnection conn, String subId, String mid) throws IOException, InterruptedException
+   {
+      ClientStompFrame ackFrame = conn.createFrame("NACK");
+      ackFrame.addHeader("subscription", subId);
+      ackFrame.addHeader("message-id", mid);
+      
+      conn.sendFrame(ackFrame);
+   }
+   
+   private void subscribe(StompClientConnection conn, String subId, String ack) throws IOException, InterruptedException
+   {
+      subscribe(conn, subId, ack, null, null);
+   }
+
+   private void subscribe(StompClientConnection conn, String subId,
+         String ack, String durableId) throws IOException, InterruptedException
+   {
+      subscribe(conn, subId, ack, durableId, null);
+   }
+
+   private void subscribe(StompClientConnection conn, String subId,
+         String ack, String durableId, boolean receipt) throws IOException, InterruptedException
+   {
+      subscribe(conn, subId, ack, durableId, null, receipt);
+   }
+
+   private void subscribe(StompClientConnection conn, String subId, String ack,
+         String durableId, String selector) throws IOException,
+         InterruptedException
+   {
+      subscribe(conn, subId, ack, durableId, selector, false);
+   }
+   
+   private void subscribe(StompClientConnection conn, String subId,
+         String ack, String durableId, String selector, boolean receipt) throws IOException, InterruptedException
+   {
+      ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", subId);
+      subFrame.addHeader("destination", getQueuePrefix() + getQueueName());
+      if (ack != null)
+      {
+         subFrame.addHeader("ack", ack);
+      }
+      if (durableId != null)
+      {
+         subFrame.addHeader("durable-subscriber-name", durableId);
+      }
+      if (selector != null)
+      {
+         subFrame.addHeader("selector", selector);
+      }
+      if (receipt)
+      {
+         subFrame.addHeader("receipt", "1234");
+      }
+      
+      subFrame = conn.sendFrame(subFrame);
+      
+      if (receipt)
+      {
+         assertEquals("1234", subFrame.getHeader("receipt-id"));
+      }
+   }
+
+   private void subscribeTopic(StompClientConnection conn, String subId,
+         String ack, String durableId) throws IOException, InterruptedException
+   {
+      subscribeTopic(conn, subId, ack, durableId, false);
+   }
+
+   private void subscribeTopic(StompClientConnection conn, String subId,
+         String ack, String durableId, boolean receipt) throws IOException, InterruptedException
+   {
+      subscribeTopic(conn, subId, ack, durableId, receipt, false);
+   }
+
+   private void subscribeTopic(StompClientConnection conn, String subId,
+         String ack, String durableId, boolean receipt, boolean noLocal) throws IOException, InterruptedException
+   {
+      ClientStompFrame subFrame = conn.createFrame("SUBSCRIBE");
+      subFrame.addHeader("id", subId);
+      subFrame.addHeader("destination", getTopicPrefix() + getTopicName());
+      if (ack != null)
+      {
+         subFrame.addHeader("ack", ack);
+      }
+      if (durableId != null)
+      {
+         subFrame.addHeader("durable-subscriber-name", durableId);
+      }
+      if (receipt)
+      {
+         subFrame.addHeader("receipt", "1234");
+      }
+      if (noLocal)
+      {
+         subFrame.addHeader("no-local", "true");
+      }
+      
+      ClientStompFrame frame = conn.sendFrame(subFrame);
+      
+      if (receipt)
+      {
+         assertTrue(frame.getHeader("receipt-id").equals("1234"));
+      }
+   }
+
+   private void unsubscribe(StompClientConnection conn, String subId) throws IOException, InterruptedException
+   {
+      ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
+      subFrame.addHeader("id", subId);
+      
+      conn.sendFrame(subFrame);
+   }
+   
+   private void unsubscribe(StompClientConnection conn, String subId,
+         boolean receipt) throws IOException, InterruptedException
+   {
+      ClientStompFrame subFrame = conn.createFrame("UNSUBSCRIBE");
+      subFrame.addHeader("id", subId);
+      
+      if (receipt)
+      {
+         subFrame.addHeader("receipt", "4321");
+      }
+      
+      ClientStompFrame f = conn.sendFrame(subFrame);
+      
+      if (receipt)
+      {
+         System.out.println("response: " + f);
+         assertEquals("RECEIPT", f.getCommand());
+         assertEquals("4321", f.getHeader("receipt-id"));
+      }
+   }
+
+   protected void assertSubscribeWithClientAckThenConsumeWithAutoAck(boolean sendDisconnect) throws Exception
+   {
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "sub1", "client");
+
+      sendMessage(getName());
+      
+      ClientStompFrame frame = connV11.receiveFrame();
+
+      Assert.assertEquals("MESSAGE", frame.getCommand());
+
+      log.info("Reconnecting!");
+
+      if (sendDisconnect)
+      {
+         connV11.disconnect();
+         connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      }
+      else
+      {
+         connV11.destroy();
+         connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      }
+
+      // message should be received since message was not acknowledged
+      connV11.connect(defUser, defPass);
+
+      this.subscribe(connV11, "sub1", null);
+
+      frame = connV11.receiveFrame();
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+
+      connV11.disconnect();
+
+      // now lets make sure we don't see the message again
+      connV11.destroy();
+      connV11 = StompClientConnectionFactory.createClientConnection("1.1", hostname, port);
+      connV11.connect(defUser, defPass);
+      
+      this.subscribe(connV11, "sub1", null, null, true);
+
+      sendMessage("shouldBeNextMessage");
+
+      frame = connV11.receiveFrame();
+      Assert.assertTrue(frame.getCommand().equals("MESSAGE"));
+      Assert.assertEquals("shouldBeNextMessage", frame.getBody());
+   }
+
+}
+
+
+
+
+



More information about the hornetq-commits mailing list