diff --git a/openwire-jms/.gitignore b/openwire-jms/.gitignore
index ea8c4bf..ae3c172 100644
--- a/openwire-jms/.gitignore
+++ b/openwire-jms/.gitignore
@@ -1 +1 @@
-/target
+/bin/
diff --git a/openwire-jms/pom.xml b/openwire-jms/pom.xml
deleted file mode 100644
index a68d4a4..0000000
--- a/openwire-jms/pom.xml
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.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.
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.activemq</groupId>
-    <artifactId>openwire-protocol</artifactId>
-    <version>1.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>openwire-jms</artifactId>
-  <name>openwire-jms</name>
-  <description>OpenWire JMS Message mappings allowing for easier implementation of a JMS client using OpenWire</description>
-  <packaging>jar</packaging>
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-
-  <dependencies>
-    <!-- =================================== -->
-    <!-- Required Dependencies                -->
-    <!-- =================================== -->
-    <dependency>
-      <groupId>org.apache.activemq</groupId>
-      <artifactId>openwire-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-jms_1.1_spec</artifactId>
-    </dependency>
-
-    <!-- =================================== -->
-    <!-- Testing Dependencies                -->
-    <!-- =================================== -->
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.activemq</groupId>
-      <artifactId>activemq-broker</artifactId>
-      <version>${activemq-version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.activemq</groupId>
-      <artifactId>activemq-kahadb-store</artifactId>
-      <version>${activemq-version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.activemq</groupId>
-      <artifactId>activemq-jaas</artifactId>
-      <version>${activemq-version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.activemq</groupId>
-      <artifactId>activemq-spring</artifactId>
-      <version>${activemq-version}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessage.java
deleted file mode 100644
index 8ce1c1a..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessage.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import javax.jms.BytesMessage;
-import javax.jms.JMSException;
-import javax.jms.MessageEOFException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.commands.OpenWireBytesMessage;
-import org.apache.activemq.openwire.utils.ExceptionSupport;
-import org.fusesource.hawtbuf.Buffer;
-import org.fusesource.hawtbuf.ByteArrayInputStream;
-import org.fusesource.hawtbuf.ByteArrayOutputStream;
-
-/**
- * Wrapper class that provides ByteMessage compliant mappings to the OpenWireBytesMessage
- */
-public class OpenWireJMSBytesMessage extends OpenWireJMSMessage implements BytesMessage {
-
-    private final OpenWireBytesMessage message;
-
-    protected transient DataOutputStream dataOut;
-    protected transient ByteArrayOutputStream bytesOut;
-    protected transient DataInputStream dataIn;
-    protected transient int length;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireJMSBytesMessage instance.
-     */
-    public OpenWireJMSBytesMessage() {
-        this(new OpenWireBytesMessage());
-    }
-
-    /**
-     * Creates a new instance that wraps the given OpenWireJMSBytesMessage
-     *
-     * @param message
-     *        the OpenWireMessage to wrap.
-     */
-    public OpenWireJMSBytesMessage(OpenWireBytesMessage message) {
-        super(message);
-        this.message = message;
-    }
-
-    @Override
-    public OpenWireJMSBytesMessage copy() throws JMSException {
-        storeContent();
-        OpenWireJMSBytesMessage other = new OpenWireJMSBytesMessage(message.copy());
-        other.copy(this);
-        return other;
-    }
-
-    private void copy(OpenWireJMSBytesMessage other) throws JMSException {
-        super.copy(other);
-        bytesOut = null;
-        dataIn = null;
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        super.clearBody();
-        message.clearBody();
-        dataOut = null;
-        dataIn = null;
-        bytesOut = null;
-    }
-
-    @Override
-    public long getBodyLength() throws JMSException {
-        return message.getBodyLength();
-    }
-
-    /**
-     * Reads a <code>boolean</code> from the bytes message stream.
-     *
-     * @return the <code>boolean</code> value read
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public boolean readBoolean() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readBoolean();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a signed 8-bit value from the bytes message stream.
-     *
-     * @return the next byte from the bytes message stream as a signed 8-bit
-     *         <code>byte</code>
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public byte readByte() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readByte();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads an unsigned 8-bit number from the bytes message stream.
-     *
-     * @return the next byte from the bytes message stream, interpreted as an
-     *         unsigned 8-bit number
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public int readUnsignedByte() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readUnsignedByte();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a signed 16-bit number from the bytes message stream.
-     *
-     * @return the next two bytes from the bytes message stream, interpreted as
-     *         a signed 16-bit number
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public short readShort() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readShort();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads an unsigned 16-bit number from the bytes message stream.
-     *
-     * @return the next two bytes from the bytes message stream, interpreted as
-     *         an unsigned 16-bit integer
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public int readUnsignedShort() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readUnsignedShort();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a Unicode character value from the bytes message stream.
-     *
-     * @return the next two bytes from the bytes message stream as a Unicode
-     *         character
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public char readChar() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readChar();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a signed 32-bit integer from the bytes message stream.
-     *
-     * @return the next four bytes from the bytes message stream, interpreted as
-     *         an <code>int</code>
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public int readInt() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readInt();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a signed 64-bit integer from the bytes message stream.
-     *
-     * @return the next eight bytes from the bytes message stream, interpreted
-     *         as a <code>long</code>
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public long readLong() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readLong();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a <code>float</code> from the bytes message stream.
-     *
-     * @return the next four bytes from the bytes message stream, interpreted as
-     *         a <code>float</code>
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public float readFloat() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readFloat();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a <code>double</code> from the bytes message stream.
-     *
-     * @return the next eight bytes from the bytes message stream, interpreted
-     *         as a <code>double</code>
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public double readDouble() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readDouble();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a string that has been encoded using a modified UTF-8 format from
-     * the bytes message stream.
-     * <P>
-     * For more information on the UTF-8 format, see "File System Safe UCS
-     * Transformation Format (FSS_UTF)", X/Open Preliminary Specification,
-     * X/Open Company Ltd., Document Number: P316. This information also appears
-     * in ISO/IEC 10646, Annex P.
-     *
-     * @return a Unicode string from the bytes message stream
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageEOFException if unexpected end of bytes stream has been
-     *                 reached.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public String readUTF() throws JMSException {
-        initializeReading();
-        try {
-            return this.dataIn.readUTF();
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Reads a byte array from the bytes message stream.
-     * <P>
-     * If the length of array <code>value</code> is less than the number of
-     * bytes remaining to be read from the stream, the array should be filled. A
-     * subsequent call reads the next increment, and so on.
-     * <P>
-     * If the number of bytes remaining in the stream is less than the length of
-     * array <code>value</code>, the bytes should be read into the array. The
-     * return value of the total number of bytes read will be less than the
-     * length of the array, indicating that there are no more bytes left to be
-     * read from the stream. The next read of the stream returns -1.
-     *
-     * @param value the buffer into which the data is read
-     * @return the total number of bytes read into the buffer, or -1 if there is
-     *         no more data because the end of the stream has been reached
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public int readBytes(byte[] value) throws JMSException {
-        return readBytes(value, value.length);
-    }
-
-    /**
-     * Reads a portion of the bytes message stream.
-     * <P>
-     * If the length of array <code>value</code> is less than the number of
-     * bytes remaining to be read from the stream, the array should be filled. A
-     * subsequent call reads the next increment, and so on.
-     * <P>
-     * If the number of bytes remaining in the stream is less than the length of
-     * array <code>value</code>, the bytes should be read into the array. The
-     * return value of the total number of bytes read will be less than the
-     * length of the array, indicating that there are no more bytes left to be
-     * read from the stream. The next read of the stream returns -1. <p/> If
-     * <code>length</code> is negative, or <code>length</code> is greater
-     * than the length of the array <code>value</code>, then an
-     * <code>IndexOutOfBoundsException</code> is thrown. No bytes will be read
-     * from the stream for this exception case.
-     *
-     * @param value the buffer into which the data is read
-     * @param length the number of bytes to read; must be less than or equal to
-     *                <code>value.length</code>
-     * @return the total number of bytes read into the buffer, or -1 if there is
-     *         no more data because the end of the stream has been reached
-     * @throws JMSException if the JMS provider fails to read the message due to
-     *                 some internal error.
-     * @throws MessageNotReadableException if the message is in write-only mode.
-     */
-    @Override
-    public int readBytes(byte[] value, int length) throws JMSException {
-        initializeReading();
-        try {
-            int n = 0;
-            while (n < length) {
-                int count = this.dataIn.read(value, n, length - n);
-                if (count < 0) {
-                    break;
-                }
-                n += count;
-            }
-            if (n == 0 && length > 0) {
-                n = -1;
-            }
-            return n;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    /**
-     * Writes a <code>boolean</code> to the bytes message stream as a 1-byte
-     * value. The value <code>true</code> is written as the value
-     * <code>(byte)1</code>; the value <code>false</code> is written as the
-     * value <code>(byte)0</code>.
-     *
-     * @param value the <code>boolean</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeBoolean(boolean value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeBoolean(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a <code>byte</code> to the bytes message stream as a 1-byte
-     * value.
-     *
-     * @param value the <code>byte</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeByte(byte value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeByte(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a <code>short</code> to the bytes message stream as two bytes,
-     * high byte first.
-     *
-     * @param value the <code>short</code> to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeShort(short value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeShort(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a <code>char</code> to the bytes message stream as a 2-byte
-     * value, high byte first.
-     *
-     * @param value the <code>char</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeChar(char value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeChar(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes an <code>int</code> to the bytes message stream as four bytes,
-     * high byte first.
-     *
-     * @param value the <code>int</code> to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeInt(int value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeInt(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a <code>long</code> to the bytes message stream as eight bytes,
-     * high byte first.
-     *
-     * @param value the <code>long</code> to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeLong(long value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeLong(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Converts the <code>float</code> argument to an <code>int</code> using
-     * the <code>floatToIntBits</code> method in class <code>Float</code>,
-     * and then writes that <code>int</code> value to the bytes message stream
-     * as a 4-byte quantity, high byte first.
-     *
-     * @param value the <code>float</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeFloat(float value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeFloat(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Converts the <code>double</code> argument to a <code>long</code>
-     * using the <code>doubleToLongBits</code> method in class
-     * <code>Double</code>, and then writes that <code>long</code> value to
-     * the bytes message stream as an 8-byte quantity, high byte first.
-     *
-     * @param value the <code>double</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeDouble(double value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeDouble(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a string to the bytes message stream using UTF-8 encoding in a
-     * machine-independent manner.
-     * <P>
-     * For more information on the UTF-8 format, see "File System Safe UCS
-     * Transformation Format (FSS_UTF)", X/Open Preliminary Specification,
-     * X/Open Company Ltd., Document Number: P316. This information also appears
-     * in ISO/IEC 10646, Annex P.
-     *
-     * @param value the <code>String</code> value to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeUTF(String value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.writeUTF(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a byte array to the bytes message stream.
-     *
-     * @param value the byte array to be written
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeBytes(byte[] value) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.write(value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes a portion of a byte array to the bytes message stream.
-     *
-     * @param value the byte array value to be written
-     * @param offset the initial offset within the byte array
-     * @param length the number of bytes to use
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     */
-    @Override
-    public void writeBytes(byte[] value, int offset, int length) throws JMSException {
-        initializeWriting();
-        try {
-            this.dataOut.write(value, offset, length);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    /**
-     * Writes an object to the bytes message stream.
-     * <P>
-     * This method works only for the objectified primitive object types (<code>Integer</code>,<code>Double</code>,
-     * <code>Long</code> &nbsp;...), <code>String</code> objects, and byte
-     * arrays.
-     *
-     * @param value the object in the Java programming language ("Java object")
-     *                to be written; it must not be null
-     * @throws JMSException if the JMS provider fails to write the message due
-     *                 to some internal error.
-     * @throws MessageFormatException if the object is of an invalid type.
-     * @throws MessageNotWriteableException if the message is in read-only mode.
-     * @throws java.lang.NullPointerException if the parameter
-     *                 <code>value</code> is null.
-     */
-    @Override
-    public void writeObject(Object value) throws JMSException {
-        if (value == null) {
-            throw new NullPointerException();
-        }
-        initializeWriting();
-        if (value instanceof Boolean) {
-            writeBoolean(((Boolean)value).booleanValue());
-        } else if (value instanceof Character) {
-            writeChar(((Character)value).charValue());
-        } else if (value instanceof Byte) {
-            writeByte(((Byte)value).byteValue());
-        } else if (value instanceof Short) {
-            writeShort(((Short)value).shortValue());
-        } else if (value instanceof Integer) {
-            writeInt(((Integer)value).intValue());
-        } else if (value instanceof Long) {
-            writeLong(((Long)value).longValue());
-        } else if (value instanceof Float) {
-            writeFloat(((Float)value).floatValue());
-        } else if (value instanceof Double) {
-            writeDouble(((Double)value).doubleValue());
-        } else if (value instanceof String) {
-            writeUTF(value.toString());
-        } else if (value instanceof byte[]) {
-            writeBytes((byte[])value);
-        } else {
-            throw new MessageFormatException("Cannot write non-primitive type:" + value.getClass());
-        }
-    }
-
-    @Override
-    public void reset() throws JMSException {
-        storeContent();
-        setReadOnlyBody(true);
-        try {
-            if (bytesOut != null) {
-                bytesOut.close();
-                bytesOut = null;
-            }
-            if (dataIn != null) {
-                dataIn.close();
-                dataIn = null;
-            }
-            if (dataOut != null) {
-                dataOut.close();
-                dataOut = null;
-            }
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    private void initializeWriting() throws JMSException {
-        checkReadOnlyBody();
-        if (this.dataOut == null) {
-            this.bytesOut = new ByteArrayOutputStream();
-            OutputStream os = bytesOut;
-            this.dataOut = new DataOutputStream(os);
-        }
-
-        restoreOldContent();
-    }
-
-    private void restoreOldContent() throws JMSException {
-        // For a message that already had a body and was sent we need to restore the content
-        // if the message is used again without having its clearBody method called.
-        byte[] oldContent = message.getBodyBytes();
-        if (oldContent.length != 0) {
-            try {
-                dataOut.write(oldContent);
-            } catch (IOException e) {
-                throw ExceptionSupport.create(e);
-            }
-
-            // Clear old buffer as we are in write mode, only a call to reset can
-            // put us back in read mode and that will store any current pending
-            // content updates first.
-            message.clearBody();
-        }
-    }
-
-    private void initializeReading() throws JMSException {
-        checkWriteOnlyBody();
-        if (dataIn == null) {
-            try {
-                Buffer data = message.getPayload();
-                InputStream is = new ByteArrayInputStream(data);
-                length = data.length;
-                dataIn = new DataInputStream(is);
-            } catch (Exception ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-        }
-    }
-
-    private void storeContent() throws JMSException {
-        if (dataOut != null) {
-            try {
-                dataOut.close();
-                Buffer buffer = bytesOut.toBuffer();
-                message.setPayload(buffer);
-            } catch (IOException ioe) {
-                throw new RuntimeException(ioe.getMessage(), ioe);
-            } finally {
-                try {
-                    if (bytesOut != null) {
-                        bytesOut.close();
-                        bytesOut = null;
-                    }
-                    if (dataOut != null) {
-                        dataOut.close();
-                        dataOut = null;
-                    }
-                } catch (IOException ioe) {
-                }
-            }
-        }
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessage.java
deleted file mode 100644
index a2fbd11..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessage.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import java.util.Enumeration;
-
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.MessageFormatException;
-
-import org.apache.activemq.openwire.commands.OpenWireMapMessage;
-import org.fusesource.hawtbuf.UTF8Buffer;
-
-/**
- * Wrapper class that provides MapMessage compliant mappings to the OpenWireMapMessage
- */
-public class OpenWireJMSMapMessage extends OpenWireJMSMessage implements MapMessage {
-
-    private final OpenWireMapMessage message;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireMessage instance.
-     */
-    public OpenWireJMSMapMessage() {
-        this(new OpenWireMapMessage());
-    }
-
-    /**
-     * Creates a new instance that wraps the given OpenWireMessage
-     *
-     * @param message
-     *        the OpenWireMessage to wrap.
-     */
-    public OpenWireJMSMapMessage(OpenWireMapMessage message) {
-        this.message = message;
-    }
-
-    @Override
-    public OpenWireJMSMapMessage copy() throws JMSException {
-        OpenWireJMSMapMessage other = new OpenWireJMSMapMessage(message.copy());
-        return other;
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        super.clearBody();
-        message.clearBody();
-    }
-
-    @Override
-    public boolean getBoolean(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return false;
-        }
-        if (value instanceof Boolean) {
-            return ((Boolean)value).booleanValue();
-        }
-        if (value instanceof UTF8Buffer) {
-            return Boolean.valueOf(value.toString()).booleanValue();
-        }
-        if (value instanceof String) {
-            return Boolean.valueOf(value.toString()).booleanValue();
-        } else {
-            throw new MessageFormatException(" cannot read a boolean from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public byte getByte(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Byte) {
-            return ((Byte)value).byteValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Byte.valueOf(value.toString()).byteValue();
-        } else if (value instanceof String) {
-            return Byte.valueOf(value.toString()).byteValue();
-        } else {
-            throw new MessageFormatException(" cannot read a byte from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public short getShort(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Short) {
-            return ((Short)value).shortValue();
-        } else if (value instanceof Byte) {
-            return ((Byte)value).shortValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Short.valueOf(value.toString()).shortValue();
-        } else if (value instanceof String) {
-            return Short.valueOf(value.toString()).shortValue();
-        } else {
-            throw new MessageFormatException(" cannot read a short from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public char getChar(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            throw new NullPointerException();
-        } else if (value instanceof Character) {
-            return ((Character)value).charValue();
-        } else {
-            throw new MessageFormatException(" cannot read a short from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public int getInt(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Integer) {
-            return ((Integer)value).intValue();
-        } else if (value instanceof Short) {
-            return ((Short)value).intValue();
-        } else if (value instanceof Byte) {
-            return ((Byte)value).intValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Integer.valueOf(value.toString()).intValue();
-        } else if (value instanceof String) {
-            return Integer.valueOf(value.toString()).intValue();
-        } else {
-            throw new MessageFormatException(" cannot read an int from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public long getLong(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Long) {
-            return ((Long)value).longValue();
-        } else if (value instanceof Integer) {
-            return ((Integer)value).longValue();
-        } else if (value instanceof Short) {
-            return ((Short)value).longValue();
-        } else if (value instanceof Byte) {
-            return ((Byte)value).longValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Long.valueOf(value.toString()).longValue();
-        } else if (value instanceof String) {
-            return Long.valueOf(value.toString()).longValue();
-        } else {
-            throw new MessageFormatException(" cannot read a long from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public float getFloat(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Float) {
-            return ((Float)value).floatValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Float.valueOf(value.toString()).floatValue();
-        } else if (value instanceof String) {
-            return Float.valueOf(value.toString()).floatValue();
-        } else {
-            throw new MessageFormatException(" cannot read a float from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public double getDouble(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return 0;
-        } else if (value instanceof Double) {
-            return ((Double)value).doubleValue();
-        } else if (value instanceof Float) {
-            return ((Float)value).floatValue();
-        } else if (value instanceof UTF8Buffer) {
-            return Float.valueOf(value.toString()).floatValue();
-        } else if (value instanceof String) {
-            return Float.valueOf(value.toString()).floatValue();
-        } else {
-            throw new MessageFormatException(" cannot read a double from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public String getString(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value == null) {
-            return null;
-        } else if (value instanceof byte[]) {
-            throw new MessageFormatException("Use getBytes to read a byte array");
-        } else {
-            return value.toString();
-        }
-    }
-
-    @Override
-    public byte[] getBytes(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value instanceof byte[]) {
-            return (byte[])value;
-        } else {
-            throw new MessageFormatException(" cannot read a byte[] from " + value.getClass().getName());
-        }
-    }
-
-    @Override
-    public Object getObject(String name) throws JMSException {
-        Object value = message.getObject(name);
-        if (value instanceof UTF8Buffer) {
-            value = value.toString();
-        }
-
-        return value;
-    }
-
-    @Override
-    public Enumeration<String> getMapNames() throws JMSException {
-        return message.getMapNames();
-    }
-
-    @Override
-    public void setBoolean(String name, boolean value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, value ? Boolean.TRUE : Boolean.FALSE);
-    }
-
-    @Override
-    public void setByte(String name, byte value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Byte.valueOf(value));
-    }
-
-    @Override
-    public void setShort(String name, short value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Short.valueOf(value));
-    }
-
-    @Override
-    public void setChar(String name, char value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Character.valueOf(value));
-    }
-
-    @Override
-    public void setInt(String name, int value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Integer.valueOf(value));
-    }
-
-    @Override
-    public void setLong(String name, long value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Long.valueOf(value));
-    }
-
-    @Override
-    public void setFloat(String name, float value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Float.valueOf(value));
-    }
-
-    @Override
-    public void setDouble(String name, double value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, Double.valueOf(value));
-    }
-
-    @Override
-    public void setString(String name, String value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, value);
-    }
-
-    @Override
-    public void setBytes(String name, byte[] value) throws JMSException {
-        checkReadOnlyBody();
-        if (value != null) {
-            message.setObject(name, value);
-        } else {
-            message.removeObject(name);
-        }
-    }
-
-    @Override
-    public void setBytes(String name, byte[] value, int offset, int length) throws JMSException {
-        checkReadOnlyBody();
-        byte[] data = new byte[length];
-        System.arraycopy(value, offset, data, 0, length);
-        message.setObject(name, data);
-    }
-
-    @Override
-    public void setObject(String name, Object value) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(name, value);
-    }
-
-    @Override
-    public boolean itemExists(String name) throws JMSException {
-        return message.itemExists(name);
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMessage.java
deleted file mode 100644
index a278f37..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSMessage.java
+++ /dev/null
@@ -1,561 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.concurrent.Callable;
-
-import javax.jms.DeliveryMode;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.codec.OpenWireConstants;
-import org.apache.activemq.openwire.commands.OpenWireDestination;
-import org.apache.activemq.openwire.commands.OpenWireMessage;
-import org.apache.activemq.openwire.jms.utils.OpenWireMessagePropertyGetter;
-import org.apache.activemq.openwire.jms.utils.OpenWireMessagePropertySetter;
-import org.apache.activemq.openwire.jms.utils.TypeConversionSupport;
-import org.apache.activemq.openwire.utils.ExceptionSupport;
-import org.fusesource.hawtbuf.UTF8Buffer;
-
-/**
- * A JMS Message implementation that wraps the basic OpenWireMessage instance
- * to enforce adherence to the JMS specification rules for the javax.jms.Message
- * type.
- */
-public class OpenWireJMSMessage implements Message {
-
-    private final OpenWireMessage message;
-
-    private Callable<Void> acknowledgeCallback;
-    private boolean readOnlyBody;
-    private boolean readOnlyProperties;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireMessage instance.
-     */
-    public OpenWireJMSMessage() {
-        this(new OpenWireMessage());
-    }
-
-    /**
-     * Creates a new instance that wraps the given OpenWireMessage
-     *
-     * @param message
-     *        the OpenWireMessage to wrap.
-     */
-    public OpenWireJMSMessage(OpenWireMessage message) {
-        this.message = message;
-    }
-
-    /**
-     * Copies this message into a new OpenWireJMSMessage instance.
-     *
-     * @return a new copy of this message and it's contents.
-     *
-     * @throws JMSException if an error occurs during the copy operation.
-     */
-    public OpenWireJMSMessage copy() throws JMSException {
-        OpenWireJMSMessage copy = new OpenWireJMSMessage(message.copy());
-        copy(copy);
-        return copy;
-    }
-
-    protected void copy(OpenWireJMSMessage copy) {
-        copy.readOnlyBody = readOnlyBody;
-        copy.readOnlyProperties = readOnlyProperties;
-    }
-
-    /**
-     * @return the wrapped OpenWireMessage instance.
-     */
-    public OpenWireMessage getOpenWireMessage() {
-        return this.message;
-    }
-
-    @Override
-    public String getJMSMessageID() throws JMSException {
-        return message.getMessageIdAsString();
-    }
-
-    @Override
-    public void setJMSMessageID(String id) throws JMSException {
-        message.setMessageId(id);
-    }
-
-    @Override
-    public long getJMSTimestamp() throws JMSException {
-        return message.getTimestamp();
-    }
-
-    @Override
-    public void setJMSTimestamp(long timestamp) throws JMSException {
-        message.setTimestamp(timestamp);
-    }
-
-    @Override
-    public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
-        return message.getCorrelationIdAsBytes();
-    }
-
-    @Override
-    public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException {
-        message.setCorrelationIdAsBytes(correlationID);
-    }
-
-    @Override
-    public void setJMSCorrelationID(String correlationID) throws JMSException {
-        message.setCorrelationId(correlationID);
-    }
-
-    @Override
-    public String getJMSCorrelationID() throws JMSException {
-        return message.getCorrelationId();
-    }
-
-    @Override
-    public Destination getJMSReplyTo() throws JMSException {
-        return message.getReplyTo();
-    }
-
-    @Override
-    public void setJMSReplyTo(Destination replyTo) throws JMSException {
-        message.setReplyTo(OpenWireDestination.transform(replyTo));
-    }
-
-    @Override
-    public Destination getJMSDestination() throws JMSException {
-        return message.getDestination();
-    }
-
-    @Override
-    public void setJMSDestination(Destination destination) throws JMSException {
-        message.setDestination(OpenWireDestination.transform(destination));
-    }
-
-    @Override
-    public int getJMSDeliveryMode() throws JMSException {
-        return message.isPersistent() ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
-    }
-
-    @Override
-    public void setJMSDeliveryMode(int deliveryMode) throws JMSException {
-        message.setPersistent(deliveryMode == DeliveryMode.PERSISTENT);
-    }
-
-    @Override
-    public boolean getJMSRedelivered() throws JMSException {
-        return message.getRedeliveryCounter() > 0;
-    }
-
-    @Override
-    public void setJMSRedelivered(boolean redelivered) throws JMSException {
-        message.setRedelivered(true);
-    }
-
-    @Override
-    public String getJMSType() throws JMSException {
-        return message.getType();
-    }
-
-    @Override
-    public void setJMSType(String type) throws JMSException {
-        message.setType(type);
-    }
-
-    @Override
-    public long getJMSExpiration() throws JMSException {
-        return message.getExpiration();
-    }
-
-    @Override
-    public void setJMSExpiration(long expiration) throws JMSException {
-        message.setExpiration(expiration);
-    }
-
-    @Override
-    public int getJMSPriority() throws JMSException {
-        return message.getPriority();
-    }
-
-    @Override
-    public void setJMSPriority(int priority) throws JMSException {
-        message.setPriority((byte) priority);
-    }
-
-    @Override
-    public void clearProperties() throws JMSException {
-        message.clearProperties();
-    }
-
-    @Override
-    public boolean propertyExists(String name) throws JMSException {
-        try {
-            return (message.propertyExists(name) || getObjectProperty(name)!= null);
-        } catch (Exception e) {
-            throw ExceptionSupport.create(e);
-        }
-    }
-
-    @Override
-    public boolean getBooleanProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-
-        if (value == null) {
-            return false;
-        }
-
-        Boolean rc = (Boolean) TypeConversionSupport.convert(value, Boolean.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a boolean");
-        }
-
-        return rc.booleanValue();
-    }
-
-    @Override
-    public byte getByteProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NumberFormatException("property " + name + " was null");
-        }
-        Byte rc = (Byte) TypeConversionSupport.convert(value, Byte.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a byte");
-        }
-        return rc.byteValue();
-    }
-
-    @Override
-    public short getShortProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NumberFormatException("property " + name + " was null");
-        }
-        Short rc = (Short) TypeConversionSupport.convert(value, Short.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a short");
-        }
-        return rc.shortValue();
-    }
-
-    @Override
-    public int getIntProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NumberFormatException("property " + name + " was null");
-        }
-        Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as an integer");
-        }
-        return rc.intValue();
-    }
-
-    @Override
-    public long getLongProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NumberFormatException("property " + name + " was null");
-        }
-        Long rc = (Long) TypeConversionSupport.convert(value, Long.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a long");
-        }
-        return rc.longValue();
-    }
-
-    @Override
-    public float getFloatProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NullPointerException("property " + name + " was null");
-        }
-        Float rc = (Float) TypeConversionSupport.convert(value, Float.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a float");
-        }
-        return rc.floatValue();
-    }
-
-    @Override
-    public double getDoubleProperty(String name) throws JMSException {
-        Object value = getObjectProperty(name);
-        if (value == null) {
-            throw new NullPointerException("property " + name + " was null");
-        }
-        Double rc = (Double) TypeConversionSupport.convert(value, Double.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a double");
-        }
-        return rc.doubleValue();
-    }
-
-    @Override
-    public String getStringProperty(String name) throws JMSException {
-        Object value = null;
-
-        // Always go first to the OpenWire Message field before checking in the
-        // application properties for any other versions.
-        if (name.equals("JMSXUserID")) {
-            value = message.getUserId();
-            if (value == null) {
-                value = getObjectProperty(name);
-            }
-        } else {
-            value = getObjectProperty(name);
-        }
-        if (value == null) {
-            return null;
-        }
-        String rc = (String) TypeConversionSupport.convert(value, String.class);
-        if (rc == null) {
-            throw new MessageFormatException("Property " + name + " was a " + value.getClass().getName() + " and cannot be read as a String");
-        }
-        return rc;
-    }
-
-    @Override
-    public Object getObjectProperty(String name) throws JMSException {
-        if (name == null) {
-            throw new NullPointerException("Property name cannot be null");
-        }
-
-        return OpenWireMessagePropertyGetter.getProperty(message, name);
-    }
-
-    @Override
-    public Enumeration<?> getPropertyNames() throws JMSException {
-        return message.getPropertyNames();
-    }
-
-    /**
-     * return all property names, including standard JMS properties and JMSX properties
-     * @return  Enumeration of all property names on this message
-     * @throws JMSException
-     */
-    public Enumeration<String> getAllPropertyNames() throws JMSException {
-        try {
-            Vector<String> result = new Vector<String>(message.getProperties().keySet());
-            result.addAll(OpenWireMessagePropertyGetter.getPropertyNames());
-            return result.elements();
-        } catch (Exception e) {
-            throw ExceptionSupport.create(e);
-        }
-    }
-
-    @Override
-    public void setBooleanProperty(String name, boolean value) throws JMSException {
-        setObjectProperty(name, Boolean.valueOf(value), true);
-    }
-
-    @Override
-    public void setByteProperty(String name, byte value) throws JMSException {
-        setObjectProperty(name, Byte.valueOf(value), true);
-    }
-
-    @Override
-    public void setShortProperty(String name, short value) throws JMSException {
-        setObjectProperty(name, Short.valueOf(value), true);
-    }
-
-    @Override
-    public void setIntProperty(String name, int value) throws JMSException {
-        setObjectProperty(name, Integer.valueOf(value), true);
-    }
-
-    @Override
-    public void setLongProperty(String name, long value) throws JMSException {
-        setObjectProperty(name, Long.valueOf(value), true);
-    }
-
-    @Override
-    public void setFloatProperty(String name, float value) throws JMSException {
-        setObjectProperty(name, Float.valueOf(value), true);
-    }
-
-    @Override
-    public void setDoubleProperty(String name, double value) throws JMSException {
-        setObjectProperty(name, Double.valueOf(value), true);
-    }
-
-    @Override
-    public void setStringProperty(String name, String value) throws JMSException {
-        setObjectProperty(name, value, true);
-    }
-
-    @Override
-    public void setObjectProperty(String name, Object value) throws JMSException {
-        setObjectProperty(name, value, true);
-    }
-
-    protected void setObjectProperty(String name, Object value, boolean checkReadOnly) throws JMSException {
-
-        if (checkReadOnly) {
-            checkReadOnlyProperties();
-        }
-
-        if (name == null || name.equals("")) {
-            throw new IllegalArgumentException("Property name cannot be empty or null");
-        }
-
-        if (value instanceof UTF8Buffer) {
-            value = value.toString();
-        }
-
-        // Ensure that message sent with scheduling options comply with the
-        // expected property types for the settings values.
-        value = convertScheduled(name, value);
-
-        OpenWireMessagePropertySetter.setProperty(message, name, value);
-    }
-
-    @Override
-    public void acknowledge() throws JMSException {
-        if (acknowledgeCallback != null) {
-            try {
-                acknowledgeCallback.call();
-            } catch (Exception e) {
-                throw ExceptionSupport.create(e);
-            }
-        }
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        setReadOnlyBody(false);
-    }
-
-    /**
-     * @return the acknowledge callback instance set on this message.
-     */
-    public Callable<Void> getAcknowledgeCallback() {
-        return acknowledgeCallback;
-    }
-
-    /**
-     * Sets the Callable instance that is invoked when the client calls the JMS Message
-     * acknowledge method.
-     *
-     * @param acknowledgeCallback
-     *        the acknowledgeCallback to set on this message.
-     */
-    public void setAcknowledgeCallback(Callable<Void> acknowledgeCallback) {
-        this.acknowledgeCallback = acknowledgeCallback;
-    }
-
-    /**
-     * @return true if the body is in read only mode.
-     */
-    public boolean isReadOnlyBody() {
-        return readOnlyBody;
-    }
-
-    /**
-     * @param readOnlyBody
-     *        sets if the message body is in read-only mode.
-     */
-    public void setReadOnlyBody(boolean readOnlyBody) {
-        this.readOnlyBody = readOnlyBody;
-    }
-
-    /**
-     * @return true if the message properties are in read-only mode.
-     */
-    public boolean isReadOnlyProperties() {
-        return readOnlyProperties;
-    }
-
-    /**
-     * @param readOnlyProperties
-     *        sets if the message properties are in read-only mode.
-     */
-    public void setReadOnlyProperties(boolean readOnlyProperties) {
-        this.readOnlyProperties = readOnlyProperties;
-    }
-
-    /**
-     * @returns true if this message has expired.
-     */
-    public boolean isExpired() {
-        return message.isExpired();
-    }
-
-    /**
-     * @returns true if this message is an Advisory message instance.
-     */
-    public boolean isAdviory() {
-        return this.message.isAdvisory();
-    }
-
-    @Override
-    public int hashCode() {
-        return message.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        }
-
-        if (other == null || other.getClass() != getClass()) {
-            return false;
-        }
-
-        OpenWireJMSMessage jmsMessage = (OpenWireJMSMessage) other;
-
-        return message.equals(jmsMessage.getOpenWireMessage());
-    }
-
-    private void checkReadOnlyProperties() throws MessageNotWriteableException {
-        if (readOnlyProperties) {
-            throw new MessageNotWriteableException("Message properties are read-only");
-        }
-    }
-
-    protected void checkReadOnlyBody() throws MessageNotWriteableException {
-        if (readOnlyBody) {
-            throw new MessageNotWriteableException("Message body is read-only");
-        }
-    }
-
-    protected void checkWriteOnlyBody() throws MessageNotReadableException {
-        if (!readOnlyBody) {
-            throw new MessageNotReadableException("Message body is write-only");
-        }
-    }
-
-    protected Object convertScheduled(String name, Object value) throws MessageFormatException {
-        Object result = value;
-        if (OpenWireConstants.AMQ_SCHEDULED_DELAY.equals(name)){
-            result = TypeConversionSupport.convert(value, Long.class);
-        }
-        else if (OpenWireConstants.AMQ_SCHEDULED_PERIOD.equals(name)){
-            result = TypeConversionSupport.convert(value, Long.class);
-        }
-        else if (OpenWireConstants.AMQ_SCHEDULED_REPEAT.equals(name)){
-            result = TypeConversionSupport.convert(value, Integer.class);
-        }
-        return result;
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessage.java
deleted file mode 100644
index db42806..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessage.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import java.io.Serializable;
-
-import javax.jms.JMSException;
-import javax.jms.ObjectMessage;
-
-import org.apache.activemq.openwire.commands.OpenWireObjectMessage;
-
-/**
- * Wrapper class that provides ObjectMessage compliant mappings to the OpenWireObjectMessage
- */
-public class OpenWireJMSObjectMessage extends OpenWireJMSMessage implements ObjectMessage {
-
-    private final OpenWireObjectMessage message;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireMessage instance.
-     */
-    public OpenWireJMSObjectMessage() {
-        this(new OpenWireObjectMessage());
-    }
-
-    /**
-     * Creates a new instance that wraps the given OpenWireMessage
-     *
-     * @param message
-     *        the OpenWireMessage to wrap.
-     */
-    public OpenWireJMSObjectMessage(OpenWireObjectMessage message) {
-        this.message = message;
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        super.clearBody();
-        message.clearBody();
-    }
-
-    @Override
-    public OpenWireJMSObjectMessage copy() throws JMSException {
-        OpenWireJMSObjectMessage other = new OpenWireJMSObjectMessage(message.copy());
-        return other;
-    }
-
-    @Override
-    public void setObject(Serializable object) throws JMSException {
-        checkReadOnlyBody();
-        message.setObject(object);
-    }
-
-    @Override
-    public Serializable getObject() throws JMSException {
-        return message.getObject();
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessage.java
deleted file mode 100644
index ae7793c..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessage.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.jms.JMSException;
-import javax.jms.MessageEOFException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.StreamMessage;
-
-import org.apache.activemq.openwire.commands.OpenWireStreamMessage;
-import org.apache.activemq.openwire.utils.ExceptionSupport;
-import org.apache.activemq.openwire.utils.OpenWireMarshallingSupport;
-import org.fusesource.hawtbuf.Buffer;
-import org.fusesource.hawtbuf.ByteArrayInputStream;
-import org.fusesource.hawtbuf.ByteArrayOutputStream;
-
-/**
- * Wrapper class that provides StreamMessage compliant mappings to the OpenWireStreamMessage
- */
-public class OpenWireJMSStreamMessage extends OpenWireJMSMessage implements StreamMessage {
-
-    private final OpenWireStreamMessage message;
-
-    protected transient DataOutputStream dataOut;
-    protected transient ByteArrayOutputStream bytesOut;
-    protected transient DataInputStream dataIn;
-    protected transient int remainingBytes = -1;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireMessage instance.
-     */
-    public OpenWireJMSStreamMessage() {
-        this(new OpenWireStreamMessage());
-    }
-
-    /**
-     * Creates a new instance that wraps the given OpenWireMessage
-     *
-     * @param message
-     *        the OpenWireMessage to wrap.
-     */
-    public OpenWireJMSStreamMessage(OpenWireStreamMessage message) {
-        this.message = message;
-    }
-
-    @Override
-    public OpenWireJMSStreamMessage copy() throws JMSException {
-        OpenWireJMSStreamMessage other = new OpenWireJMSStreamMessage(message.copy());
-        copy(other);
-        return other;
-    }
-
-    private void copy(OpenWireJMSStreamMessage copy) throws JMSException {
-        storeContent();
-        super.copy(copy);
-        copy.dataOut = null;
-        copy.bytesOut = null;
-        copy.dataIn = null;
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        super.clearBody();
-        message.clearBody();
-        dataOut = null;
-        dataIn = null;
-        bytesOut = null;
-        remainingBytes = -1;
-    }
-
-    @Override
-    public boolean readBoolean() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(10);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.BOOLEAN_TYPE) {
-                return this.dataIn.readBoolean();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Boolean.valueOf(this.dataIn.readUTF()).booleanValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to boolean.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a boolean type");
-            }
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public byte readByte() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(10);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return this.dataIn.readByte();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Byte.valueOf(this.dataIn.readUTF()).byteValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to byte.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a byte type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public short readShort() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(17);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.SHORT_TYPE) {
-                return this.dataIn.readShort();
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return this.dataIn.readByte();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Short.valueOf(this.dataIn.readUTF()).shortValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to short.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a short type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public char readChar() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(17);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.CHAR_TYPE) {
-                return this.dataIn.readChar();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to char.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a char type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public int readInt() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(33);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.INTEGER_TYPE) {
-                return this.dataIn.readInt();
-            } else if (type == OpenWireMarshallingSupport.SHORT_TYPE) {
-                return this.dataIn.readShort();
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return this.dataIn.readByte();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Integer.valueOf(this.dataIn.readUTF()).intValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to int.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not an int type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public long readLong() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(65);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.LONG_TYPE) {
-                return this.dataIn.readLong();
-            } else if (type == OpenWireMarshallingSupport.INTEGER_TYPE) {
-                return this.dataIn.readInt();
-            } else if (type == OpenWireMarshallingSupport.SHORT_TYPE) {
-                return this.dataIn.readShort();
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return this.dataIn.readByte();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Long.valueOf(this.dataIn.readUTF()).longValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to long.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a long type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public float readFloat() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(33);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.FLOAT_TYPE) {
-                return this.dataIn.readFloat();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Float.valueOf(this.dataIn.readUTF()).floatValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to float.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a float type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public double readDouble() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(65);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.DOUBLE_TYPE) {
-                return this.dataIn.readDouble();
-            } else if (type == OpenWireMarshallingSupport.FLOAT_TYPE) {
-                return this.dataIn.readFloat();
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return Double.valueOf(this.dataIn.readUTF()).doubleValue();
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                this.dataIn.reset();
-                throw new NullPointerException("Cannot convert NULL value to double.");
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a double type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public String readString() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(65);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                return null;
-            } else if (type == OpenWireMarshallingSupport.BIG_STRING_TYPE) {
-                return OpenWireMarshallingSupport.readUTF8(dataIn);
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return this.dataIn.readUTF();
-            } else if (type == OpenWireMarshallingSupport.LONG_TYPE) {
-                return new Long(this.dataIn.readLong()).toString();
-            } else if (type == OpenWireMarshallingSupport.INTEGER_TYPE) {
-                return new Integer(this.dataIn.readInt()).toString();
-            } else if (type == OpenWireMarshallingSupport.SHORT_TYPE) {
-                return new Short(this.dataIn.readShort()).toString();
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return new Byte(this.dataIn.readByte()).toString();
-            } else if (type == OpenWireMarshallingSupport.FLOAT_TYPE) {
-                return new Float(this.dataIn.readFloat()).toString();
-            } else if (type == OpenWireMarshallingSupport.DOUBLE_TYPE) {
-                return new Double(this.dataIn.readDouble()).toString();
-            } else if (type == OpenWireMarshallingSupport.BOOLEAN_TYPE) {
-                return (this.dataIn.readBoolean() ? Boolean.TRUE : Boolean.FALSE).toString();
-            } else if (type == OpenWireMarshallingSupport.CHAR_TYPE) {
-                return new Character(this.dataIn.readChar()).toString();
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException(" not a String type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            throw ExceptionSupport.createMessageEOFException(e);
-        } catch (IOException e) {
-            throw ExceptionSupport.createMessageFormatException(e);
-        }
-    }
-
-    @Override
-    public int readBytes(byte[] value) throws JMSException {
-        initializeReading();
-        try {
-            if (value == null) {
-                throw new NullPointerException();
-            }
-
-            if (remainingBytes == -1) {
-                this.dataIn.mark(value.length + 1);
-                int type = this.dataIn.read();
-                if (type == -1) {
-                    throw new MessageEOFException("reached end of data");
-                }
-                if (type != OpenWireMarshallingSupport.BYTE_ARRAY_TYPE) {
-                    throw new MessageFormatException("Not a byte array");
-                }
-                remainingBytes = this.dataIn.readInt();
-            } else if (remainingBytes == 0) {
-                remainingBytes = -1;
-                return -1;
-            }
-
-            if (value.length <= remainingBytes) {
-                // small buffer
-                remainingBytes -= value.length;
-                this.dataIn.readFully(value);
-                return value.length;
-            } else {
-                // big buffer
-                int rc = this.dataIn.read(value, 0, remainingBytes);
-                remainingBytes = 0;
-                return rc;
-            }
-        } catch (EOFException e) {
-            JMSException jmsEx = new MessageEOFException(e.getMessage());
-            jmsEx.setLinkedException(e);
-            throw jmsEx;
-        } catch (IOException e) {
-            JMSException jmsEx = new MessageFormatException(e.getMessage());
-            jmsEx.setLinkedException(e);
-            throw jmsEx;
-        }
-    }
-
-    @Override
-    public Object readObject() throws JMSException {
-        initializeReading();
-        try {
-            this.dataIn.mark(65);
-            int type = this.dataIn.read();
-            if (type == -1) {
-                throw new MessageEOFException("reached end of data");
-            } else if (type == OpenWireMarshallingSupport.NULL) {
-                return null;
-            } else if (type == OpenWireMarshallingSupport.BIG_STRING_TYPE) {
-                return OpenWireMarshallingSupport.readUTF8(dataIn);
-            } else if (type == OpenWireMarshallingSupport.STRING_TYPE) {
-                return this.dataIn.readUTF();
-            } else if (type == OpenWireMarshallingSupport.LONG_TYPE) {
-                return Long.valueOf(this.dataIn.readLong());
-            } else if (type == OpenWireMarshallingSupport.INTEGER_TYPE) {
-                return Integer.valueOf(this.dataIn.readInt());
-            } else if (type == OpenWireMarshallingSupport.SHORT_TYPE) {
-                return Short.valueOf(this.dataIn.readShort());
-            } else if (type == OpenWireMarshallingSupport.BYTE_TYPE) {
-                return Byte.valueOf(this.dataIn.readByte());
-            } else if (type == OpenWireMarshallingSupport.FLOAT_TYPE) {
-                return new Float(this.dataIn.readFloat());
-            } else if (type == OpenWireMarshallingSupport.DOUBLE_TYPE) {
-                return new Double(this.dataIn.readDouble());
-            } else if (type == OpenWireMarshallingSupport.BOOLEAN_TYPE) {
-                return this.dataIn.readBoolean() ? Boolean.TRUE : Boolean.FALSE;
-            } else if (type == OpenWireMarshallingSupport.CHAR_TYPE) {
-                return Character.valueOf(this.dataIn.readChar());
-            } else if (type == OpenWireMarshallingSupport.BYTE_ARRAY_TYPE) {
-                int len = this.dataIn.readInt();
-                byte[] value = new byte[len];
-                this.dataIn.readFully(value);
-                return value;
-            } else {
-                this.dataIn.reset();
-                throw new MessageFormatException("unknown type");
-            }
-        } catch (NumberFormatException mfe) {
-            try {
-                this.dataIn.reset();
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-            throw mfe;
-        } catch (EOFException e) {
-            JMSException jmsEx = new MessageEOFException(e.getMessage());
-            jmsEx.setLinkedException(e);
-            throw jmsEx;
-        } catch (IOException e) {
-            JMSException jmsEx = new MessageFormatException(e.getMessage());
-            jmsEx.setLinkedException(e);
-            throw jmsEx;
-        }
-    }
-
-    @Override
-    public void writeBoolean(boolean value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalBoolean(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeByte(byte value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalByte(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeShort(short value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalShort(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeChar(char value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalChar(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeInt(int value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalInt(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeLong(long value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalLong(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeFloat(float value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalFloat(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeDouble(double value) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalDouble(dataOut, value);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeString(String value) throws JMSException {
-        initializeWriting();
-        try {
-            if (value == null) {
-                OpenWireMarshallingSupport.marshalNull(dataOut);
-            } else {
-                OpenWireMarshallingSupport.marshalString(dataOut, value);
-            }
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeBytes(byte[] value) throws JMSException {
-        writeBytes(value, 0, value.length);
-    }
-
-    @Override
-    public void writeBytes(byte[] value, int offset, int length) throws JMSException {
-        initializeWriting();
-        try {
-            OpenWireMarshallingSupport.marshalByteArray(dataOut, value, offset, length);
-        } catch (IOException ioe) {
-            throw ExceptionSupport.create(ioe);
-        }
-    }
-
-    @Override
-    public void writeObject(Object value) throws JMSException {
-        initializeWriting();
-        if (value == null) {
-            try {
-                OpenWireMarshallingSupport.marshalNull(dataOut);
-            } catch (IOException ioe) {
-                throw ExceptionSupport.create(ioe);
-            }
-        } else if (value instanceof String) {
-            writeString(value.toString());
-        } else if (value instanceof Character) {
-            writeChar(((Character)value).charValue());
-        } else if (value instanceof Boolean) {
-            writeBoolean(((Boolean)value).booleanValue());
-        } else if (value instanceof Byte) {
-            writeByte(((Byte)value).byteValue());
-        } else if (value instanceof Short) {
-            writeShort(((Short)value).shortValue());
-        } else if (value instanceof Integer) {
-            writeInt(((Integer)value).intValue());
-        } else if (value instanceof Float) {
-            writeFloat(((Float)value).floatValue());
-        } else if (value instanceof Double) {
-            writeDouble(((Double)value).doubleValue());
-        } else if (value instanceof byte[]) {
-            writeBytes((byte[])value);
-        } else if (value instanceof Long) {
-            writeLong(((Long)value).longValue());
-        } else {
-            throw new MessageFormatException("Unsupported Object type: " + value.getClass());
-        }
-    }
-
-    @Override
-    public void reset() throws JMSException {
-        storeContent();
-        setReadOnlyBody(true);
-        this.bytesOut = null;
-        this.dataIn = null;
-        this.dataOut = null;
-        this.remainingBytes = -1;
-    }
-
-    private void initializeWriting() throws JMSException {
-        checkReadOnlyBody();
-        if (this.dataOut == null) {
-            this.bytesOut = new ByteArrayOutputStream();
-            this.dataOut = new DataOutputStream(bytesOut);
-        }
-
-        // For a message that already had a body and was sent we need to restore the content
-        // if the message is used again without having its clearBody method called.
-        if (message.hasContent()) {
-            Buffer content = message.getPayload();
-            try {
-                this.dataOut.write(content.getData(), content.getOffset(), content.getLength());
-            } catch (IOException e) {
-                throw ExceptionSupport.create(e);
-            }
-            message.setContent(null);
-        }
-    }
-
-    private void initializeReading() throws MessageNotReadableException {
-        checkWriteOnlyBody();
-        if (this.dataIn == null) {
-            Buffer data;
-            try {
-                data = message.getPayload();
-            } catch (JMSException e) {
-                throw new MessageNotReadableException("Failed to read content from message.");
-            }
-            InputStream is = new ByteArrayInputStream(data);
-            this.dataIn = new DataInputStream(is);
-        }
-    }
-
-    private void storeContent() throws JMSException {
-        if (dataOut != null) {
-            try {
-                dataOut.close();
-                message.setPayload(bytesOut.toBuffer());
-                bytesOut = null;
-                dataOut = null;
-            } catch (IOException ioe) {
-                throw new RuntimeException(ioe);
-            }
-        }
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessage.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessage.java
deleted file mode 100644
index c81f601..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessage.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import javax.jms.JMSException;
-import javax.jms.TextMessage;
-
-import org.apache.activemq.openwire.commands.OpenWireTextMessage;
-
-/**
- * A wrapper around an OpenWireTextMessage.
- */
-public class OpenWireJMSTextMessage extends OpenWireJMSMessage implements TextMessage {
-
-    private final OpenWireTextMessage message;
-
-    /**
-     * Creates a new instance that wraps a new OpenWireJMSTextMessage instance.
-     */
-    public OpenWireJMSTextMessage() {
-        this(new OpenWireTextMessage());
-    }
-
-    /**
-     * Creates a new instance of an OpenWireJMSTextMessage that wraps the
-     * given OpenWireTextMessage instance.
-     *
-     * @param message
-     *        the message to wrap.
-     */
-    public OpenWireJMSTextMessage(OpenWireTextMessage message) {
-        super(message);
-        this.message = message;
-    }
-
-    @Override
-    public OpenWireJMSTextMessage copy() throws JMSException {
-        OpenWireJMSTextMessage other = new OpenWireJMSTextMessage(message.copy());
-        copy(other);
-        return other;
-    }
-
-    @Override
-    public void clearBody() throws JMSException {
-        super.clearBody();
-        message.clearBody();
-    }
-
-    @Override
-    public void setText(String text) throws JMSException {
-        checkReadOnlyBody();
-        message.setText(text);
-    }
-
-    @Override
-    public String getText() throws JMSException {
-        return message.getText();
-    }
-
-    @Override
-    public String toString() {
-        return this.message.toString();
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertyGetter.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertyGetter.java
deleted file mode 100644
index cec7354..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertyGetter.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms.utils;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-
-import org.apache.activemq.openwire.commands.OpenWireMessage;
-import org.apache.activemq.openwire.commands.TransactionId;
-
-/**
- * Utility class used to intercept calls to Message property gets and map the
- * correct OpenWire fields to the property name being queried.
- */
-public class OpenWireMessagePropertyGetter {
-
-    private static final Map<String, PropertyGetter> PROPERTY_GETTERS = new HashMap<String, PropertyGetter>();
-
-    /**
-     * Interface for a Property Get intercepter object used to lookup JMS style
-     * properties that are part of the OpenWire Message object members or perform
-     * some needed conversion action before returned some named property.
-     */
-    public interface PropertyGetter {
-
-        /**
-         * Called when the names property is queried from an OpenWire Message object.
-         *
-         * @param message
-         *        The message being acted upon.
-         *
-         * @return the correct property value from the given Message.
-         */
-        Object getProperty(OpenWireMessage message);
-    }
-
-    static {
-        PROPERTY_GETTERS.put("JMSDestination", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                Destination dest = message.getOriginalDestination();
-                if (dest == null) {
-                    dest = message.getDestination();
-                }
-                if (dest == null) {
-                    return null;
-                }
-                return dest.toString();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSReplyTo", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                if (message.getReplyTo() == null) {
-                    return null;
-                }
-                return message.getReplyTo().toString();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSType", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return message.getType();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSDeliveryMode", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return message.isPersistent() ? "PERSISTENT" : "NON_PERSISTENT";
-            }
-        });
-        PROPERTY_GETTERS.put("JMSPriority", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Integer.valueOf(message.getPriority());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSMessageID", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                if (message.getMessageId() == null) {
-                    return null;
-                }
-                return message.getMessageId().toString();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSTimestamp", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Long.valueOf(message.getTimestamp());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSCorrelationID", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return message.getCorrelationId();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSExpiration", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Long.valueOf(message.getExpiration());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSRedelivered", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Boolean.valueOf(message.isRedelivered());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXDeliveryCount", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Integer.valueOf(message.getRedeliveryCounter() + 1);
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXGroupID", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return message.getGroupId();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXUserID", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                Object userId = message.getUserId();
-                if (userId == null) {
-                    try {
-                        userId = message.getProperty("JMSXUserID");
-                    } catch (JMSException e) {
-                    }
-                }
-
-                return userId;
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXGroupSeq", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return new Integer(message.getGroupSequence());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXProducerTXID", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                TransactionId txId = message.getOriginalTransactionId();
-                if (txId == null) {
-                    txId = message.getTransactionId();
-                }
-                if (txId == null) {
-                    return null;
-                }
-                return txId.toString();
-            }
-        });
-        PROPERTY_GETTERS.put("JMSActiveMQBrokerInTime", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Long.valueOf(message.getBrokerInTime());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSActiveMQBrokerOutTime", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Long.valueOf(message.getBrokerOutTime());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSActiveMQBrokerPath", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Arrays.toString(message.getBrokerPath());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXGroupFirstForConsumer", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return Boolean.valueOf(message.isJMSXGroupFirstForConsumer());
-            }
-        });
-        PROPERTY_GETTERS.put("JMSXMimeType", new PropertyGetter() {
-            @Override
-            public Object getProperty(OpenWireMessage message) {
-                return String.valueOf(message.getMimeType());
-            }
-        });
-    }
-
-    /**
-     * For each of the currently configured message property intercepter instance a
-     * string key value is inserted into an Set and returned.
-     *
-     * @return a Set<String> containing the names of all intercepted properties.
-     */
-    public static Set<String> getPropertyNames() {
-        return PROPERTY_GETTERS.keySet();
-    }
-
-    /**
-     * Static get method that takes a property name and gets the value either via
-     * a registered property get object or through the OpenWireMessage getProperty
-     * method.
-     *
-     * @param message
-     *        the OpenWireMessage instance to read from
-     * @param name
-     *        the property name that is being requested.
-     *
-     * @return the correct value either mapped to an OpenWire attribute of a Message property.
-     *
-     * @throws JMSException if an error occurs while reading the defined property.
-     */
-    public static Object getProperty(OpenWireMessage message, String name) throws JMSException {
-        Object value = null;
-
-        PropertyGetter jmsPropertyExpression = PROPERTY_GETTERS.get(name);
-        if (jmsPropertyExpression != null) {
-            value = jmsPropertyExpression.getProperty(message);
-        } else {
-            value = message.getProperty(name);
-        }
-
-        return value;
-    }
-
-    /**
-     * Allows for the additional PropertyGetter instances to be added to the global set.
-     *
-     * @param propertyName
-     *        The name of the Message property that will be intercepted.
-     * @param getter
-     *        The PropertyGetter instance that should be used for the named property.
-     */
-    public static void addPropertyGetter(String propertyName, PropertyGetter getter) {
-        PROPERTY_GETTERS.put(propertyName, getter);
-    }
-
-    /**
-     * Given a property name, remove the configured getter that has been assigned to
-     * intercept the queries for that property value.
-     *
-     * @param propertyName
-     *        The name of the Property Getter to remove.
-     *
-     * @return true if a getter was removed from the global set.
-     */
-    public boolean removePropertyGetter(String propertyName) {
-        if (PROPERTY_GETTERS.remove(propertyName) != null) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private final String name;
-    private final PropertyGetter jmsPropertyExpression;
-
-    /**
-     * Creates an new property getter instance that is assigned to read the named value.
-     *
-     * @param name
-     *        the property value that this getter is assigned to lookup.
-     */
-    public OpenWireMessagePropertyGetter(String name) {
-        this.name = name;
-        jmsPropertyExpression = PROPERTY_GETTERS.get(name);
-    }
-
-    /**
-     * Gets the correct property value from the OpenWireMessage instance based on
-     * the predefined property mappings.
-     *
-     * @param message
-     *        the OpenWireMessage whose property is being read.
-     *
-     * @return the correct value either mapped to an OpenWire attribute of a Message property.
-     *
-     * @throws JMSException if an error occurs while reading the defined property.
-     */
-    public Object get(OpenWireMessage message) throws JMSException {
-        if (jmsPropertyExpression != null) {
-            return jmsPropertyExpression.getProperty(message);
-        }
-
-        return message.getProperty(name);
-    }
-
-    /**
-     * @return the property name that is being intercepted for the OpenWireMessage.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    /**
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    /**
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (o == null || !this.getClass().equals(o.getClass())) {
-            return false;
-        }
-        return name.equals(((OpenWireMessagePropertyGetter) o).name);
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertySetter.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertySetter.java
deleted file mode 100644
index d3f6854..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/OpenWireMessagePropertySetter.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms.utils;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jms.DeliveryMode;
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-
-import org.apache.activemq.openwire.commands.OpenWireDestination;
-import org.apache.activemq.openwire.commands.OpenWireMessage;
-
-/**
- * Utility class used to intercept calls to Message property sets and map the
- * correct OpenWire fields to the property name being set.
- */
-public class OpenWireMessagePropertySetter {
-
-    private static final Map<String, PropertySetter> PROPERTY_SETTERS = new HashMap<String, PropertySetter>();
-
-    /**
-     * Interface for a Property Set intercepter object used to write JMS style
-     * properties that are part of the OpenWire Message object members or perform
-     * some needed conversion action before some named property is set.
-     */
-    interface PropertySetter {
-
-        /**
-         * Called when the names property is assigned from an OpenWire Message object.
-         *
-         * @param message
-         *        The message instance being acted upon.
-         * @param value
-         *        The value to assign to the intercepted property.
-         *
-         * @throws MessageFormatException if an error occurs writing the property.
-s         */
-        void setProperty(OpenWireMessage message, Object value) throws MessageFormatException;
-    }
-
-    static {
-        PROPERTY_SETTERS.put("JMSXDeliveryCount", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSXDeliveryCount cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setRedeliveryCounter(rc.intValue() - 1);
-            }
-        });
-        PROPERTY_SETTERS.put("JMSXGroupID", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                String rc = (String) TypeConversionSupport.convert(value, String.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSXGroupID cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setGroupID(rc);
-            }
-        });
-        PROPERTY_SETTERS.put("JMSXGroupSeq", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSXGroupSeq cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setGroupSequence(rc.intValue());
-            }
-        });
-        PROPERTY_SETTERS.put("JMSCorrelationID", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                String rc = (String) TypeConversionSupport.convert(value, String.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSCorrelationID cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setCorrelationId(rc);
-            }
-        });
-        PROPERTY_SETTERS.put("JMSDeliveryMode", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class);
-                if (rc == null) {
-                    Boolean bool = (Boolean) TypeConversionSupport.convert(value, Boolean.class);
-                    if (bool == null) {
-                        throw new MessageFormatException("Property JMSDeliveryMode cannot be set from a " + value.getClass().getName() + ".");
-                    } else {
-                        message.setPersistent(bool.booleanValue());
-                    }
-                } else {
-                    message.setPersistent(rc == DeliveryMode.PERSISTENT);
-                }
-            }
-        });
-        PROPERTY_SETTERS.put("JMSExpiration", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Long rc = (Long) TypeConversionSupport.convert(value, Long.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSExpiration cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setExpiration(rc.longValue());
-            }
-        });
-        PROPERTY_SETTERS.put("JMSPriority", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Integer rc = (Integer) TypeConversionSupport.convert(value, Integer.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSPriority cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setPriority(rc.byteValue());
-            }
-        });
-        PROPERTY_SETTERS.put("JMSRedelivered", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Boolean rc = (Boolean) TypeConversionSupport.convert(value, Boolean.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSRedelivered cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setRedelivered(rc.booleanValue());
-            }
-        });
-        PROPERTY_SETTERS.put("JMSReplyTo", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                OpenWireDestination rc = (OpenWireDestination) TypeConversionSupport.convert(value, OpenWireDestination.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSReplyTo cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setReplyTo(rc);
-            }
-        });
-        PROPERTY_SETTERS.put("JMSTimestamp", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                Long rc = (Long) TypeConversionSupport.convert(value, Long.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSTimestamp cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setTimestamp(rc.longValue());
-            }
-        });
-        PROPERTY_SETTERS.put("JMSType", new PropertySetter() {
-            @Override
-            public void setProperty(OpenWireMessage message, Object value) throws MessageFormatException {
-                String rc = (String) TypeConversionSupport.convert(value, String.class);
-                if (rc == null) {
-                    throw new MessageFormatException("Property JMSType cannot be set from a " + value.getClass().getName() + ".");
-                }
-                message.setType(rc);
-            }
-        });
-    }
-
-    /**
-     * Static set method that takes a property name and sets the value either via
-     * a registered property set object or through the OpenWireMessage setProperty
-     * method.
-     *
-     * @param message
-     *        the OpenWireMessage instance to write to.
-     * @param name
-     *        the property name that is being written.
-     * @param value
-     *        the new value to assign for the named property.
-     *
-     * @throws JMSException if an error occurs while writting the defined property.
-     */
-    public static void setProperty(OpenWireMessage message, String name, Object value) throws JMSException {
-        PropertySetter jmsPropertyExpression = PROPERTY_SETTERS.get(name);
-        if (jmsPropertyExpression != null) {
-            jmsPropertyExpression.setProperty(message, value);
-        } else {
-            message.setProperty(name, value);
-        }
-    }
-
-    /**
-     * Allows for the additional PropertySetter instances to be added to the global set.
-     *
-     * @param propertyName
-     *        The name of the Message property that will be intercepted.
-     * @param getter
-     *        The PropertySetter instance that should be used for the named property.
-     */
-    public static void addPropertySetter(String propertyName, PropertySetter getter) {
-        PROPERTY_SETTERS.put(propertyName, getter);
-    }
-
-    /**
-     * Given a property name, remove the configured getter that has been assigned to
-     * intercept the queries for that property value.
-     *
-     * @param propertyName
-     *        The name of the Property Getter to remove.
-     *
-     * @return true if a getter was removed from the global set.
-     */
-    public boolean removePropertySetter(String propertyName) {
-        if (PROPERTY_SETTERS.remove(propertyName) != null) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private final String name;
-    private final PropertySetter jmsPropertyExpression;
-
-    /**
-     * For each of the currently configured message property intercepter instance a
-     * string key value is inserted into an Set and returned.
-     *
-     * @return a Set<String> containing the names of all intercepted properties.
-     */
-    public static Set<String> getPropertyNames() {
-        return PROPERTY_SETTERS.keySet();
-    }
-
-    /**
-     * Creates an new property getter instance that is assigned to read the named value.
-     *
-     * @param name
-     *        the property value that this getter is assigned to lookup.
-     */
-    public OpenWireMessagePropertySetter(String name) {
-        this.name = name;
-        jmsPropertyExpression = PROPERTY_SETTERS.get(name);
-    }
-
-    /**
-     * Sets the correct property value from the OpenWireMessage instance based on
-     * the predefined property mappings.
-     *
-     * @param message
-     *        the OpenWireMessage whose property is being read.
-     * @param value
-     *        the value to be set on the intercepted OpenWireMessage property.
-     *
-     * @throws JMSException if an error occurs while reading the defined property.
-     */
-    public void set(OpenWireMessage message, Object value) throws JMSException {
-        if (jmsPropertyExpression != null) {
-            jmsPropertyExpression.setProperty(message, value);
-        } else {
-            message.setProperty(name, value);
-        }
-    }
-
-    /**
-     * @return the property name that is being intercepted for the OpenWireMessage.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    /**
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        return name.hashCode();
-    }
-
-    /**
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (o == null || !this.getClass().equals(o.getClass())) {
-            return false;
-        }
-        return name.equals(((OpenWireMessagePropertySetter) o).name);
-    }
-}
diff --git a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/TypeConversionSupport.java b/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/TypeConversionSupport.java
deleted file mode 100644
index a4121e4..0000000
--- a/openwire-jms/src/main/java/org/apache/activemq/openwire/jms/utils/TypeConversionSupport.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms.utils;
-
-import java.math.BigInteger;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.activemq.openwire.commands.OpenWireDestination;
-import org.fusesource.hawtbuf.UTF8Buffer;
-
-/**
- * Type conversion support for OpenWireMessage property types.
- */
-public final class TypeConversionSupport {
-
-    private static final Converter IDENTITY_CONVERTER = new Converter() {
-        @Override
-        public Object convert(Object value) {
-            return value;
-        }
-    };
-
-    private static class ConversionKey {
-        final Class<?> from;
-        final Class<?> to;
-        final int hashCode;
-
-        public ConversionKey(Class<?> from, Class<?> to) {
-            this.from = from;
-            this.to = to;
-            this.hashCode = from.hashCode() ^ (to.hashCode() << 1);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            ConversionKey x = (ConversionKey) o;
-            return x.from == from && x.to == to;
-        }
-
-        @Override
-        public int hashCode() {
-            return hashCode;
-        }
-    }
-
-    public interface Converter {
-        Object convert(Object value);
-    }
-
-    private static final Map<ConversionKey, Converter> CONVERSION_MAP = new HashMap<ConversionKey, Converter>();
-    static {
-        Converter toStringConverter = new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return value.toString();
-            }
-        };
-        CONVERSION_MAP.put(new ConversionKey(Boolean.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Byte.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Short.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Integer.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Long.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Float.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(Double.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(UTF8Buffer.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(URI.class, String.class), toStringConverter);
-        CONVERSION_MAP.put(new ConversionKey(BigInteger.class, String.class), toStringConverter);
-
-        CONVERSION_MAP.put(new ConversionKey(String.class, Boolean.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Boolean.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Byte.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Byte.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Short.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Short.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Integer.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Integer.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Long.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Long.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Float.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Float.valueOf((String) value);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, Double.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Double.valueOf((String) value);
-            }
-        });
-
-        Converter longConverter = new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Long.valueOf(((Number) value).longValue());
-            }
-        };
-        CONVERSION_MAP.put(new ConversionKey(Byte.class, Long.class), longConverter);
-        CONVERSION_MAP.put(new ConversionKey(Short.class, Long.class), longConverter);
-        CONVERSION_MAP.put(new ConversionKey(Integer.class, Long.class), longConverter);
-        CONVERSION_MAP.put(new ConversionKey(Date.class, Long.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Long.valueOf(((Date) value).getTime());
-            }
-        });
-
-        Converter intConverter = new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Integer.valueOf(((Number) value).intValue());
-            }
-        };
-        CONVERSION_MAP.put(new ConversionKey(Byte.class, Integer.class), intConverter);
-        CONVERSION_MAP.put(new ConversionKey(Short.class, Integer.class), intConverter);
-
-        CONVERSION_MAP.put(new ConversionKey(Byte.class, Short.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return Short.valueOf(((Number) value).shortValue());
-            }
-        });
-
-        CONVERSION_MAP.put(new ConversionKey(Float.class, Double.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return new Double(((Number) value).doubleValue());
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, OpenWireDestination.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                return OpenWireDestination.createDestination((String) value, OpenWireDestination.QUEUE_TYPE);
-            }
-        });
-        CONVERSION_MAP.put(new ConversionKey(String.class, URI.class), new Converter() {
-            @Override
-            public Object convert(Object value) {
-                String text = value.toString();
-                try {
-                    return new URI(text);
-                } catch (URISyntaxException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        });
-    }
-
-    private TypeConversionSupport() {
-    }
-
-    public static Object convert(Object value, Class<?> to) {
-        if (value == null) {
-            // lets avoid NullPointerException when converting to boolean for null values
-            if (boolean.class.isAssignableFrom(to)) {
-                return Boolean.FALSE;
-            }
-            return null;
-        }
-
-        // eager same instance type test to avoid the overhead of invoking the
-        // type converter if already same type
-        if (to.isInstance(value)) {
-            return to.cast(value);
-        }
-
-        // lookup converter
-        Converter c = lookupConverter(value.getClass(), to);
-        if (c != null) {
-            return c.convert(value);
-        } else {
-            return null;
-        }
-    }
-
-    public static Converter lookupConverter(Class<?> from, Class<?> to) {
-        // use wrapped type for primitives
-        if (from.isPrimitive()) {
-            from = convertPrimitiveTypeToWrapperType(from);
-        }
-        if (to.isPrimitive()) {
-            to = convertPrimitiveTypeToWrapperType(to);
-        }
-
-        if (from.equals(to)) {
-            return IDENTITY_CONVERTER;
-        }
-
-        return CONVERSION_MAP.get(new ConversionKey(from, to));
-    }
-
-    /**
-     * Converts primitive types such as int to its wrapper type like
-     * {@link Integer}
-     */
-    private static Class<?> convertPrimitiveTypeToWrapperType(Class<?> type) {
-        Class<?> rc = type;
-        if (type.isPrimitive()) {
-            if (type == int.class) {
-                rc = Integer.class;
-            } else if (type == long.class) {
-                rc = Long.class;
-            } else if (type == double.class) {
-                rc = Double.class;
-            } else if (type == float.class) {
-                rc = Float.class;
-            } else if (type == short.class) {
-                rc = Short.class;
-            } else if (type == byte.class) {
-                rc = Byte.class;
-            } else if (type == boolean.class) {
-                rc = Boolean.class;
-            }
-        }
-        return rc;
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessageTest.java
deleted file mode 100644
index 04f19b2..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSBytesMessageTest.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.commands.CommandTypes;
-import org.apache.activemq.openwire.jms.OpenWireJMSBytesMessage;
-import org.junit.Test;
-
-/**
- * Test that the OpenWireJMSBytesMessage object is JMS Compliant.
- */
-public class OpenWireJMSBytesMessageTest {
-
-    @Test
-    public void testGetDataStructureType() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        assertEquals(CommandTypes.OPENWIRE_BYTES_MESSAGE, msg.getOpenWireMessage().getDataStructureType());
-    }
-
-    @Test
-    public void testGetBodyLength() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        int len = 10;
-        try {
-            for (int i = 0; i < len; i++) {
-                msg.writeLong(5L);
-            }
-        } catch (JMSException ex) {
-            ex.printStackTrace();
-        }
-        try {
-            msg.reset();
-            assertTrue(msg.getBodyLength() == (len * 8));
-        } catch (Throwable e) {
-            e.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadBoolean() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeBoolean(true);
-            msg.reset();
-            assertTrue(msg.readBoolean());
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadByte() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeByte((byte) 2);
-            msg.reset();
-            assertTrue(msg.readByte() == 2);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadUnsignedByte() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeByte((byte) 2);
-            msg.reset();
-            assertTrue(msg.readUnsignedByte() == 2);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadShort() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeShort((short) 3000);
-            msg.reset();
-            assertTrue(msg.readShort() == 3000);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadUnsignedShort() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeShort((short) 3000);
-            msg.reset();
-            assertTrue(msg.readUnsignedShort() == 3000);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadChar() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeChar('a');
-            msg.reset();
-            assertTrue(msg.readChar() == 'a');
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadInt() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeInt(3000);
-            msg.reset();
-            assertTrue(msg.readInt() == 3000);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadLong() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeLong(3000);
-            msg.reset();
-            assertTrue(msg.readLong() == 3000);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadFloat() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeFloat(3.3f);
-            msg.reset();
-            assertTrue(msg.readFloat() == 3.3f);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadDouble() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeDouble(3.3d);
-            msg.reset();
-            assertTrue(msg.readDouble() == 3.3d);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadUTF() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            String str = "this is a test";
-            msg.writeUTF(str);
-            msg.reset();
-            assertTrue(msg.readUTF().equals(str));
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadBytesbyteArray() {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            byte[] data = new byte[50];
-            for (int i = 0; i < data.length; i++) {
-                data[i] = (byte) i;
-            }
-            msg.writeBytes(data);
-            msg.reset();
-            byte[] test = new byte[data.length];
-            msg.readBytes(test);
-            for (int i = 0; i < test.length; i++) {
-                assertTrue(test[i] == i);
-            }
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testWriteObject() throws JMSException {
-        OpenWireJMSBytesMessage msg = new OpenWireJMSBytesMessage();
-        try {
-            msg.writeObject("fred");
-            msg.writeObject(Boolean.TRUE);
-            msg.writeObject(Character.valueOf('q'));
-            msg.writeObject(Byte.valueOf((byte) 1));
-            msg.writeObject(Short.valueOf((short) 3));
-            msg.writeObject(Integer.valueOf(3));
-            msg.writeObject(Long.valueOf(300L));
-            msg.writeObject(new Float(3.3f));
-            msg.writeObject(new Double(3.3));
-            msg.writeObject(new byte[3]);
-        } catch (MessageFormatException mfe) {
-            fail("objectified primitives should be allowed");
-        }
-        try {
-            msg.writeObject(new Object());
-            fail("only objectified primitives are allowed");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testClearBody() throws JMSException {
-        OpenWireJMSBytesMessage bytesMessage = new OpenWireJMSBytesMessage();
-        try {
-            bytesMessage.writeInt(1);
-            bytesMessage.clearBody();
-            assertFalse(bytesMessage.isReadOnlyBody());
-            bytesMessage.writeInt(1);
-            bytesMessage.readInt();
-        } catch (MessageNotReadableException mnwe) {
-        } catch (MessageNotWriteableException mnwe) {
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReset() throws JMSException {
-        OpenWireJMSBytesMessage message = new OpenWireJMSBytesMessage();
-        try {
-            message.writeDouble(24.5);
-            message.writeLong(311);
-        } catch (MessageNotWriteableException mnwe) {
-            fail("should be writeable");
-        }
-        message.reset();
-        try {
-            assertTrue(message.isReadOnlyBody());
-            assertEquals(message.readDouble(), 24.5, 0);
-            assertEquals(message.readLong(), 311);
-        } catch (MessageNotReadableException mnre) {
-            fail("should be readable");
-        }
-        try {
-            message.writeInt(33);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testReadOnlyBody() throws JMSException {
-        OpenWireJMSBytesMessage message = new OpenWireJMSBytesMessage();
-        try {
-            message.writeBoolean(true);
-            message.writeByte((byte) 1);
-            message.writeByte((byte) 1);
-            message.writeBytes(new byte[1]);
-            message.writeBytes(new byte[3], 0, 2);
-            message.writeChar('a');
-            message.writeDouble(1.5);
-            message.writeFloat((float) 1.5);
-            message.writeInt(1);
-            message.writeLong(1);
-            message.writeObject("stringobj");
-            message.writeShort((short) 1);
-            message.writeShort((short) 1);
-            message.writeUTF("utfstring");
-        } catch (MessageNotWriteableException mnwe) {
-            fail("Should be writeable");
-        }
-        message.reset();
-        try {
-            message.readBoolean();
-            message.readByte();
-            message.readUnsignedByte();
-            message.readBytes(new byte[1]);
-            message.readBytes(new byte[2], 2);
-            message.readChar();
-            message.readDouble();
-            message.readFloat();
-            message.readInt();
-            message.readLong();
-            message.readUTF();
-            message.readShort();
-            message.readUnsignedShort();
-            message.readUTF();
-        } catch (MessageNotReadableException mnwe) {
-            fail("Should be readable");
-        }
-        try {
-            message.writeBoolean(true);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeByte((byte) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeBytes(new byte[3], 0, 2);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeChar('a');
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeDouble(1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeFloat((float) 1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeInt(1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeLong(1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeObject("stringobj");
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeShort((short) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeUTF("utfstring");
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testWriteOnlyBody() throws JMSException {
-        OpenWireJMSBytesMessage message = new OpenWireJMSBytesMessage();
-        message.clearBody();
-        try {
-            message.writeBoolean(true);
-            message.writeByte((byte) 1);
-            message.writeByte((byte) 1);
-            message.writeBytes(new byte[1]);
-            message.writeBytes(new byte[3], 0, 2);
-            message.writeChar('a');
-            message.writeDouble(1.5);
-            message.writeFloat((float) 1.5);
-            message.writeInt(1);
-            message.writeLong(1);
-            message.writeObject("stringobj");
-            message.writeShort((short) 1);
-            message.writeShort((short) 1);
-            message.writeUTF("utfstring");
-        } catch (MessageNotWriteableException mnwe) {
-            fail("Should be writeable");
-        }
-        try {
-            message.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException mnwe) {
-        }
-        try {
-            message.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readUnsignedByte();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readBytes(new byte[2], 2);
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readUTF();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readUnsignedShort();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readUTF();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessageTest.java
deleted file mode 100644
index 9313a5e..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMapMessageTest.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.jms.OpenWireJMSMapMessage;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Test the OpenWireJMSMapMessage facade class.
- */
-public class OpenWireJMSMapMessageTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(OpenWireJMSMapMessageTest.class);
-
-    private final String name = "testName";
-
-    @Test
-    public void testBytesConversion() throws JMSException, IOException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setBoolean("boolean", true);
-        msg.setByte("byte", (byte)1);
-        msg.setBytes("bytes", new byte[1]);
-        msg.setChar("char", 'a');
-        msg.setDouble("double", 1.5);
-        msg.setFloat("float", 1.5f);
-        msg.setInt("int", 1);
-        msg.setLong("long", 1);
-        msg.setObject("object", "stringObj");
-        msg.setShort("short", (short)1);
-        msg.setString("string", "string");
-
-        // Test with a 1Meg String
-        StringBuffer bigSB = new StringBuffer(1024 * 1024);
-        for (int i = 0; i < 1024 * 1024; i++) {
-            bigSB.append('a' + i % 26);
-        }
-        String bigString = bigSB.toString();
-
-        msg.setString("bigString", bigString);
-
-        msg = msg.copy();
-
-        assertEquals(msg.getBoolean("boolean"), true);
-        assertEquals(msg.getByte("byte"), (byte)1);
-        assertEquals(msg.getBytes("bytes").length, 1);
-        assertEquals(msg.getChar("char"), 'a');
-        assertEquals(msg.getDouble("double"), 1.5, 0);
-        assertEquals(msg.getFloat("float"), 1.5f, 0);
-        assertEquals(msg.getInt("int"), 1);
-        assertEquals(msg.getLong("long"), 1);
-        assertEquals(msg.getObject("object"), "stringObj");
-        assertEquals(msg.getShort("short"), (short)1);
-        assertEquals(msg.getString("string"), "string");
-        assertEquals(msg.getString("bigString"), bigString);
-    }
-
-    @Test
-    public void testGetBoolean() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setBoolean(name, true);
-        msg.setReadOnlyBody(true);
-        assertTrue(msg.getBoolean(name));
-        msg.clearBody();
-        msg.setString(name, "true");
-
-        msg = msg.copy();
-
-        assertTrue(msg.getBoolean(name));
-    }
-
-    @Test
-    public void testGetByte() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setByte(this.name, (byte)1);
-        msg = msg.copy();
-        assertTrue(msg.getByte(this.name) == (byte)1);
-    }
-
-    @Test
-    public void testGetShort() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setShort(this.name, (short)1);
-            msg = msg.copy();
-            assertTrue(msg.getShort(this.name) == (short)1);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetChar() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setChar(this.name, 'a');
-            msg = msg.copy();
-            assertTrue(msg.getChar(this.name) == 'a');
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetInt() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setInt(this.name, 1);
-            msg = msg.copy();
-            assertTrue(msg.getInt(this.name) == 1);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetLong() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setLong(this.name, 1);
-            msg = msg.copy();
-            assertTrue(msg.getLong(this.name) == 1);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetFloat() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setFloat(this.name, 1.5f);
-            msg = msg.copy();
-            assertTrue(msg.getFloat(this.name) == 1.5f);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetDouble() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            msg.setDouble(this.name, 1.5);
-            msg = msg.copy();
-            assertTrue(msg.getDouble(this.name) == 1.5);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetString() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            String str = "test";
-            msg.setString(this.name, str);
-            msg = msg.copy();
-            assertEquals(msg.getString(this.name), str);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetBytes() {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        try {
-            byte[] bytes1 = new byte[3];
-            byte[] bytes2 = new byte[2];
-            System.arraycopy(bytes1, 0, bytes2, 0, 2);
-            msg.setBytes(this.name, bytes1);
-            msg.setBytes(this.name + "2", bytes1, 0, 2);
-            msg = msg.copy();
-            assertTrue(Arrays.equals(msg.getBytes(this.name), bytes1));
-            assertEquals(msg.getBytes(this.name + "2").length, bytes2.length);
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testGetObject() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        Boolean booleanValue = Boolean.TRUE;
-        Byte byteValue = Byte.valueOf("1");
-        byte[] bytesValue = new byte[3];
-        Character charValue = new Character('a');
-        Double doubleValue = Double.valueOf("1.5");
-        Float floatValue = Float.valueOf("1.5");
-        Integer intValue = Integer.valueOf("1");
-        Long longValue = Long.valueOf("1");
-        Short shortValue = Short.valueOf("1");
-        String stringValue = "string";
-
-        try {
-            msg.setObject("boolean", booleanValue);
-            msg.setObject("byte", byteValue);
-            msg.setObject("bytes", bytesValue);
-            msg.setObject("char", charValue);
-            msg.setObject("double", doubleValue);
-            msg.setObject("float", floatValue);
-            msg.setObject("int", intValue);
-            msg.setObject("long", longValue);
-            msg.setObject("short", shortValue);
-            msg.setObject("string", stringValue);
-        } catch (MessageFormatException mfe) {
-            LOG.warn("Caught: " + mfe);
-            mfe.printStackTrace();
-            fail("object formats should be correct");
-        }
-
-        msg = msg.copy();
-
-        assertTrue(msg.getObject("boolean") instanceof Boolean);
-        assertEquals(msg.getObject("boolean"), booleanValue);
-        assertEquals(msg.getBoolean("boolean"), booleanValue.booleanValue());
-        assertTrue(msg.getObject("byte") instanceof Byte);
-        assertEquals(msg.getObject("byte"), byteValue);
-        assertEquals(msg.getByte("byte"), byteValue.byteValue());
-        assertTrue(msg.getObject("bytes") instanceof byte[]);
-        assertEquals(((byte[])msg.getObject("bytes")).length, bytesValue.length);
-        assertEquals(msg.getBytes("bytes").length, bytesValue.length);
-        assertTrue(msg.getObject("char") instanceof Character);
-        assertEquals(msg.getObject("char"), charValue);
-        assertEquals(msg.getChar("char"), charValue.charValue());
-        assertTrue(msg.getObject("double") instanceof Double);
-        assertEquals(msg.getObject("double"), doubleValue);
-        assertEquals(msg.getDouble("double"), doubleValue.doubleValue(), 0);
-        assertTrue(msg.getObject("float") instanceof Float);
-        assertEquals(msg.getObject("float"), floatValue);
-        assertEquals(msg.getFloat("float"), floatValue.floatValue(), 0);
-        assertTrue(msg.getObject("int") instanceof Integer);
-        assertEquals(msg.getObject("int"), intValue);
-        assertEquals(msg.getInt("int"), intValue.intValue());
-        assertTrue(msg.getObject("long") instanceof Long);
-        assertEquals(msg.getObject("long"), longValue);
-        assertEquals(msg.getLong("long"), longValue.longValue());
-        assertTrue(msg.getObject("short") instanceof Short);
-        assertEquals(msg.getObject("short"), shortValue);
-        assertEquals(msg.getShort("short"), shortValue.shortValue());
-        assertTrue(msg.getObject("string") instanceof String);
-        assertEquals(msg.getObject("string"), stringValue);
-        assertEquals(msg.getString("string"), stringValue);
-
-        msg.clearBody();
-        try {
-            msg.setObject("object", new Object());
-            fail("should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-
-    }
-
-    @Test
-    public void testGetMapNames() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setBoolean("boolean", true);
-        msg.setByte("byte", (byte)1);
-        msg.setBytes("bytes1", new byte[1]);
-        msg.setBytes("bytes2", new byte[3], 0, 2);
-        msg.setChar("char", 'a');
-        msg.setDouble("double", 1.5);
-        msg.setFloat("float", 1.5f);
-        msg.setInt("int", 1);
-        msg.setLong("long", 1);
-        msg.setObject("object", "stringObj");
-        msg.setShort("short", (short)1);
-        msg.setString("string", "string");
-
-        msg = msg.copy();
-
-        Enumeration<String> mapNamesEnum = msg.getMapNames();
-        List<String> mapNamesList = Collections.list(mapNamesEnum);
-
-        assertEquals(mapNamesList.size(), 12);
-        assertTrue(mapNamesList.contains("boolean"));
-        assertTrue(mapNamesList.contains("byte"));
-        assertTrue(mapNamesList.contains("bytes1"));
-        assertTrue(mapNamesList.contains("bytes2"));
-        assertTrue(mapNamesList.contains("char"));
-        assertTrue(mapNamesList.contains("double"));
-        assertTrue(mapNamesList.contains("float"));
-        assertTrue(mapNamesList.contains("int"));
-        assertTrue(mapNamesList.contains("long"));
-        assertTrue(mapNamesList.contains("object"));
-        assertTrue(mapNamesList.contains("short"));
-        assertTrue(mapNamesList.contains("string"));
-    }
-
-    @Test
-    public void testItemExists() throws JMSException {
-        OpenWireJMSMapMessage mapMessage = new OpenWireJMSMapMessage();
-
-        mapMessage.setString("exists", "test");
-
-        mapMessage = mapMessage.copy();
-
-        assertTrue(mapMessage.itemExists("exists"));
-        assertFalse(mapMessage.itemExists("doesntExist"));
-    }
-
-    @Test
-    public void testClearBody() throws JMSException {
-        OpenWireJMSMapMessage mapMessage = new OpenWireJMSMapMessage();
-        mapMessage.setString("String", "String");
-        mapMessage.clearBody();
-        assertFalse(mapMessage.isReadOnlyBody());
-
-        mapMessage.getOpenWireMessage().onSend();
-        mapMessage.getOpenWireMessage().setContent(mapMessage.getOpenWireMessage().getContent());
-        assertNull(mapMessage.getString("String"));
-        mapMessage.clearBody();
-        mapMessage.setString("String", "String");
-
-        mapMessage = mapMessage.copy();
-
-        mapMessage.getString("String");
-    }
-
-    @Test
-    public void testReadOnlyBody() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setBoolean("boolean", true);
-        msg.setByte("byte", (byte)1);
-        msg.setBytes("bytes", new byte[1]);
-        msg.setBytes("bytes2", new byte[3], 0, 2);
-        msg.setChar("char", 'a');
-        msg.setDouble("double", 1.5);
-        msg.setFloat("float", 1.5f);
-        msg.setInt("int", 1);
-        msg.setLong("long", 1);
-        msg.setObject("object", "stringObj");
-        msg.setShort("short", (short)1);
-        msg.setString("string", "string");
-
-        msg.setReadOnlyBody(true);
-
-        try {
-            msg.getBoolean("boolean");
-            msg.getByte("byte");
-            msg.getBytes("bytes");
-            msg.getChar("char");
-            msg.getDouble("double");
-            msg.getFloat("float");
-            msg.getInt("int");
-            msg.getLong("long");
-            msg.getObject("object");
-            msg.getShort("short");
-            msg.getString("string");
-        } catch (MessageNotReadableException mnre) {
-            fail("should be readable");
-        }
-        try {
-            msg.setBoolean("boolean", true);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setByte("byte", (byte)1);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setBytes("bytes", new byte[1]);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setBytes("bytes2", new byte[3], 0, 2);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setChar("char", 'a');
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setDouble("double", 1.5);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setFloat("float", 1.5f);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setInt("int", 1);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setLong("long", 1);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setObject("object", "stringObj");
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setShort("short", (short)1);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            msg.setString("string", "string");
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testWriteOnlyBody() throws JMSException {
-        OpenWireJMSMapMessage msg = new OpenWireJMSMapMessage();
-        msg.setReadOnlyBody(false);
-
-        msg.setBoolean("boolean", true);
-        msg.setByte("byte", (byte)1);
-        msg.setBytes("bytes", new byte[1]);
-        msg.setBytes("bytes2", new byte[3], 0, 2);
-        msg.setChar("char", 'a');
-        msg.setDouble("double", 1.5);
-        msg.setFloat("float", 1.5f);
-        msg.setInt("int", 1);
-        msg.setLong("long", 1);
-        msg.setObject("object", "stringObj");
-        msg.setShort("short", (short)1);
-        msg.setString("string", "string");
-
-        msg.setReadOnlyBody(true);
-
-        msg.getBoolean("boolean");
-        msg.getByte("byte");
-        msg.getBytes("bytes");
-        msg.getChar("char");
-        msg.getDouble("double");
-        msg.getFloat("float");
-        msg.getInt("int");
-        msg.getLong("long");
-        msg.getObject("object");
-        msg.getShort("short");
-        msg.getString("string");
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMessageTest.java
deleted file mode 100644
index f6bb646..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSMessageTest.java
+++ /dev/null
@@ -1,991 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Map;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.codec.OpenWireFormat;
-import org.apache.activemq.openwire.commands.CommandTypes;
-import org.apache.activemq.openwire.commands.CommandVisitor;
-import org.apache.activemq.openwire.commands.OpenWireDestination;
-import org.apache.activemq.openwire.commands.OpenWireTopic;
-import org.apache.activemq.openwire.commands.Response;
-import org.apache.activemq.openwire.jms.OpenWireJMSBytesMessage;
-import org.apache.activemq.openwire.jms.OpenWireJMSMessage;
-import org.fusesource.hawtbuf.Buffer;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tests for the OpenWireJMSMessage wrapper class.
- */
-public class OpenWireJMSMessageTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(OpenWireJMSMessageTest.class);
-
-    protected boolean readOnlyMessage;
-
-    private String jmsMessageID;
-    private String jmsCorrelationID;
-    private OpenWireDestination jmsDestination;
-    private OpenWireDestination jmsReplyTo;
-    private int jmsDeliveryMode;
-    private boolean jmsRedelivered;
-    private String jmsType;
-    private long jmsExpiration;
-    private int jmsPriority;
-    private long jmsTimestamp;
-    private long[] consumerIDs;
-
-    @Before
-    public void setUp() throws Exception {
-        this.jmsMessageID = "ID:TEST-ID:0:0:0:1";
-        this.jmsCorrelationID = "testcorrelationid";
-        this.jmsDestination = new OpenWireTopic("test.topic");
-        this.jmsReplyTo = new OpenWireTopic("test.replyto.topic:001");
-        this.jmsDeliveryMode = Message.DEFAULT_DELIVERY_MODE;
-        this.jmsRedelivered = true;
-        this.jmsType = "test type";
-        this.jmsExpiration = 100000;
-        this.jmsPriority = 5;
-        this.jmsTimestamp = System.currentTimeMillis();
-        this.readOnlyMessage = false;
-        this.consumerIDs = new long[3];
-        for (int i = 0; i < this.consumerIDs.length; i++) {
-            this.consumerIDs[i] = i;
-        }
-    }
-
-    @Test
-    public void testGetDataStructureType() {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        assertEquals(msg.getOpenWireMessage().getDataStructureType(), CommandTypes.OPENWIRE_MESSAGE);
-    }
-
-    @Test
-    public void testHashCode() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSMessageID(this.jmsMessageID);
-        assertTrue(msg.getJMSMessageID().hashCode() == jmsMessageID.hashCode());
-    }
-
-    @Test
-    public void testSetReadOnly() {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setReadOnlyProperties(true);
-        boolean test = false;
-        try {
-            msg.setIntProperty("test", 1);
-        } catch (MessageNotWriteableException me) {
-            test = true;
-        } catch (JMSException e) {
-            e.printStackTrace(System.err);
-            test = false;
-        }
-        assertTrue(test);
-    }
-
-    @Test
-    public void testSetToForeignJMSID() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSMessageID("ID:EMS-SERVER.8B443C380083:429");
-    }
-
-    @Test
-    public void testEqualsObject() throws Exception {
-        OpenWireJMSMessage msg1 = new OpenWireJMSMessage();
-        OpenWireJMSMessage msg2 = new OpenWireJMSMessage();
-        msg1.setJMSMessageID(this.jmsMessageID);
-        assertTrue(!msg1.equals(msg2));
-        msg2.setJMSMessageID(this.jmsMessageID);
-        assertTrue(msg1.equals(msg2));
-    }
-
-    @Test
-    public void testShallowCopy() throws Exception {
-        OpenWireJMSMessage msg1 = new OpenWireJMSMessage();
-        msg1.setJMSMessageID(jmsMessageID);
-        OpenWireJMSMessage msg2 = msg1.copy();
-        assertTrue(msg1 != msg2 && msg1.equals(msg2));
-    }
-
-    @Test
-    public void testCopy() throws Exception {
-        this.jmsMessageID = "testid";
-        this.jmsCorrelationID = "testcorrelationid";
-        this.jmsDestination = new OpenWireTopic("test.topic");
-        this.jmsReplyTo = new OpenWireTopic("test.replyto.topic:001");
-        this.jmsDeliveryMode = Message.DEFAULT_DELIVERY_MODE;
-        this.jmsRedelivered = true;
-        this.jmsType = "test type";
-        this.jmsExpiration = 100000;
-        this.jmsPriority = 5;
-        this.jmsTimestamp = System.currentTimeMillis();
-        this.readOnlyMessage = false;
-
-        OpenWireJMSMessage msg1 = new OpenWireJMSMessage();
-        msg1.setJMSMessageID(this.jmsMessageID);
-        msg1.setJMSCorrelationID(this.jmsCorrelationID);
-        msg1.setJMSDestination(this.jmsDestination);
-        msg1.setJMSReplyTo(this.jmsReplyTo);
-        msg1.setJMSDeliveryMode(this.jmsDeliveryMode);
-        msg1.setJMSRedelivered(this.jmsRedelivered);
-        msg1.setJMSType(this.jmsType);
-        msg1.setJMSExpiration(this.jmsExpiration);
-        msg1.setJMSPriority(this.jmsPriority);
-        msg1.setJMSTimestamp(this.jmsTimestamp);
-        msg1.setReadOnlyProperties(true);
-
-        OpenWireJMSMessage msg2 = msg1.copy();
-
-        assertEquals(msg1.getJMSMessageID(), msg2.getJMSMessageID());
-        assertTrue(msg1.getJMSCorrelationID().equals(msg2.getJMSCorrelationID()));
-        assertTrue(msg1.getJMSDestination().equals(msg2.getJMSDestination()));
-        assertTrue(msg1.getJMSReplyTo().equals(msg2.getJMSReplyTo()));
-        assertTrue(msg1.getJMSDeliveryMode() == msg2.getJMSDeliveryMode());
-        assertTrue(msg1.getJMSRedelivered() == msg2.getJMSRedelivered());
-        assertTrue(msg1.getJMSType().equals(msg2.getJMSType()));
-        assertTrue(msg1.getJMSExpiration() == msg2.getJMSExpiration());
-        assertTrue(msg1.getJMSPriority() == msg2.getJMSPriority());
-        assertTrue(msg1.getJMSTimestamp() == msg2.getJMSTimestamp());
-
-        LOG.info("Message is: {}", msg1);
-    }
-
-    @Test
-    public void testGetAndSetJMSMessageID() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSMessageID(this.jmsMessageID);
-        assertEquals(msg.getJMSMessageID(), this.jmsMessageID);
-    }
-
-    @Test
-    public void testGetAndSetJMSTimestamp() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSTimestamp(this.jmsTimestamp);
-        assertTrue(msg.getJMSTimestamp() == this.jmsTimestamp);
-    }
-
-    @Test
-    public void testGetJMSCorrelationIDAsBytes() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSCorrelationID(this.jmsCorrelationID);
-        byte[] testbytes = msg.getJMSCorrelationIDAsBytes();
-        String str2 = new String(testbytes);
-        assertTrue(this.jmsCorrelationID.equals(str2));
-    }
-
-    @Test
-    public void testSetJMSCorrelationIDAsBytes() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        byte[] testbytes = this.jmsCorrelationID.getBytes();
-        msg.setJMSCorrelationIDAsBytes(testbytes);
-        testbytes = msg.getJMSCorrelationIDAsBytes();
-        String str2 = new String(testbytes);
-        assertTrue(this.jmsCorrelationID.equals(str2));
-    }
-
-    @Test
-    public void testGetAndSetJMSCorrelationID() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSCorrelationID(this.jmsCorrelationID);
-        assertTrue(msg.getJMSCorrelationID().equals(this.jmsCorrelationID));
-    }
-
-    @Test
-    public void testGetAndSetJMSReplyTo() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSReplyTo(this.jmsReplyTo);
-        assertTrue(msg.getJMSReplyTo().equals(this.jmsReplyTo));
-    }
-
-    @Test
-    public void testGetAndSetJMSDestination() throws Exception {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSDestination(this.jmsDestination);
-        assertTrue(msg.getJMSDestination().equals(this.jmsDestination));
-    }
-
-    @Test
-    public void testGetAndSetJMSDeliveryMode() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSDeliveryMode(this.jmsDeliveryMode);
-        assertTrue(msg.getJMSDeliveryMode() == this.jmsDeliveryMode);
-    }
-
-    @Test
-    public void testGetAndSetMSRedelivered() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSRedelivered(this.jmsRedelivered);
-        assertTrue(msg.getJMSRedelivered() == this.jmsRedelivered);
-    }
-
-    @Test
-    public void testGetAndSetJMSType() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSType(this.jmsType);
-        assertTrue(msg.getJMSType().equals(this.jmsType));
-    }
-
-    @Test
-    public void testGetAndSetJMSExpiration() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSExpiration(this.jmsExpiration);
-        assertTrue(msg.getJMSExpiration() == this.jmsExpiration);
-    }
-
-    @Test
-    public void testGetAndSetJMSPriority() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSPriority(this.jmsPriority);
-        assertTrue(msg.getJMSPriority() == this.jmsPriority);
-
-        msg.setJMSPriority(-90);
-        assertEquals(0, msg.getJMSPriority());
-
-        msg.setJMSPriority(90);
-        assertEquals(9, msg.getJMSPriority());
-    }
-
-    @Test
-    public void testClearProperties() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setStringProperty("test", "test");
-        msg.setJMSMessageID(this.jmsMessageID);
-        msg.getOpenWireMessage().setContent(new Buffer(new byte[] {1, 0, 0}));
-        msg.clearProperties();
-        assertNull(msg.getStringProperty("test"));
-        assertNotNull(msg.getJMSMessageID());
-        assertNotNull(msg.getOpenWireMessage().getContent());
-    }
-
-    @Test
-    public void testPropertyExists() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setStringProperty("test", "test");
-        assertTrue(msg.propertyExists("test"));
-
-        msg.setIntProperty("JMSXDeliveryCount", 1);
-        assertTrue(msg.propertyExists("JMSXDeliveryCount"));
-    }
-
-    @Test
-    public void testGetBooleanProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "booleanProperty";
-        msg.setBooleanProperty(name, true);
-        assertTrue(msg.getBooleanProperty(name));
-    }
-
-    @Test
-    public void testGetByteProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "byteProperty";
-        msg.setByteProperty(name, (byte) 1);
-        assertTrue(msg.getByteProperty(name) == 1);
-    }
-
-    @Test
-    public void testGetShortProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "shortProperty";
-        msg.setShortProperty(name, (short) 1);
-        assertTrue(msg.getShortProperty(name) == 1);
-    }
-
-    @Test
-    public void testGetIntProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "intProperty";
-        msg.setIntProperty(name, 1);
-        assertTrue(msg.getIntProperty(name) == 1);
-    }
-
-    @Test
-    public void testGetLongProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "longProperty";
-        msg.setLongProperty(name, 1);
-        assertTrue(msg.getLongProperty(name) == 1);
-    }
-
-    @Test
-    public void testGetFloatProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "floatProperty";
-        msg.setFloatProperty(name, 1.3f);
-        assertTrue(msg.getFloatProperty(name) == 1.3f);
-    }
-
-    @Test
-    public void testGetDoubleProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "doubleProperty";
-        msg.setDoubleProperty(name, 1.3d);
-        assertTrue(msg.getDoubleProperty(name) == 1.3);
-    }
-
-    @Test
-    public void testGetStringProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "stringProperty";
-        msg.setStringProperty(name, name);
-        assertTrue(msg.getStringProperty(name).equals(name));
-    }
-
-    @Test
-    public void testGetObjectProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "floatProperty";
-        msg.setFloatProperty(name, 1.3f);
-        assertTrue(msg.getObjectProperty(name) instanceof Float);
-        assertTrue(((Float) msg.getObjectProperty(name)).floatValue() == 1.3f);
-    }
-
-    @Test
-    public void testGetPropertyNames() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name1 = "floatProperty";
-        msg.setFloatProperty(name1, 1.3f);
-        String name2 = "JMSXDeliveryCount";
-        msg.setIntProperty(name2, 1);
-        String name3 = "JMSRedelivered";
-        msg.setBooleanProperty(name3, false);
-        boolean found1 = false;
-        boolean found2 = false;
-        boolean found3 = false;
-        for (Enumeration<?> iter = msg.getPropertyNames(); iter.hasMoreElements();) {
-            Object element = iter.nextElement();
-            found1 |= element.equals(name1);
-            found2 |= element.equals(name2);
-            found3 |= element.equals(name3);
-        }
-        assertTrue("prop name1 found", found1);
-        // spec compliance, only non JMS (and JMSX) props returned
-        assertFalse("prop name2 not found", found2);
-        assertFalse("prop name4 not found", found3);
-    }
-
-    @Test
-    public void testGetAllPropertyNames() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name1 = "floatProperty";
-        msg.setFloatProperty(name1, 1.3f);
-        String name2 = "JMSXDeliveryCount";
-        msg.setIntProperty(name2, 1);
-        String name3 = "JMSRedelivered";
-        msg.setBooleanProperty(name3, false);
-        boolean found1 = false;
-        boolean found2 = false;
-        boolean found3 = false;
-        for (Enumeration<?> iter = msg.getAllPropertyNames(); iter.hasMoreElements();) {
-            Object element = iter.nextElement();
-            found1 |= element.equals(name1);
-            found2 |= element.equals(name2);
-            found3 |= element.equals(name3);
-        }
-        assertTrue("prop name1 found", found1);
-        assertTrue("prop name2 found", found2);
-        assertTrue("prop name4 found", found3);
-    }
-
-    @Test
-    public void testSetObjectProperty() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String name = "property";
-
-        try {
-            msg.setObjectProperty(name, "string");
-            msg.setObjectProperty(name, Byte.valueOf("1"));
-            msg.setObjectProperty(name, Short.valueOf("1"));
-            msg.setObjectProperty(name, Integer.valueOf("1"));
-            msg.setObjectProperty(name, Long.valueOf("1"));
-            msg.setObjectProperty(name, Float.valueOf("1.1f"));
-            msg.setObjectProperty(name, Double.valueOf("1.1"));
-            msg.setObjectProperty(name, Boolean.TRUE);
-            msg.setObjectProperty(name, null);
-        } catch (MessageFormatException e) {
-            fail("should accept object primitives and String");
-        }
-        try {
-            msg.setObjectProperty(name, new byte[5]);
-            fail("should accept only object primitives and String");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.setObjectProperty(name, new Object());
-            fail("should accept only object primitives and String");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testConvertProperties() throws Exception {
-        org.apache.activemq.openwire.commands.Message msg = new org.apache.activemq.openwire.commands.Message() {
-            @Override
-            public org.apache.activemq.openwire.commands.Message copy() {
-                return null;
-            }
-
-            @Override
-            public void beforeMarshall(OpenWireFormat wireFormat) throws IOException {
-                super.beforeMarshall(wireFormat);
-            }
-
-            @Override
-            public byte getDataStructureType() {
-                return 0;
-            }
-
-            @Override
-            public Response visit(CommandVisitor visitor) throws Exception {
-                return null;
-            }
-
-            @Override
-            public void clearBody() throws JMSException {
-            }
-
-            @Override
-            public void storeContent() {
-            }
-
-            @Override
-            public void storeContentAndClear() {
-
-            }
-        };
-
-        msg.setProperty("stringProperty", "string");
-        msg.setProperty("byteProperty", Byte.valueOf("1"));
-        msg.setProperty("shortProperty", Short.valueOf("1"));
-        msg.setProperty("intProperty", Integer.valueOf("1"));
-        msg.setProperty("longProperty", Long.valueOf("1"));
-        msg.setProperty("floatProperty", Float.valueOf("1.1f"));
-        msg.setProperty("doubleProperty", Double.valueOf("1.1"));
-        msg.setProperty("booleanProperty", Boolean.TRUE);
-        msg.setProperty("nullProperty", null);
-
-        msg.beforeMarshall(new OpenWireFormat(OpenWireFormat.DEFAULT_WIRE_VERSION));
-
-        Map<String, Object> properties = msg.getProperties();
-        assertEquals(properties.get("stringProperty"), "string");
-        assertEquals(((Byte) properties.get("byteProperty")).byteValue(), 1);
-        assertEquals(((Short) properties.get("shortProperty")).shortValue(), 1);
-        assertEquals(((Integer) properties.get("intProperty")).intValue(), 1);
-        assertEquals(((Long) properties.get("longProperty")).longValue(), 1);
-        assertEquals(((Float) properties.get("floatProperty")).floatValue(), 1.1f, 0);
-        assertEquals(((Double) properties.get("doubleProperty")).doubleValue(), 1.1, 0);
-        assertEquals(((Boolean) properties.get("booleanProperty")).booleanValue(), true);
-        assertNull(properties.get("nullProperty"));
-    }
-
-    @Test
-    public void testSetNullProperty() throws JMSException {
-        Message msg = new OpenWireJMSMessage();
-        String name = "cheese";
-        msg.setStringProperty(name, "Cheddar");
-        assertEquals("Cheddar", msg.getStringProperty(name));
-
-        msg.setStringProperty(name, null);
-        assertEquals(null, msg.getStringProperty(name));
-    }
-
-    @Test
-    public void testSetNullPropertyName() throws JMSException {
-        Message msg = new OpenWireJMSMessage();
-
-        try {
-            msg.setStringProperty(null, "Cheese");
-            fail("Should have thrown exception");
-        } catch (IllegalArgumentException e) {
-            LOG.info("Worked, caught: " + e);
-        }
-    }
-
-    @Test
-    public void testSetEmptyPropertyName() throws JMSException {
-        Message msg = new OpenWireJMSMessage();
-
-        try {
-            msg.setStringProperty("", "Cheese");
-            fail("Should have thrown exception");
-        } catch (IllegalArgumentException e) {
-            LOG.info("Worked, caught: " + e);
-        }
-    }
-
-    @Test
-    public void testGetAndSetJMSXDeliveryCount() throws JMSException {
-        Message msg = new OpenWireJMSMessage();
-        msg.setIntProperty("JMSXDeliveryCount", 1);
-        int count = msg.getIntProperty("JMSXDeliveryCount");
-        assertTrue("expected delivery count = 1 - got: " + count, count == 1);
-    }
-
-    @Test
-    public void testClearBody() throws JMSException {
-        OpenWireJMSBytesMessage message = new OpenWireJMSBytesMessage();
-        message.clearBody();
-        assertFalse(message.isReadOnlyBody());
-        assertNull(message.getOpenWireMessage().getContent());
-    }
-
-    @Test
-    public void testBooleanPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setBooleanProperty(propertyName, true);
-
-        assertEquals(((Boolean) msg.getObjectProperty(propertyName)).booleanValue(), true);
-        assertTrue(msg.getBooleanProperty(propertyName));
-        assertEquals(msg.getStringProperty(propertyName), "true");
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getLongProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testBytePropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setByteProperty(propertyName, (byte) 1);
-
-        assertEquals(((Byte) msg.getObjectProperty(propertyName)).byteValue(), 1);
-        assertEquals(msg.getByteProperty(propertyName), 1);
-        assertEquals(msg.getShortProperty(propertyName), 1);
-        assertEquals(msg.getIntProperty(propertyName), 1);
-        assertEquals(msg.getLongProperty(propertyName), 1);
-        assertEquals(msg.getStringProperty(propertyName), "1");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testShortPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setShortProperty(propertyName, (short) 1);
-
-        assertEquals(((Short) msg.getObjectProperty(propertyName)).shortValue(), 1);
-        assertEquals(msg.getShortProperty(propertyName), 1);
-        assertEquals(msg.getIntProperty(propertyName), 1);
-        assertEquals(msg.getLongProperty(propertyName), 1);
-        assertEquals(msg.getStringProperty(propertyName), "1");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testIntPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setIntProperty(propertyName, 1);
-
-        assertEquals(((Integer) msg.getObjectProperty(propertyName)).intValue(), 1);
-        assertEquals(msg.getIntProperty(propertyName), 1);
-        assertEquals(msg.getLongProperty(propertyName), 1);
-        assertEquals(msg.getStringProperty(propertyName), "1");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testLongPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setLongProperty(propertyName, 1);
-
-        assertEquals(((Long) msg.getObjectProperty(propertyName)).longValue(), 1);
-        assertEquals(msg.getLongProperty(propertyName), 1);
-        assertEquals(msg.getStringProperty(propertyName), "1");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testFloatPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setFloatProperty(propertyName, (float) 1.5);
-        assertEquals(((Float) msg.getObjectProperty(propertyName)).floatValue(), 1.5, 0);
-        assertEquals(msg.getFloatProperty(propertyName), 1.5, 0);
-        assertEquals(msg.getDoubleProperty(propertyName), 1.5, 0);
-        assertEquals(msg.getStringProperty(propertyName), "1.5");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getLongProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testDoublePropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setDoubleProperty(propertyName, 1.5);
-        assertEquals(((Double) msg.getObjectProperty(propertyName)).doubleValue(), 1.5, 0);
-        assertEquals(msg.getDoubleProperty(propertyName), 1.5, 0);
-        assertEquals(msg.getStringProperty(propertyName), "1.5");
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getLongProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testStringPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        String stringValue = "true";
-        msg.setStringProperty(propertyName, stringValue);
-        assertEquals(msg.getStringProperty(propertyName), stringValue);
-        assertEquals(msg.getObjectProperty(propertyName), stringValue);
-        assertEquals(msg.getBooleanProperty(propertyName), true);
-
-        stringValue = "1";
-        msg.setStringProperty(propertyName, stringValue);
-        assertEquals(msg.getByteProperty(propertyName), 1);
-        assertEquals(msg.getShortProperty(propertyName), 1);
-        assertEquals(msg.getIntProperty(propertyName), 1);
-        assertEquals(msg.getLongProperty(propertyName), 1);
-
-        stringValue = "1.5";
-        msg.setStringProperty(propertyName, stringValue);
-        assertEquals(msg.getFloatProperty(propertyName), 1.5, 0);
-        assertEquals(msg.getDoubleProperty(propertyName), 1.5, 0);
-
-        stringValue = "bad";
-        msg.setStringProperty(propertyName, stringValue);
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        try {
-            msg.getLongProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (NumberFormatException e) {
-        }
-        assertFalse(msg.getBooleanProperty(propertyName));
-    }
-
-    @Test
-    public void testObjectPropertyConversion() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        Object obj = new Object();
-        try {
-            // Bypass normal checks.
-            msg.getOpenWireMessage().setProperty(propertyName, obj, false);
-        } catch (Exception e) {
-        }
-        try {
-            msg.getStringProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getBooleanProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getByteProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getShortProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getIntProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getLongProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getFloatProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        try {
-            msg.getDoubleProperty(propertyName);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testReadOnlyProperties() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        String propertyName = "property";
-        msg.setReadOnlyProperties(true);
-
-        try {
-            msg.setObjectProperty(propertyName, new Object());
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setStringProperty(propertyName, "test");
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setBooleanProperty(propertyName, true);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setByteProperty(propertyName, (byte) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setShortProperty(propertyName, (short) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setIntProperty(propertyName, 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setLongProperty(propertyName, 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setFloatProperty(propertyName, (float) 1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-        try {
-            msg.setDoubleProperty(propertyName, 1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException e) {
-        }
-    }
-
-    @Test
-    public void testIsExpired() throws JMSException {
-        OpenWireJMSMessage msg = new OpenWireJMSMessage();
-        msg.setJMSExpiration(System.currentTimeMillis() - 1);
-        assertTrue(msg.isExpired());
-        msg.setJMSExpiration(System.currentTimeMillis() + 10000);
-        assertFalse(msg.isExpired());
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessageTest.java
deleted file mode 100644
index b40fe1e..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSObjectMessageTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-
-import javax.jms.JMSException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.jms.OpenWireJMSObjectMessage;
-import org.junit.Test;
-
-/**
- *
- */
-public class OpenWireJMSObjectMessageTest {
-
-    @Test
-    public void testBytes() throws JMSException, IOException {
-        OpenWireJMSObjectMessage msg = new OpenWireJMSObjectMessage();
-        String str = "testText";
-        msg.setObject(str);
-
-        msg = msg.copy();
-        assertEquals(msg.getObject(), str);
-    }
-
-    @Test
-    public void testSetObject() throws JMSException {
-        OpenWireJMSObjectMessage msg = new OpenWireJMSObjectMessage();
-        String str = "testText";
-        msg.setObject(str);
-        assertTrue(msg.getObject() == str);
-    }
-
-    @Test
-    public void testClearBody() throws JMSException {
-        OpenWireJMSObjectMessage objectMessage = new OpenWireJMSObjectMessage();
-        try {
-            objectMessage.setObject("String");
-            objectMessage.clearBody();
-            assertFalse(objectMessage.isReadOnlyBody());
-            assertNull(objectMessage.getObject());
-            objectMessage.setObject("String");
-            objectMessage.getObject();
-        } catch (MessageNotWriteableException mnwe) {
-            fail("should be writeable");
-        }
-    }
-
-    @Test
-    public void testReadOnlyBody() throws JMSException {
-        OpenWireJMSObjectMessage msg = new OpenWireJMSObjectMessage();
-        msg.setObject("test");
-        msg.setReadOnlyBody(true);
-        try {
-            msg.getObject();
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        }
-        try {
-            msg.setObject("test");
-            fail("should throw exception");
-        } catch (MessageNotWriteableException e) {
-        }
-    }
-
-    @Test
-    public void testWriteOnlyBody() throws JMSException {
-        // should always be readable
-        OpenWireJMSObjectMessage msg = new OpenWireJMSObjectMessage();
-        msg.setReadOnlyBody(false);
-        try {
-            msg.setObject("test");
-            msg.getObject();
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        }
-        msg.setReadOnlyBody(true);
-        try {
-            msg.getObject();
-            msg.setObject("test");
-            fail("should throw exception");
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessageTest.java
deleted file mode 100644
index fe4cc9d..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSStreamMessageTest.java
+++ /dev/null
@@ -1,938 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.jms.JMSException;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.jms.OpenWireJMSStreamMessage;
-import org.junit.Test;
-
-/**
- * Test for the OpenWireJMSStreamMessage facade class.
- */
-public class OpenWireJMSStreamMessageTest {
-
-    @Test
-    public void testReadBoolean() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        msg.writeBoolean(true);
-        msg.reset();
-        assertTrue(msg.readBoolean());
-        msg.reset();
-        assertTrue(msg.readString().equals("true"));
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testreadByte() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        byte test = (byte) 4;
-        msg.writeByte(test);
-        msg.reset();
-        assertTrue(msg.readByte() == test);
-        msg.reset();
-        assertTrue(msg.readShort() == test);
-        msg.reset();
-        assertTrue(msg.readInt() == test);
-        msg.reset();
-        assertTrue(msg.readLong() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Byte(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadShort() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        short test = (short) 4;
-        msg.writeShort(test);
-        msg.reset();
-        assertTrue(msg.readShort() == test);
-        msg.reset();
-        assertTrue(msg.readInt() == test);
-        msg.reset();
-        assertTrue(msg.readLong() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Short(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadChar() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        char test = 'z';
-        msg.writeChar(test);
-        msg.reset();
-        assertTrue(msg.readChar() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Character(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadInt() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        int test = 4;
-        msg.writeInt(test);
-        msg.reset();
-        assertTrue(msg.readInt() == test);
-        msg.reset();
-        assertTrue(msg.readLong() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Integer(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadLong() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        long test = 4L;
-        msg.writeLong(test);
-        msg.reset();
-        assertTrue(msg.readLong() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(Long.valueOf(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg = new OpenWireJMSStreamMessage();
-        msg.writeObject(new Long("1"));
-        // reset so it's readable now
-        msg.reset();
-        assertEquals(new Long("1"), msg.readObject());
-    }
-
-    @Test
-    public void testReadFloat() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        float test = 4.4f;
-        msg.writeFloat(test);
-        msg.reset();
-        assertTrue(msg.readFloat() == test);
-        msg.reset();
-        assertTrue(msg.readDouble() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Float(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadDouble() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        double test = 4.4d;
-        msg.writeDouble(test);
-        msg.reset();
-        assertTrue(msg.readDouble() == test);
-        msg.reset();
-        assertTrue(msg.readString().equals(new Double(test).toString()));
-        msg.reset();
-        try {
-            msg.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-        msg.reset();
-        try {
-            msg.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException mfe) {
-        }
-    }
-
-    @Test
-    public void testReadString() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        byte testByte = (byte) 2;
-        msg.writeString(new Byte(testByte).toString());
-        msg.reset();
-        assertTrue(msg.readByte() == testByte);
-        msg.clearBody();
-        short testShort = 3;
-        msg.writeString(new Short(testShort).toString());
-        msg.reset();
-        assertTrue(msg.readShort() == testShort);
-        msg.clearBody();
-        int testInt = 4;
-        msg.writeString(new Integer(testInt).toString());
-        msg.reset();
-        assertTrue(msg.readInt() == testInt);
-        msg.clearBody();
-        long testLong = 6L;
-        msg.writeString(new Long(testLong).toString());
-        msg.reset();
-        assertTrue(msg.readLong() == testLong);
-        msg.clearBody();
-        float testFloat = 6.6f;
-        msg.writeString(new Float(testFloat).toString());
-        msg.reset();
-        assertTrue(msg.readFloat() == testFloat);
-        msg.clearBody();
-        double testDouble = 7.7d;
-        msg.writeString(new Double(testDouble).toString());
-        msg.reset();
-        assertTrue(msg.readDouble() == testDouble);
-        msg.clearBody();
-        msg.writeString("true");
-        msg.reset();
-        assertTrue(msg.readBoolean());
-        msg.clearBody();
-        msg.writeString("a");
-        msg.reset();
-        try {
-            msg.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-        msg.clearBody();
-        msg.writeString("777");
-        msg.reset();
-        try {
-            msg.readBytes(new byte[3]);
-            fail("Should have thrown exception");
-        } catch (MessageFormatException e) {
-        }
-    }
-
-    @Test
-    public void testReadBigString() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        try {
-            // Test with a 1Meg String
-            StringBuffer bigSB = new StringBuffer(1024 * 1024);
-            for (int i = 0; i < 1024 * 1024; i++) {
-                bigSB.append('a' + i % 26);
-            }
-            String bigString = bigSB.toString();
-
-            msg.writeString(bigString);
-            msg.reset();
-            assertEquals(bigString, msg.readString());
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadBytes() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        try {
-            byte[] test = new byte[50];
-            for (int i = 0; i < test.length; i++) {
-                test[i] = (byte) i;
-            }
-            msg.writeBytes(test);
-            msg.reset();
-            byte[] valid = new byte[test.length];
-            msg.readBytes(valid);
-            for (int i = 0; i < valid.length; i++) {
-                assertTrue(valid[i] == test[i]);
-            }
-            msg.reset();
-            try {
-                msg.readByte();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readShort();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readInt();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readLong();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readFloat();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readChar();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-            msg.reset();
-            try {
-                msg.readString();
-                fail("Should have thrown exception");
-            } catch (MessageFormatException mfe) {
-            }
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testReadObject() throws Exception {
-        OpenWireJMSStreamMessage msg = new OpenWireJMSStreamMessage();
-        try {
-            byte testByte = (byte) 2;
-            msg.writeByte(testByte);
-            msg.reset();
-            assertTrue(((Byte) msg.readObject()).byteValue() == testByte);
-            msg.clearBody();
-
-            short testShort = 3;
-            msg.writeShort(testShort);
-            msg.reset();
-            assertTrue(((Short) msg.readObject()).shortValue() == testShort);
-            msg.clearBody();
-
-            int testInt = 4;
-            msg.writeInt(testInt);
-            msg.reset();
-            assertTrue(((Integer) msg.readObject()).intValue() == testInt);
-            msg.clearBody();
-
-            long testLong = 6L;
-            msg.writeLong(testLong);
-            msg.reset();
-            assertTrue(((Long) msg.readObject()).longValue() == testLong);
-            msg.clearBody();
-
-            float testFloat = 6.6f;
-            msg.writeFloat(testFloat);
-            msg.reset();
-            assertTrue(((Float) msg.readObject()).floatValue() == testFloat);
-            msg.clearBody();
-
-            double testDouble = 7.7d;
-            msg.writeDouble(testDouble);
-            msg.reset();
-            assertTrue(((Double) msg.readObject()).doubleValue() == testDouble);
-            msg.clearBody();
-
-            char testChar = 'z';
-            msg.writeChar(testChar);
-            msg.reset();
-            assertTrue(((Character) msg.readObject()).charValue() == testChar);
-            msg.clearBody();
-
-            byte[] data = new byte[50];
-            for (int i = 0; i < data.length; i++) {
-                data[i] = (byte) i;
-            }
-            msg.writeBytes(data);
-            msg.reset();
-            byte[] valid = (byte[]) msg.readObject();
-            assertTrue(valid.length == data.length);
-            for (int i = 0; i < valid.length; i++) {
-                assertTrue(valid[i] == data[i]);
-            }
-            msg.clearBody();
-            msg.writeBoolean(true);
-            msg.reset();
-            assertTrue(((Boolean) msg.readObject()).booleanValue());
-        } catch (JMSException jmsEx) {
-            jmsEx.printStackTrace();
-            assertTrue(false);
-        }
-    }
-
-    @Test
-    public void testClearBody() throws JMSException {
-        OpenWireJMSStreamMessage streamMessage = new OpenWireJMSStreamMessage();
-        try {
-            streamMessage.writeObject(new Long(2));
-            streamMessage.clearBody();
-            assertFalse(streamMessage.isReadOnlyBody());
-            streamMessage.writeObject(new Long(2));
-            streamMessage.readObject();
-            fail("should throw exception");
-        } catch (MessageNotReadableException mnwe) {
-        } catch (MessageNotWriteableException mnwe) {
-            fail("should be writeable");
-        }
-    }
-
-    @Test
-    public void testReset() throws JMSException {
-        OpenWireJMSStreamMessage streamMessage = new OpenWireJMSStreamMessage();
-        try {
-            streamMessage.writeDouble(24.5);
-            streamMessage.writeLong(311);
-        } catch (MessageNotWriteableException mnwe) {
-            fail("should be writeable");
-        }
-        streamMessage.reset();
-        try {
-            assertTrue(streamMessage.isReadOnlyBody());
-            assertEquals(streamMessage.readDouble(), 24.5, 0);
-            assertEquals(streamMessage.readLong(), 311);
-        } catch (MessageNotReadableException mnre) {
-            fail("should be readable");
-        }
-        try {
-            streamMessage.writeInt(33);
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testReadOnlyBody() throws JMSException {
-        OpenWireJMSStreamMessage message = new OpenWireJMSStreamMessage();
-        try {
-            message.writeBoolean(true);
-            message.writeByte((byte) 1);
-            message.writeBytes(new byte[1]);
-            message.writeBytes(new byte[3], 0, 2);
-            message.writeChar('a');
-            message.writeDouble(1.5);
-            message.writeFloat((float) 1.5);
-            message.writeInt(1);
-            message.writeLong(1);
-            message.writeObject("stringobj");
-            message.writeShort((short) 1);
-            message.writeString("string");
-        } catch (MessageNotWriteableException mnwe) {
-            fail("Should be writeable");
-        }
-        message.reset();
-        try {
-            message.readBoolean();
-            message.readByte();
-            assertEquals(1, message.readBytes(new byte[10]));
-            assertEquals(-1, message.readBytes(new byte[10]));
-            assertEquals(2, message.readBytes(new byte[10]));
-            assertEquals(-1, message.readBytes(new byte[10]));
-            message.readChar();
-            message.readDouble();
-            message.readFloat();
-            message.readInt();
-            message.readLong();
-            message.readString();
-            message.readShort();
-            message.readString();
-        } catch (MessageNotReadableException mnwe) {
-            fail("Should be readable");
-        }
-        try {
-            message.writeBoolean(true);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeByte((byte) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeBytes(new byte[3], 0, 2);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeChar('a');
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeDouble(1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeFloat((float) 1.5);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeInt(1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeLong(1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeObject("stringobj");
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeShort((short) 1);
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-        try {
-            message.writeString("string");
-            fail("Should have thrown exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testWriteOnlyBody() throws JMSException {
-        OpenWireJMSStreamMessage message = new OpenWireJMSStreamMessage();
-        message.clearBody();
-        try {
-            message.writeBoolean(true);
-            message.writeByte((byte) 1);
-            message.writeBytes(new byte[1]);
-            message.writeBytes(new byte[3], 0, 2);
-            message.writeChar('a');
-            message.writeDouble(1.5);
-            message.writeFloat((float) 1.5);
-            message.writeInt(1);
-            message.writeLong(1);
-            message.writeObject("stringobj");
-            message.writeShort((short) 1);
-            message.writeString("string");
-        } catch (MessageNotWriteableException mnwe) {
-            fail("Should be writeable");
-        }
-        try {
-            message.readBoolean();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException mnwe) {
-        }
-        try {
-            message.readByte();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readBytes(new byte[1]);
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readBytes(new byte[2]);
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readChar();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readDouble();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readFloat();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readInt();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readLong();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readString();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readShort();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-        try {
-            message.readString();
-            fail("Should have thrown exception");
-        } catch (MessageNotReadableException e) {
-        }
-    }
-
-    @Test
-    public void testWriteObject() throws Exception {
-        try {
-            OpenWireJMSStreamMessage message = new OpenWireJMSStreamMessage();
-            message.clearBody();
-            message.writeObject("test");
-            message.writeObject(new Character('a'));
-            message.writeObject(new Boolean(false));
-            message.writeObject(new Byte((byte) 2));
-            message.writeObject(new Short((short) 2));
-            message.writeObject(new Integer(2));
-            message.writeObject(new Long(2l));
-            message.writeObject(new Float(2.0f));
-            message.writeObject(new Double(2.0d));
-        } catch (Exception e) {
-            fail(e.getMessage());
-        }
-        try {
-            OpenWireJMSStreamMessage message = new OpenWireJMSStreamMessage();
-            message.clearBody();
-            message.writeObject(new Object());
-            fail("should throw an exception");
-        } catch (MessageFormatException e) {
-        } catch (Exception e) {
-            fail(e.getMessage());
-        }
-    }
-}
diff --git a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessageTest.java b/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessageTest.java
deleted file mode 100644
index c299f8c..0000000
--- a/openwire-jms/src/test/java/org/apache/activemq/openwire/jms/OpenWireJMSTextMessageTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.activemq.openwire.jms;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.DataOutputStream;
-
-import javax.jms.JMSException;
-import javax.jms.MessageNotReadableException;
-import javax.jms.MessageNotWriteableException;
-
-import org.apache.activemq.openwire.commands.OpenWireMessage;
-import org.apache.activemq.openwire.jms.OpenWireJMSTextMessage;
-import org.apache.activemq.openwire.utils.OpenWireMarshallingSupport;
-import org.fusesource.hawtbuf.ByteArrayOutputStream;
-import org.junit.Test;
-
-/**
- *
- */
-public class OpenWireJMSTextMessageTest {
-
-    @Test
-    public void testReadOnlyBody() throws JMSException {
-        OpenWireJMSTextMessage textMessage = new OpenWireJMSTextMessage();
-        textMessage.setText("test");
-        textMessage.setReadOnlyBody(true);
-        try {
-            textMessage.getText();
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        }
-        try {
-            textMessage.setText("test");
-            fail("should throw exception");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testWriteOnlyBody() throws JMSException { // should always be readable
-        OpenWireJMSTextMessage textMessage = new OpenWireJMSTextMessage();
-        textMessage.setReadOnlyBody(false);
-        try {
-            textMessage.setText("test");
-            textMessage.getText();
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        }
-        textMessage.setReadOnlyBody(true);
-        try {
-            textMessage.getText();
-            textMessage.setText("test");
-            fail("should throw exception");
-        } catch (MessageNotReadableException e) {
-            fail("should be readable");
-        } catch (MessageNotWriteableException mnwe) {
-        }
-    }
-
-    @Test
-    public void testShortText() throws Exception {
-        String shortText = "Content";
-        OpenWireJMSTextMessage shortMessage = new OpenWireJMSTextMessage();
-        setContent(shortMessage.getOpenWireMessage(), shortText);
-        assertTrue(shortMessage.getText().equals(shortText));
-
-        String longText = "Very very very very veeeeeeery loooooooooooooooooooooooooooooooooong text";
-        OpenWireJMSTextMessage longMessage = new OpenWireJMSTextMessage();
-        setContent(longMessage.getOpenWireMessage(), longText);
-        assertTrue(longMessage.getText().equals(longText));
-    }
-
-    protected void setContent(OpenWireMessage message, String text) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        DataOutputStream dataOut = new DataOutputStream(baos);
-        OpenWireMarshallingSupport.writeUTF8(dataOut, text);
-        dataOut.close();
-        message.setContent(baos.toBuffer());
-    }
-}
diff --git a/openwire-jms/src/test/resources/log4j.properties b/openwire-jms/src/test/resources/log4j.properties
deleted file mode 100644
index 0588275..0000000
--- a/openwire-jms/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,41 +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.
-## ---------------------------------------------------------------------------
-
-#
-# The logging properties used during tests..
-#
-log4j.rootLogger=INFO, out, stdout
-
-log4j.logger.org.apache.activemq.openwire=DEBUG
-
-# Tune the ActiveMQ and it's OpenWire transport as needed for debugging.
-log4j.logger.org.apache.activemq=INFO
-log4j.logger.org.apache.activemq.broker=DEBUG
-log4j.logger.org.apache.activemq.transport.openwire=TRACE
-log4j.logger.org.apache.activemq.transport.openwire.FRAMES=DEBUG
-
-# CONSOLE appender not used by default
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
-
-# File appender
-log4j.appender.out=org.apache.log4j.FileAppender
-log4j.appender.out.layout=org.apache.log4j.PatternLayout
-log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] - %-5p %-30.30c{1} - %m%n
-log4j.appender.out.file=target/activemq-test.log
-log4j.appender.out.append=true
diff --git a/pom.xml b/pom.xml
index 3c2d61e..8171a6e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,7 +108,6 @@
     <module>openwire-core</module>
     <module>openwire-legacy</module>
     <module>openwire-interop-tests</module>
-    <module>openwire-jms</module>
     <module>openwire-website</module>
   </modules>
 
