Forked the coded input/output streams from the google proto buff project so that we don't need them as a dependency and also because we want to do some optimizations to them.

git-svn-id: https://svn.apache.org/repos/asf/activemq/sandbox/activemq-protobuf@713432 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java b/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
index c1d456a..8cad790 100644
--- a/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
+++ b/activemq-protobuf-test/src/test/java/com/google/protobuf/TestUtil.java
@@ -22,20 +22,21 @@
 
 package com.google.protobuf;
 
-import protobuf_unittest.UnittestProto;
-import protobuf_unittest.UnittestProto.TestAllTypes;
-import protobuf_unittest.UnittestProto.TestAllExtensions;
-import protobuf_unittest.UnittestProto.ForeignMessage;
-import protobuf_unittest.UnittestProto.ForeignEnum;
-import com.google.protobuf.test.UnittestImport.ImportMessage;
-import com.google.protobuf.test.UnittestImport.ImportEnum;
-
-import junit.framework.Assert;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
+import junit.framework.Assert;
+
+import org.apache.activemq.protobuf.ByteString;
+
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+
 /**
  * Contains methods for setting all fields of {@code TestAllTypes} to
  * some vaules as well as checking that all the fields are set to those values.
diff --git a/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java b/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
index d96dc9e..60513fd 100644
--- a/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/activemq-protobuf-test/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -17,6 +17,10 @@
 package com.google.protobuf;
 
 import junit.framework.TestCase;
+
+import org.apache.activemq.protobuf.ByteString;
+import org.apache.activemq.protobuf.CodedInputStream;
+
 import protobuf_unittest.UnittestProto.TestAllTypes;
 
 /**
diff --git a/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java b/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
index 5340848..d5f9fc8 100644
--- a/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
+++ b/activemq-protobuf-test/src/test/java/org/apache/activemq/protobuf/DeferredUnmarshalTest.java
@@ -16,13 +16,11 @@
  */
 package org.apache.activemq.protobuf;
 
-import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
-import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-
 import junit.framework.TestCase;
 
+import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
+import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
+
 public class DeferredUnmarshalTest extends TestCase {
 	
 	public void testDeferredDecoding() throws InvalidProtocolBufferException {
diff --git a/activemq-protobuf/pom.xml b/activemq-protobuf/pom.xml
index d9d73fa..23781db 100644
--- a/activemq-protobuf/pom.xml
+++ b/activemq-protobuf/pom.xml
@@ -37,12 +37,6 @@
 
   <dependencies>
     <dependency>
-      <groupId>com.google.protobuf</groupId>
-      <artifactId>protobuf-java</artifactId>
-      <version>2.0.1</version>
-    </dependency>
-    
-    <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
       <version>2.0</version>
@@ -63,14 +57,6 @@
     </dependency>
   </dependencies>
   
-  <repositories>
-    <repository>
-      <id>google</id>
-      <name>Google Maven Repo</name>
-      <url>http://google-maven-repository.googlecode.com/svn/repository</url>
-    </repository>
-  </repositories>
-
   <build>
     <plugins>
       <plugin>
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
index 2e2753c..270af4c 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/BaseMessage.java
@@ -16,10 +16,10 @@
  */
 package org.apache.activemq.protobuf;
 
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_END_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_LENGTH_DELIMITED;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_START_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.makeTag;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_END_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_START_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.makeTag;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -28,11 +28,6 @@
 import java.util.Collection;
 import java.util.List;
 
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
 abstract public class BaseMessage<T> implements Message<T> {
 
 	protected int memoizedSerializedSize = -1;
@@ -84,7 +79,7 @@
     }
     
 	
-     public void writeUnframed(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
+     public void writeUnframed(CodedOutputStream output) throws java.io.IOException {
 //        if (encodedForm == null) {
 //           encodedForm = new byte[serializedSizeUnframed()];
 //           com.google.protobuf.CodedOutputStream original = output;
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java
new file mode 100644
index 0000000..e77b219
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/ByteString.java
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format

+// Copyright 2008 Google Inc.

+// http://code.google.com/p/protobuf/

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//      http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.activemq.protobuf;

+

+import java.io.InputStream;

+import java.io.ByteArrayInputStream;

+import java.io.ByteArrayOutputStream;

+import java.io.FilterOutputStream;

+import java.io.UnsupportedEncodingException;

+

+/**

+ * Immutable array of bytes.

+ *

+ * @author crazybob@google.com Bob Lee

+ * @author kenton@google.com Kenton Varda

+ */

+public final class ByteString {

+  private final byte[] bytes;

+

+  private ByteString(byte[] bytes) {

+    this.bytes = bytes;

+  }

+

+  /**

+   * Gets the byte at the given index.

+   *

+   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size

+   */

+  public byte byteAt(int index) {

+    return bytes[index];

+  }

+

+  /**

+   * Gets the number of bytes.

+   */

+  public int size() {

+    return this.bytes.length;

+  }

+

+  /**

+   * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.

+   */

+  public boolean isEmpty() {

+    return this.bytes.length == 0;

+  }

+

+  // =================================================================

+  // byte[] -> ByteString

+

+  /**

+   * Empty ByteString.

+   */

+  public static final ByteString EMPTY = new ByteString(new byte[0]);

+

+  /**

+   * Copies the given bytes into a {@code ByteString}.

+   */

+  public static ByteString copyFrom(byte[] bytes, int offset, int size) {

+    byte[] copy = new byte[size];

+    System.arraycopy(bytes, offset, copy, 0, size);

+    return new ByteString(copy);

+  }

+

+  /**

+   * Copies the given bytes into a {@code ByteString}.

+   */

+  public static ByteString copyFrom(byte[] bytes) {

+    return copyFrom(bytes, 0, bytes.length);

+  }

+

+  /**

+   * Encodes {@code text} into a sequence of bytes using the named charset

+   * and returns the result as a {@code ByteString}.

+   */

+  public static ByteString copyFrom(String text, String charsetName)

+      throws UnsupportedEncodingException {

+    return new ByteString(text.getBytes(charsetName));

+  }

+

+  /**

+   * Encodes {@code text} into a sequence of UTF-8 bytes and returns the

+   * result as a {@code ByteString}.

+   */

+  public static ByteString copyFromUtf8(String text) {

+    try {

+      return new ByteString(text.getBytes("UTF-8"));

+    } catch (UnsupportedEncodingException e) {

+      throw new RuntimeException("UTF-8 not supported?", e);

+    }

+  }

+

+  // =================================================================

+  // ByteString -> byte[]

+

+  /**

+   * Copies bytes into a buffer at the given offset.

+   *

+   * @param target buffer to copy into

+   * @param offset in the target buffer

+   */

+  public void copyTo(byte[] target, int offset) {

+    System.arraycopy(bytes, 0, target, offset, bytes.length);

+  }

+

+  /**

+   * Copies bytes into a buffer.

+   *

+   * @param target buffer to copy into

+   * @param sourceOffset offset within these bytes

+   * @param targetOffset offset within the target buffer

+   * @param size number of bytes to copy

+   */

+  public void copyTo(byte[] target, int sourceOffset, int targetOffset,

+      int size) {

+    System.arraycopy(bytes, sourceOffset, target, targetOffset, size);

+  }

+

+  /**

+   * Copies bytes to a {@code byte[]}.

+   */

+  public byte[] toByteArray() {

+    int size = this.bytes.length;

+    byte[] copy = new byte[size];

+    System.arraycopy(this.bytes, 0, copy, 0, size);

+    return copy;

+  }

+

+  /**

+   * Constructs a new {@code String} by decoding the bytes using the

+   * specified charset.

+   */

+  public String toString(String charsetName)

+      throws UnsupportedEncodingException {

+    return new String(this.bytes, charsetName);

+  }

+

+  /**

+   * Constructs a new {@code String} by decoding the bytes as UTF-8.

+   */

+  public String toStringUtf8() {

+    try {

+      return new String(this.bytes, "UTF-8");

+    } catch (UnsupportedEncodingException e) {

+      throw new RuntimeException("UTF-8 not supported?", e);

+    }

+  }

+

+  // =================================================================

+  // equals() and hashCode()

+

+  @Override

+  public boolean equals(Object o) {

+    if (o == this) {

+      return true;

+    }

+

+    if (!(o instanceof ByteString)) {

+      return false;

+    }

+

+    ByteString other = (ByteString) o;

+    int size = this.bytes.length;

+    if (size != other.bytes.length) {

+      return false;

+    }

+

+    byte[] bytes = this.bytes;

+    byte[] otherBytes = other.bytes;

+    for (int i = 0; i < size; i++) {

+      if (bytes[i] != otherBytes[i]) {

+        return false;

+      }

+    }

+

+    return true;

+  }

+

+  volatile int hash = 0;

+

+  @Override

+  public int hashCode() {

+    int h = this.hash;

+

+    if (h == 0) {

+      byte[] bytes = this.bytes;

+      int size = this.bytes.length;

+

+      h = size;

+      for (int i = 0; i < size; i++) {

+        h = h * 31 + bytes[i];

+      }

+      if (h == 0) {

+        h = 1;

+      }

+

+      this.hash = h;

+    }

+

+    return h;

+  }

+

+  // =================================================================

+  // Input stream

+

+  /**

+   * Creates an {@code InputStream} which can be used to read the bytes.

+   */

+  public InputStream newInput() {

+    return new ByteArrayInputStream(bytes);

+  }

+

+  /**

+   * Creates a {@link CodedInputStream} which can be used to read the bytes.

+   * Using this is more efficient than creating a {@link CodedInputStream}

+   * wrapping the result of {@link #newInput()}.

+   */

+  public CodedInputStream newCodedInput() {

+    // We trust CodedInputStream not to modify the bytes, or to give anyone

+    // else access to them.

+    return CodedInputStream.newInstance(bytes);

+  }

+

+  // =================================================================

+  // Output stream

+

+  /**

+   * Creates a new {@link Output} with the given initial capacity.

+   */

+  public static Output newOutput(int initialCapacity) {

+    return new Output(new ByteArrayOutputStream(initialCapacity));

+  }

+

+  /**

+   * Creates a new {@link Output}.

+   */

+  public static Output newOutput() {

+    return newOutput(32);

+  }

+

+  /**

+   * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to

+   * create the {@code ByteString} instance.

+   */

+  public static final class Output extends FilterOutputStream {

+    private final ByteArrayOutputStream bout;

+

+    /**

+     * Constructs a new output with the given initial capacity.

+     */

+    private Output(ByteArrayOutputStream bout) {

+      super(bout);

+      this.bout = bout;

+    }

+

+    /**

+     * Creates a {@code ByteString} instance from this {@code Output}.

+     */

+    public ByteString toByteString() {

+      byte[] byteArray = bout.toByteArray();

+      return new ByteString(byteArray);

+    }

+  }

+

+  /**

+   * Constructs a new ByteString builder, which allows you to efficiently

+   * construct a {@code ByteString} by writing to a {@link CodedOutputSteam}.

+   * Using this is much more efficient than calling {@code newOutput()} and

+   * wrapping that in a {@code CodedOutputStream}.

+   *

+   * <p>This is package-private because it's a somewhat confusing interface.

+   * Users can call {@link Message#toByteString()} instead of calling this

+   * directly.

+   *

+   * @param size The target byte size of the {@code ByteString}.  You must

+   *             write exactly this many bytes before building the result.

+   */

+  static CodedBuilder newCodedBuilder(int size) {

+    return new CodedBuilder(size);

+  }

+

+  /** See {@link ByteString#newCodedBuilder(int)}. */

+  static final class CodedBuilder {

+    private final CodedOutputStream output;

+    private final byte[] buffer;

+

+    private CodedBuilder(int size) {

+      buffer = new byte[size];

+      output = CodedOutputStream.newInstance(buffer);

+    }

+

+    public ByteString build() {

+      output.checkNoSpaceLeft();

+

+      // We can be confident that the CodedOutputStream will not modify the

+      // underlying bytes anymore because it already wrote all of them.  So,

+      // no need to make a copy.

+      return new ByteString(buffer);

+    }

+

+    public CodedOutputStream getCodedOutput() {

+      return output;

+    }

+  }

+}

diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
new file mode 100644
index 0000000..2ebb710
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedInputStream.java
@@ -0,0 +1,676 @@
+// Protocol Buffers - Google's data interchange format

+// Copyright 2008 Google Inc.

+// http://code.google.com/p/protobuf/

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//      http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.activemq.protobuf;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * Reads and decodes protocol message fields.

+ * 

+ * This class contains two kinds of methods: methods that read specific protocol

+ * message constructs and field types (e.g. {@link #readTag()} and

+ * {@link #readInt32()}) and methods that read low-level values (e.g.

+ * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading

+ * encoded protocol messages, you should use the former methods, but if you are

+ * reading some other format of your own design, use the latter.

+ * 

+ * @author kenton@google.com Kenton Varda

+ */

+public final class CodedInputStream {

+    

+    /**

+     * Create a new CodedInputStream wrapping the given InputStream.

+     */

+    public static CodedInputStream newInstance(InputStream input) {

+        return new CodedInputStream(input);

+    }

+

+    /**

+     * Create a new CodedInputStream wrapping the given byte array.

+     */

+    public static CodedInputStream newInstance(byte[] buf) {

+        return new CodedInputStream(buf);

+    }

+

+    // -----------------------------------------------------------------

+

+    /**

+     * Attempt to read a field tag, returning zero if we have reached EOF.

+     * Protocol message parsers use this to read tags, since a protocol message

+     * may legally end wherever a tag occurs, and zero is not a valid tag

+     * number.

+     */

+    public int readTag() throws IOException {

+        if (bufferPos == bufferSize && !refillBuffer(false)) {

+            lastTag = 0;

+            return 0;

+        }

+

+        lastTag = readRawVarint32();

+        if (lastTag == 0) {

+            // If we actually read zero, that's not a valid tag.

+            throw InvalidProtocolBufferException.invalidTag();

+        }

+        return lastTag;

+    }

+

+    /**

+     * Verifies that the last call to readTag() returned the given tag value.

+     * This is used to verify that a nested group ended with the correct end

+     * tag.

+     * 

+     * @throws InvalidProtocolBufferException

+     *             {@code value} does not match the last tag.

+     */

+    public void checkLastTagWas(int value) throws InvalidProtocolBufferException {

+        if (lastTag != value) {

+            throw InvalidProtocolBufferException.invalidEndTag();

+        }

+    }

+

+    /**

+     * Reads and discards a single field, given its tag value.

+     * 

+     * @return {@code false} if the tag is an endgroup tag, in which case

+     *         nothing is skipped. Otherwise, returns {@code true}.

+     */

+    public boolean skipField(int tag) throws IOException {

+        switch (WireFormat.getTagWireType(tag)) {

+        case WireFormat.WIRETYPE_VARINT:

+            readInt32();

+            return true;

+        case WireFormat.WIRETYPE_FIXED64:

+            readRawLittleEndian64();

+            return true;

+        case WireFormat.WIRETYPE_LENGTH_DELIMITED:

+            skipRawBytes(readRawVarint32());

+            return true;

+        case WireFormat.WIRETYPE_START_GROUP:

+            skipMessage();

+            checkLastTagWas(WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));

+            return true;

+        case WireFormat.WIRETYPE_END_GROUP:

+            return false;

+        case WireFormat.WIRETYPE_FIXED32:

+            readRawLittleEndian32();

+            return true;

+        default:

+            throw InvalidProtocolBufferException.invalidWireType();

+        }

+    }

+

+    /**

+     * Reads and discards an entire message. This will read either until EOF or

+     * until an endgroup tag, whichever comes first.

+     */

+    public void skipMessage() throws IOException {

+        while (true) {

+            int tag = readTag();

+            if (tag == 0 || !skipField(tag))

+                return;

+        }

+    }

+

+    // -----------------------------------------------------------------

+

+    /** Read a {@code double} field value from the stream. */

+    public double readDouble() throws IOException {

+        return Double.longBitsToDouble(readRawLittleEndian64());

+    }

+

+    /** Read a {@code float} field value from the stream. */

+    public float readFloat() throws IOException {

+        return Float.intBitsToFloat(readRawLittleEndian32());

+    }

+

+    /** Read a {@code uint64} field value from the stream. */

+    public long readUInt64() throws IOException {

+        return readRawVarint64();

+    }

+

+    /** Read an {@code int64} field value from the stream. */

+    public long readInt64() throws IOException {

+        return readRawVarint64();

+    }

+

+    /** Read an {@code int32} field value from the stream. */

+    public int readInt32() throws IOException {

+        return readRawVarint32();

+    }

+

+    /** Read a {@code fixed64} field value from the stream. */

+    public long readFixed64() throws IOException {

+        return readRawLittleEndian64();

+    }

+

+    /** Read a {@code fixed32} field value from the stream. */

+    public int readFixed32() throws IOException {

+        return readRawLittleEndian32();

+    }

+

+    /** Read a {@code bool} field value from the stream. */

+    public boolean readBool() throws IOException {

+        return readRawVarint32() != 0;

+    }

+

+    /** Read a {@code string} field value from the stream. */

+    public String readString() throws IOException {

+        int size = readRawVarint32();

+        if (size < bufferSize - bufferPos && size > 0) {

+            // Fast path: We already have the bytes in a contiguous buffer, so

+            // just copy directly from it.

+            String result = new String(buffer, bufferPos, size, "UTF-8");

+            bufferPos += size;

+            return result;

+        } else {

+            // Slow path: Build a byte array first then copy it.

+            return new String(readRawBytes(size), "UTF-8");

+        }

+    }

+

+    /** Read a {@code bytes} field value from the stream. */

+    public ByteString readBytes() throws IOException {

+        int size = readRawVarint32();

+        if (size < bufferSize - bufferPos && size > 0) {

+            // Fast path: We already have the bytes in a contiguous buffer, so

+            // just copy directly from it.

+            ByteString result = ByteString.copyFrom(buffer, bufferPos, size);

+            bufferPos += size;

+            return result;

+        } else {

+            // Slow path: Build a byte array first then copy it.

+            return ByteString.copyFrom(readRawBytes(size));

+        }

+    }

+

+    /** Read a {@code uint32} field value from the stream. */

+    public int readUInt32() throws IOException {

+        return readRawVarint32();

+    }

+

+    /**

+     * Read an enum field value from the stream. Caller is responsible for

+     * converting the numeric value to an actual enum.

+     */

+    public int readEnum() throws IOException {

+        return readRawVarint32();

+    }

+

+    /** Read an {@code sfixed32} field value from the stream. */

+    public int readSFixed32() throws IOException {

+        return readRawLittleEndian32();

+    }

+

+    /** Read an {@code sfixed64} field value from the stream. */

+    public long readSFixed64() throws IOException {

+        return readRawLittleEndian64();

+    }

+

+    /** Read an {@code sint32} field value from the stream. */

+    public int readSInt32() throws IOException {

+        return decodeZigZag32(readRawVarint32());

+    }

+

+    /** Read an {@code sint64} field value from the stream. */

+    public long readSInt64() throws IOException {

+        return decodeZigZag64(readRawVarint64());

+    }

+

+    // =================================================================

+

+    /**

+     * Read a raw Varint from the stream. If larger than 32 bits, discard the

+     * upper bits.

+     */

+    public int readRawVarint32() throws IOException {

+        byte tmp = readRawByte();

+        if (tmp >= 0) {

+            return tmp;

+        }

+        int result = tmp & 0x7f;

+        if ((tmp = readRawByte()) >= 0) {

+            result |= tmp << 7;

+        } else {

+            result |= (tmp & 0x7f) << 7;

+            if ((tmp = readRawByte()) >= 0) {

+                result |= tmp << 14;

+            } else {

+                result |= (tmp & 0x7f) << 14;

+                if ((tmp = readRawByte()) >= 0) {

+                    result |= tmp << 21;

+                } else {

+                    result |= (tmp & 0x7f) << 21;

+                    result |= (tmp = readRawByte()) << 28;

+                    if (tmp < 0) {

+                        // Discard upper 32 bits.

+                        for (int i = 0; i < 5; i++) {

+                            if (readRawByte() >= 0)

+                                return result;

+                        }

+                        throw InvalidProtocolBufferException.malformedVarint();

+                    }

+                }

+            }

+        }

+        return result;

+    }

+

+    /** Read a raw Varint from the stream. */

+    public long readRawVarint64() throws IOException {

+        int shift = 0;

+        long result = 0;

+        while (shift < 64) {

+            byte b = readRawByte();

+            result |= (long) (b & 0x7F) << shift;

+            if ((b & 0x80) == 0)

+                return result;

+            shift += 7;

+        }

+        throw InvalidProtocolBufferException.malformedVarint();

+    }

+

+    /** Read a 32-bit little-endian integer from the stream. */

+    public int readRawLittleEndian32() throws IOException {

+        byte b1 = readRawByte();

+        byte b2 = readRawByte();

+        byte b3 = readRawByte();

+        byte b4 = readRawByte();

+        return (((int) b1 & 0xff)) | (((int) b2 & 0xff) << 8) | (((int) b3 & 0xff) << 16) | (((int) b4 & 0xff) << 24);

+    }

+

+    /** Read a 64-bit little-endian integer from the stream. */

+    public long readRawLittleEndian64() throws IOException {

+        byte b1 = readRawByte();

+        byte b2 = readRawByte();

+        byte b3 = readRawByte();

+        byte b4 = readRawByte();

+        byte b5 = readRawByte();

+        byte b6 = readRawByte();

+        byte b7 = readRawByte();

+        byte b8 = readRawByte();

+        return (((long) b1 & 0xff)) | (((long) b2 & 0xff) << 8) | (((long) b3 & 0xff) << 16) | (((long) b4 & 0xff) << 24) | (((long) b5 & 0xff) << 32) | (((long) b6 & 0xff) << 40) | (((long) b7 & 0xff) << 48) | (((long) b8 & 0xff) << 56);

+    }

+

+    /**

+     * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into

+     * values that can be efficiently encoded with varint. (Otherwise, negative

+     * values must be sign-extended to 64 bits to be varint encoded, thus always

+     * taking 10 bytes on the wire.)

+     * 

+     * @param n

+     *            An unsigned 32-bit integer, stored in a signed int because

+     *            Java has no explicit unsigned support.

+     * @return A signed 32-bit integer.

+     */

+    public static int decodeZigZag32(int n) {

+        return (n >>> 1) ^ -(n & 1);

+    }

+

+    /**

+     * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into

+     * values that can be efficiently encoded with varint. (Otherwise, negative

+     * values must be sign-extended to 64 bits to be varint encoded, thus always

+     * taking 10 bytes on the wire.)

+     * 

+     * @param n

+     *            An unsigned 64-bit integer, stored in a signed int because

+     *            Java has no explicit unsigned support.

+     * @return A signed 64-bit integer.

+     */

+    public static long decodeZigZag64(long n) {

+        return (n >>> 1) ^ -(n & 1);

+    }

+

+    // -----------------------------------------------------------------

+

+    private byte[] buffer;

+    private int bufferSize;

+    private int bufferSizeAfterLimit = 0;

+    private int bufferPos = 0;

+    private InputStream input;

+    private int lastTag = 0;

+

+    /**

+     * The total number of bytes read before the current buffer. The total bytes

+     * read up to the current position can be computed as {@code

+     * totalBytesRetired + bufferPos}.

+     */

+    private int totalBytesRetired = 0;

+

+    /** The absolute position of the end of the current message. */

+    private int currentLimit = Integer.MAX_VALUE;

+

+    /** See setRecursionLimit() */

+    private int recursionDepth = 0;

+    private int recursionLimit = DEFAULT_RECURSION_LIMIT;

+

+    /** See setSizeLimit() */

+    private int sizeLimit = DEFAULT_SIZE_LIMIT;

+

+    private static final int DEFAULT_RECURSION_LIMIT = 64;

+    private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB

+    private static final int BUFFER_SIZE = 4096;

+

+    private CodedInputStream(byte[] buffer) {

+        this.buffer = buffer;

+        this.bufferSize = buffer.length;

+        this.input = null;

+    }

+

+    private CodedInputStream(InputStream input) {

+        this.buffer = new byte[BUFFER_SIZE];

+        this.bufferSize = 0;

+        this.input = input;

+    }

+

+    /**

+     * Set the maximum message recursion depth. In order to prevent malicious

+     * messages from causing stack overflows, {@code CodedInputStream} limits

+     * how deeply messages may be nested. The default limit is 64.

+     * 

+     * @return the old limit.

+     */

+    public int setRecursionLimit(int limit) {

+        if (limit < 0) {

+            throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);

+        }

+        int oldLimit = recursionLimit;

+        recursionLimit = limit;

+        return oldLimit;

+    }

+

+    /**

+     * Set the maximum message size. In order to prevent malicious messages from

+     * exhausting memory or causing integer overflows, {@code CodedInputStream}

+     * limits how large a message may be. The default limit is 64MB. You should

+     * set this limit as small as you can without harming your app's

+     * functionality. Note that size limits only apply when reading from an

+     * {@code InputStream}, not when constructed around a raw byte array (nor

+     * with {@link ByteString#newCodedInput}).

+     * 

+     * @return the old limit.

+     */

+    public int setSizeLimit(int limit) {

+        if (limit < 0) {

+            throw new IllegalArgumentException("Size limit cannot be negative: " + limit);

+        }

+        int oldLimit = sizeLimit;

+        sizeLimit = limit;

+        return oldLimit;

+    }

+

+    /**

+     * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This

+     * is called when descending into a length-delimited embedded message.

+     * 

+     * @return the old limit.

+     */

+    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {

+        if (byteLimit < 0) {

+            throw InvalidProtocolBufferException.negativeSize();

+        }

+        byteLimit += totalBytesRetired + bufferPos;

+        int oldLimit = currentLimit;

+        if (byteLimit > oldLimit) {

+            throw InvalidProtocolBufferException.truncatedMessage();

+        }

+        currentLimit = byteLimit;

+

+        recomputeBufferSizeAfterLimit();

+

+        return oldLimit;

+    }

+

+    private void recomputeBufferSizeAfterLimit() {

+        bufferSize += bufferSizeAfterLimit;

+        int bufferEnd = totalBytesRetired + bufferSize;

+        if (bufferEnd > currentLimit) {

+            // Limit is in current buffer.

+            bufferSizeAfterLimit = bufferEnd - currentLimit;

+            bufferSize -= bufferSizeAfterLimit;

+        } else {

+            bufferSizeAfterLimit = 0;

+        }

+    }

+

+    /**

+     * Discards the current limit, returning to the previous limit.

+     * 

+     * @param oldLimit

+     *            The old limit, as returned by {@code pushLimit}.

+     */

+    public void popLimit(int oldLimit) {

+        currentLimit = oldLimit;

+        recomputeBufferSizeAfterLimit();

+    }

+

+    /**

+     * Called with {@code this.buffer} is empty to read more bytes from the

+     * input. If {@code mustSucceed} is true, refillBuffer() gurantees that

+     * either there will be at least one byte in the buffer when it returns or

+     * it will throw an exception. If {@code mustSucceed} is false,

+     * refillBuffer() returns false if no more bytes were available.

+     */

+    private boolean refillBuffer(boolean mustSucceed) throws IOException {

+        if (bufferPos < bufferSize) {

+            throw new IllegalStateException("refillBuffer() called when buffer wasn't empty.");

+        }

+

+        if (totalBytesRetired + bufferSize == currentLimit) {

+            // Oops, we hit a limit.

+            if (mustSucceed) {

+                throw InvalidProtocolBufferException.truncatedMessage();

+            } else {

+                return false;

+            }

+        }

+

+        totalBytesRetired += bufferSize;

+

+        bufferPos = 0;

+        bufferSize = (input == null) ? -1 : input.read(buffer);

+        if (bufferSize == -1) {

+            bufferSize = 0;

+            if (mustSucceed) {

+                throw InvalidProtocolBufferException.truncatedMessage();

+            } else {

+                return false;

+            }

+        } else {

+            recomputeBufferSizeAfterLimit();

+            int totalBytesRead = totalBytesRetired + bufferSize + bufferSizeAfterLimit;

+            if (totalBytesRead > sizeLimit || totalBytesRead < 0) {

+                throw InvalidProtocolBufferException.sizeLimitExceeded();

+            }

+            return true;

+        }

+    }

+

+    /**

+     * Read one byte from the input.

+     * 

+     * @throws InvalidProtocolBufferException

+     *             The end of the stream or the current limit was reached.

+     */

+    public byte readRawByte() throws IOException {

+        if (bufferPos == bufferSize) {

+            refillBuffer(true);

+        }

+        return buffer[bufferPos++];

+    }

+

+    /**

+     * Read a fixed size of bytes from the input.

+     * 

+     * @throws InvalidProtocolBufferException

+     *             The end of the stream or the current limit was reached.

+     */

+    public byte[] readRawBytes(int size) throws IOException {

+        if (size < 0) {

+            throw InvalidProtocolBufferException.negativeSize();

+        }

+

+        if (totalBytesRetired + bufferPos + size > currentLimit) {

+            // Read to the end of the stream anyway.

+            skipRawBytes(currentLimit - totalBytesRetired - bufferPos);

+            // Then fail.

+            throw InvalidProtocolBufferException.truncatedMessage();

+        }

+

+        if (size <= bufferSize - bufferPos) {

+            // We have all the bytes we need already.

+            byte[] bytes = new byte[size];

+            System.arraycopy(buffer, bufferPos, bytes, 0, size);

+            bufferPos += size;

+            return bytes;

+        } else if (size < BUFFER_SIZE) {

+            // Reading more bytes than are in the buffer, but not an excessive

+            // number

+            // of bytes. We can safely allocate the resulting array ahead of

+            // time.

+

+            // First copy what we have.

+            byte[] bytes = new byte[size];

+            int pos = bufferSize - bufferPos;

+            System.arraycopy(buffer, bufferPos, bytes, 0, pos);

+            bufferPos = bufferSize;

+

+            // We want to use refillBuffer() and then copy from the buffer into

+            // our

+            // byte array rather than reading directly into our byte array

+            // because

+            // the input may be unbuffered.

+            refillBuffer(true);

+

+            while (size - pos > bufferSize) {

+                System.arraycopy(buffer, 0, bytes, pos, bufferSize);

+                pos += bufferSize;

+                bufferPos = bufferSize;

+                refillBuffer(true);

+            }

+

+            System.arraycopy(buffer, 0, bytes, pos, size - pos);

+            bufferPos = size - pos;

+

+            return bytes;

+        } else {

+            // The size is very large. For security reasons, we can't allocate

+            // the

+            // entire byte array yet. The size comes directly from the input, so

+            // a

+            // maliciously-crafted message could provide a bogus very large size

+            // in

+            // order to trick the app into allocating a lot of memory. We avoid

+            // this

+            // by allocating and reading only a small chunk at a time, so that

+            // the

+            // malicious message must actually *be* extremely large to cause

+            // problems. Meanwhile, we limit the allowed size of a message

+            // elsewhere.

+

+            // Remember the buffer markers since we'll have to copy the bytes

+            // out of

+            // it later.

+            int originalBufferPos = bufferPos;

+            int originalBufferSize = bufferSize;

+

+            // Mark the current buffer consumed.

+            totalBytesRetired += bufferSize;

+            bufferPos = 0;

+            bufferSize = 0;

+

+            // Read all the rest of the bytes we need.

+            int sizeLeft = size - (originalBufferSize - originalBufferPos);

+            List<byte[]> chunks = new ArrayList<byte[]>();

+

+            while (sizeLeft > 0) {

+                byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];

+                int pos = 0;

+                while (pos < chunk.length) {

+                    int n = (input == null) ? -1 : input.read(chunk, pos, chunk.length - pos);

+                    if (n == -1) {

+                        throw InvalidProtocolBufferException.truncatedMessage();

+                    }

+                    totalBytesRetired += n;

+                    pos += n;

+                }

+                sizeLeft -= chunk.length;

+                chunks.add(chunk);

+            }

+

+            // OK, got everything. Now concatenate it all into one buffer.

+            byte[] bytes = new byte[size];

+

+            // Start by copying the leftover bytes from this.buffer.

+            int pos = originalBufferSize - originalBufferPos;

+            System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);

+

+            // And now all the chunks.

+            for (byte[] chunk : chunks) {

+                System.arraycopy(chunk, 0, bytes, pos, chunk.length);

+                pos += chunk.length;

+            }

+

+            // Done.

+            return bytes;

+        }

+    }

+

+    /**

+     * Reads and discards {@code size} bytes.

+     * 

+     * @throws InvalidProtocolBufferException

+     *             The end of the stream or the current limit was reached.

+     */

+    public void skipRawBytes(int size) throws IOException {

+        if (size < 0) {

+            throw InvalidProtocolBufferException.negativeSize();

+        }

+

+        if (totalBytesRetired + bufferPos + size > currentLimit) {

+            // Read to the end of the stream anyway.

+            skipRawBytes(currentLimit - totalBytesRetired - bufferPos);

+            // Then fail.

+            throw InvalidProtocolBufferException.truncatedMessage();

+        }

+

+        if (size < bufferSize - bufferPos) {

+            // We have all the bytes we need already.

+            bufferPos += size;

+        } else {

+            // Skipping more bytes than are in the buffer. First skip what we

+            // have.

+            int pos = bufferSize - bufferPos;

+            totalBytesRetired += pos;

+            bufferPos = 0;

+            bufferSize = 0;

+

+            // Then skip directly from the InputStream for the rest.

+            while (pos < size) {

+                int n = (input == null) ? -1 : (int) input.skip(size - pos);

+                if (n <= 0) {

+                    throw InvalidProtocolBufferException.truncatedMessage();

+                }

+                pos += n;

+                totalBytesRetired += n;

+            }

+        }

+    }

+}

diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java
new file mode 100644
index 0000000..7e391f8
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/CodedOutputStream.java
@@ -0,0 +1,599 @@
+

+//Protocol Buffers - Google's data interchange format

+//Copyright 2008 Google Inc.

+//http://code.google.com/p/protobuf/

+//

+//Licensed under the Apache License, Version 2.0 (the "License");

+//you may not use this file except in compliance with the License.

+//You may obtain a copy of the License at

+//

+//   http://www.apache.org/licenses/LICENSE-2.0

+//

+//Unless required by applicable law or agreed to in writing, software

+//distributed under the License is distributed on an "AS IS" BASIS,

+//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+//See the License for the specific language governing permissions and

+//limitations under the License.

+package org.apache.activemq.protobuf;

+

+import java.io.IOException;

+import java.io.OutputStream;

+

+/**

+* Encodes and writes protocol message fields.

+*

+* <p>This class contains two kinds of methods:  methods that write specific

+* protocol message constructs and field types (e.g. {@link #writeTag} and

+* {@link #writeInt32}) and methods that write low-level values (e.g.

+* {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are

+* writing encoded protocol messages, you should use the former methods, but if

+* you are writing some other format of your own design, use the latter.

+*

+* <p>This class is totally unsynchronized.

+*

+* @author kneton@google.com Kenton Varda

+*/

+public final class CodedOutputStream {

+private final byte[] buffer;

+private final int limit;

+private int position;

+

+private final OutputStream output;

+

+/**

+* The buffer size used in {@link #newInstance(java.io.OutputStream)}.

+*/

+public static final int DEFAULT_BUFFER_SIZE = 4096;

+

+private CodedOutputStream(byte[] buffer, int offset, int length) {

+ this.output = null;

+ this.buffer = buffer;

+ this.position = offset;

+ this.limit = offset + length;

+}

+

+private CodedOutputStream(OutputStream output, byte[] buffer) {

+ this.output = output;

+ this.buffer = buffer;

+ this.position = 0;

+ this.limit = buffer.length;

+}

+

+/**

+* Create a new {@code CodedOutputStream} wrapping the given

+* {@code OutputStream}.

+*/

+public static CodedOutputStream newInstance(OutputStream output) {

+ return newInstance(output, DEFAULT_BUFFER_SIZE);

+}

+

+/**

+* Create a new {@code CodedOutputStream} wrapping the given

+* {@code OutputStream} with a given buffer size.

+*/

+public static CodedOutputStream newInstance(OutputStream output,

+   int bufferSize) {

+ return new CodedOutputStream(output, new byte[bufferSize]);

+}

+

+/**

+* Create a new {@code CodedOutputStream} that writes directly to the given

+* byte array.  If more bytes are written than fit in the array,

+* {@link OutOfSpaceException} will be thrown.  Writing directly to a flat

+* array is faster than writing to an {@code OutputStream}.  See also

+* {@link ByteString#newCodedBuilder}.

+*/

+public static CodedOutputStream newInstance(byte[] flatArray) {

+ return newInstance(flatArray, 0, flatArray.length);

+}

+

+/**

+* Create a new {@code CodedOutputStream} that writes directly to the given

+* byte array slice.  If more bytes are written than fit in the slice,

+* {@link OutOfSpaceException} will be thrown.  Writing directly to a flat

+* array is faster than writing to an {@code OutputStream}.  See also

+* {@link ByteString#newCodedBuilder}.

+*/

+public static CodedOutputStream newInstance(byte[] flatArray, int offset,

+   int length) {

+ return new CodedOutputStream(flatArray, offset, length);

+}

+

+// -----------------------------------------------------------------

+

+/** Write a {@code double} field, including tag, to the stream. */

+public void writeDouble(int fieldNumber, double value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);

+ writeRawLittleEndian64(Double.doubleToRawLongBits(value));

+}

+

+/** Write a {@code float} field, including tag, to the stream. */

+public void writeFloat(int fieldNumber, float value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);

+ writeRawLittleEndian32(Float.floatToRawIntBits(value));

+}

+

+/** Write a {@code uint64} field, including tag, to the stream. */

+public void writeUInt64(int fieldNumber, long value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint64(value);

+}

+

+/** Write an {@code int64} field, including tag, to the stream. */

+public void writeInt64(int fieldNumber, long value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint64(value);

+}

+

+/** Write an {@code int32} field, including tag, to the stream. */

+public void writeInt32(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ if (value >= 0) {

+   writeRawVarint32(value);

+ } else {

+   // Must sign-extend.

+   writeRawVarint64(value);

+ }

+}

+

+/** Write a {@code fixed64} field, including tag, to the stream. */

+public void writeFixed64(int fieldNumber, long value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);

+ writeRawLittleEndian64(value);

+}

+

+/** Write a {@code fixed32} field, including tag, to the stream. */

+public void writeFixed32(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);

+ writeRawLittleEndian32(value);

+}

+

+/** Write a {@code bool} field, including tag, to the stream. */

+public void writeBool(int fieldNumber, boolean value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawByte(value ? 1 : 0);

+}

+

+/** Write a {@code string} field, including tag, to the stream. */

+public void writeString(int fieldNumber, String value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);

+ // Unfortunately there does not appear to be any way to tell Java to encode

+ // UTF-8 directly into our buffer, so we have to let it create its own byte

+ // array and then copy.

+ byte[] bytes = value.getBytes("UTF-8");

+ writeRawVarint32(bytes.length);

+ writeRawBytes(bytes);

+}

+

+/** Write a {@code bytes} field, including tag, to the stream. */

+public void writeBytes(int fieldNumber, ByteString value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);

+ byte[] bytes = value.toByteArray();

+ writeRawVarint32(bytes.length);

+ writeRawBytes(bytes);

+}

+

+/** Write a {@code uint32} field, including tag, to the stream. */

+public void writeUInt32(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint32(value);

+}

+

+/**

+* Write an enum field, including tag, to the stream.  Caller is responsible

+* for converting the enum value to its numeric value.

+*/

+public void writeEnum(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint32(value);

+}

+

+/** Write an {@code sfixed32} field, including tag, to the stream. */

+public void writeSFixed32(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);

+ writeRawLittleEndian32(value);

+}

+

+/** Write an {@code sfixed64} field, including tag, to the stream. */

+public void writeSFixed64(int fieldNumber, long value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);

+ writeRawLittleEndian64(value);

+}

+

+/** Write an {@code sint32} field, including tag, to the stream. */

+public void writeSInt32(int fieldNumber, int value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint32(encodeZigZag32(value));

+}

+

+/** Write an {@code sint64} field, including tag, to the stream. */

+public void writeSInt64(int fieldNumber, long value) throws IOException {

+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);

+ writeRawVarint64(encodeZigZag64(value));

+}

+

+// =================================================================

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code double} field, including tag.

+*/

+public static int computeDoubleSize(int fieldNumber, double value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code float} field, including tag.

+*/

+public static int computeFloatSize(int fieldNumber, float value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code uint64} field, including tag.

+*/

+public static int computeUInt64Size(int fieldNumber, long value) {

+ return computeTagSize(fieldNumber) + computeRawVarint64Size(value);

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code int64} field, including tag.

+*/

+public static int computeInt64Size(int fieldNumber, long value) {

+ return computeTagSize(fieldNumber) + computeRawVarint64Size(value);

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code int32} field, including tag.

+*/

+public static int computeInt32Size(int fieldNumber, int value) {

+ if (value >= 0) {

+   return computeTagSize(fieldNumber) + computeRawVarint32Size(value);

+ } else {

+   // Must sign-extend.

+   return computeTagSize(fieldNumber) + 10;

+ }

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code fixed64} field, including tag.

+*/

+public static int computeFixed64Size(int fieldNumber, long value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code fixed32} field, including tag.

+*/

+public static int computeFixed32Size(int fieldNumber, int value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code bool} field, including tag.

+*/

+public static int computeBoolSize(int fieldNumber, boolean value) {

+ return computeTagSize(fieldNumber) + 1;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code string} field, including tag.

+*/

+public static int computeStringSize(int fieldNumber, String value) {

+ try {

+   byte[] bytes = value.getBytes("UTF-8");

+   return computeTagSize(fieldNumber) +

+          computeRawVarint32Size(bytes.length) +

+          bytes.length;

+ } catch (java.io.UnsupportedEncodingException e) {

+   throw new RuntimeException("UTF-8 not supported.", e);

+ }

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code bytes} field, including tag.

+*/

+public static int computeBytesSize(int fieldNumber, ByteString value) {

+ return computeTagSize(fieldNumber) +

+        computeRawVarint32Size(value.size()) +

+        value.size();

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a

+* {@code uint32} field, including tag.

+*/

+public static int computeUInt32Size(int fieldNumber, int value) {

+ return computeTagSize(fieldNumber) + computeRawVarint32Size(value);

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* enum field, including tag.  Caller is responsible for converting the

+* enum value to its numeric value.

+*/

+public static int computeEnumSize(int fieldNumber, int value) {

+ return computeTagSize(fieldNumber) + computeRawVarint32Size(value);

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code sfixed32} field, including tag.

+*/

+public static int computeSFixed32Size(int fieldNumber, int value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code sfixed64} field, including tag.

+*/

+public static int computeSFixed64Size(int fieldNumber, long value) {

+ return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code sint32} field, including tag.

+*/

+public static int computeSInt32Size(int fieldNumber, int value) {

+ return computeTagSize(fieldNumber) +

+        computeRawVarint32Size(encodeZigZag32(value));

+}

+

+/**

+* Compute the number of bytes that would be needed to encode an

+* {@code sint64} field, including tag.

+*/

+public static int computeSInt64Size(int fieldNumber, long value) {

+ return computeTagSize(fieldNumber) +

+        computeRawVarint64Size(encodeZigZag64(value));

+}

+

+// =================================================================

+

+/**

+* Internal helper that writes the current buffer to the output. The

+* buffer position is reset to its initial value when this returns.

+*/

+private void refreshBuffer() throws IOException {

+ if (output == null) {

+   // We're writing to a single buffer.

+   throw new OutOfSpaceException();

+ }

+

+ // Since we have an output stream, this is our buffer

+ // and buffer offset == 0

+ output.write(buffer, 0, position);

+ position = 0;

+}

+

+/**

+* Flushes the stream and forces any buffered bytes to be written.  This

+* does not flush the underlying OutputStream.

+*/

+public void flush() throws IOException {

+ if (output != null) {

+   refreshBuffer();

+ }

+}

+

+/**

+* If writing to a flat array, return the space left in the array.

+* Otherwise, throws {@code UnsupportedOperationException}.

+*/

+public int spaceLeft() {

+ if (output == null) {

+   return limit - position;

+ } else {

+   throw new UnsupportedOperationException(

+     "spaceLeft() can only be called on CodedOutputStreams that are " +

+     "writing to a flat array.");

+ }

+}

+

+/**

+* Verifies that {@link #spaceLeft()} returns zero.  It's common to create

+* a byte array that is exactly big enough to hold a message, then write to

+* it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}

+* after writing verifies that the message was actually as big as expected,

+* which can help catch bugs.

+*/

+public void checkNoSpaceLeft() {

+ if (spaceLeft() != 0) {

+   throw new IllegalStateException(

+     "Did not write as much data as expected.");

+ }

+}

+

+/**

+* If you create a CodedOutputStream around a simple flat array, you must

+* not attempt to write more bytes than the array has space.  Otherwise,

+* this exception will be thrown.

+*/

+public static class OutOfSpaceException extends IOException {

+ OutOfSpaceException() {

+   super("CodedOutputStream was writing to a flat byte array and ran " +

+         "out of space.");

+ }

+}

+

+/** Write a single byte. */

+public void writeRawByte(byte value) throws IOException {

+ if (position == limit) {

+   refreshBuffer();

+ }

+

+ buffer[position++] = value;

+}

+

+/** Write a single byte, represented by an integer value. */

+public void writeRawByte(int value) throws IOException {

+ writeRawByte((byte) value);

+}

+

+/** Write an array of bytes. */

+public void writeRawBytes(byte[] value) throws IOException {

+ writeRawBytes(value, 0, value.length);

+}

+

+/** Write part of an array of bytes. */

+public void writeRawBytes(byte[] value, int offset, int length)

+                         throws IOException {

+ if (limit - position >= length) {

+   // We have room in the current buffer.

+   System.arraycopy(value, offset, buffer, position, length);

+   position += length;

+ } else {

+   // Write extends past current buffer.  Fill the rest of this buffer and

+   // flush.

+   int bytesWritten = limit - position;

+   System.arraycopy(value, offset, buffer, position, bytesWritten);

+   offset += bytesWritten;

+   length -= bytesWritten;

+   position = limit;

+   refreshBuffer();

+

+   // Now deal with the rest.

+   // Since we have an output stream, this is our buffer

+   // and buffer offset == 0

+   if (length <= limit) {

+     // Fits in new buffer.

+     System.arraycopy(value, offset, buffer, 0, length);

+     position = length;

+   } else {

+     // Write is very big.  Let's do it all at once.

+     output.write(value, offset, length);

+   }

+ }

+}

+

+/** Encode and write a tag. */

+public void writeTag(int fieldNumber, int wireType) throws IOException {

+ writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));

+}

+

+/** Compute the number of bytes that would be needed to encode a tag. */

+public static int computeTagSize(int fieldNumber) {

+ return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));

+}

+

+/**

+* Encode and write a varint.  {@code value} is treated as

+* unsigned, so it won't be sign-extended if negative.

+*/

+public void writeRawVarint32(int value) throws IOException {

+ while (true) {

+   if ((value & ~0x7F) == 0) {

+     writeRawByte(value);

+     return;

+   } else {

+     writeRawByte((value & 0x7F) | 0x80);

+     value >>>= 7;

+   }

+ }

+}

+

+/**

+* Compute the number of bytes that would be needed to encode a varint.

+* {@code value} is treated as unsigned, so it won't be sign-extended if

+* negative.

+*/

+public static int computeRawVarint32Size(int value) {

+ if ((value & (0xffffffff <<  7)) == 0) return 1;

+ if ((value & (0xffffffff << 14)) == 0) return 2;

+ if ((value & (0xffffffff << 21)) == 0) return 3;

+ if ((value & (0xffffffff << 28)) == 0) return 4;

+ return 5;

+}

+

+/** Encode and write a varint. */

+public void writeRawVarint64(long value) throws IOException {

+ while (true) {

+   if ((value & ~0x7FL) == 0) {

+     writeRawByte((int)value);

+     return;

+   } else {

+     writeRawByte(((int)value & 0x7F) | 0x80);

+     value >>>= 7;

+   }

+ }

+}

+

+/** Compute the number of bytes that would be needed to encode a varint. */

+public static int computeRawVarint64Size(long value) {

+ if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;

+ if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;

+ if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;

+ if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;

+ if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;

+ if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;

+ if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;

+ if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;

+ if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;

+ return 10;

+}

+

+/** Write a little-endian 32-bit integer. */

+public void writeRawLittleEndian32(int value) throws IOException {

+ writeRawByte((value      ) & 0xFF);

+ writeRawByte((value >>  8) & 0xFF);

+ writeRawByte((value >> 16) & 0xFF);

+ writeRawByte((value >> 24) & 0xFF);

+}

+

+public static final int LITTLE_ENDIAN_32_SIZE = 4;

+

+/** Write a little-endian 64-bit integer. */

+public void writeRawLittleEndian64(long value) throws IOException {

+ writeRawByte((int)(value      ) & 0xFF);

+ writeRawByte((int)(value >>  8) & 0xFF);

+ writeRawByte((int)(value >> 16) & 0xFF);

+ writeRawByte((int)(value >> 24) & 0xFF);

+ writeRawByte((int)(value >> 32) & 0xFF);

+ writeRawByte((int)(value >> 40) & 0xFF);

+ writeRawByte((int)(value >> 48) & 0xFF);

+ writeRawByte((int)(value >> 56) & 0xFF);

+}

+

+public static final int LITTLE_ENDIAN_64_SIZE = 8;

+

+/**

+* Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers

+* into values that can be efficiently encoded with varint.  (Otherwise,

+* negative values must be sign-extended to 64 bits to be varint encoded,

+* thus always taking 10 bytes on the wire.)

+*

+* @param n A signed 32-bit integer.

+* @return An unsigned 32-bit integer, stored in a signed int because

+*         Java has no explicit unsigned support.

+*/

+public static int encodeZigZag32(int n) {

+ // Note:  the right-shift must be arithmetic

+ return (n << 1) ^ (n >> 31);

+}

+

+/**

+* Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers

+* into values that can be efficiently encoded with varint.  (Otherwise,

+* negative values must be sign-extended to 64 bits to be varint encoded,

+* thus always taking 10 bytes on the wire.)

+*

+* @param n A signed 64-bit integer.

+* @return An unsigned 64-bit integer, stored in a signed int because

+*         Java has no explicit unsigned support.

+*/

+public static long encodeZigZag64(long n) {

+ // Note:  the right-shift must be arithmetic

+ return (n << 1) ^ (n >> 63);

+}

+}

diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
index f914acc..f789073 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/DeferredDecodeMessage.java
@@ -18,9 +18,6 @@
 
 import java.io.IOException;
 
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
 abstract public class DeferredDecodeMessage<T> extends BaseMessage<T> {
 
     protected byte[] encodedForm;
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java
new file mode 100644
index 0000000..f624605
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/InvalidProtocolBufferException.java
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format

+// Copyright 2008 Google Inc.

+// http://code.google.com/p/protobuf/

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//      http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.activemq.protobuf;

+

+import java.io.IOException;

+

+/**

+ * Thrown when a protocol message being parsed is invalid in some way, e.g. it

+ * contains a malformed varint or a negative byte length.

+ * 

+ * @author kenton@google.com Kenton Varda

+ */

+public class InvalidProtocolBufferException extends IOException {

+    private static final long serialVersionUID = 5685337441004132240L;

+

+    public InvalidProtocolBufferException(String description) {

+        super(description);

+    }

+

+    static InvalidProtocolBufferException truncatedMessage() {

+        return new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field.  This could mean either than the " + "input has been truncated or that an embedded message "

+                + "misreported its own length.");

+    }

+

+    static InvalidProtocolBufferException negativeSize() {

+        return new InvalidProtocolBufferException("CodedInputStream encountered an embedded string or message " + "which claimed to have negative size.");

+    }

+

+    static InvalidProtocolBufferException malformedVarint() {

+        return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");

+    }

+

+    static InvalidProtocolBufferException invalidTag() {

+        return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero).");

+    }

+

+    static InvalidProtocolBufferException invalidEndTag() {

+        return new InvalidProtocolBufferException("Protocol message end-group tag did not match expected tag.");

+    }

+

+    static InvalidProtocolBufferException invalidWireType() {

+        return new InvalidProtocolBufferException("Protocol message tag had invalid wire type.");

+    }

+

+    static InvalidProtocolBufferException recursionLimitExceeded() {

+        return new InvalidProtocolBufferException("Protocol message had too many levels of nesting.  May be malicious.  " + "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");

+    }

+

+    static InvalidProtocolBufferException sizeLimitExceeded() {

+        return new InvalidProtocolBufferException("Protocol message was too large.  May be malicious.  " + "Use CodedInputStream.setSizeLimit() to increase the size limit.");

+    }

+}

diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
index 36757d6..7f13031 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/Message.java
@@ -20,11 +20,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import com.google.protobuf.ByteString;
-import com.google.protobuf.CodedInputStream;
-import com.google.protobuf.CodedOutputStream;
-import com.google.protobuf.InvalidProtocolBufferException;
-
 public interface Message<T> {
 
     public T clone() throws CloneNotSupportedException;
@@ -35,7 +30,7 @@
 
     public void clear();
 
-    public T assertInitialized() throws com.google.protobuf.UninitializedMessageException;
+    public T assertInitialized() throws UninitializedMessageException;
 
     public T mergeFrom(T other);
 
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
index 4824b15..3e17dae 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/UninitializedMessageException.java
@@ -16,67 +16,61 @@
 
 package org.apache.activemq.protobuf;
 
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Thrown when attempting to build a protocol message that is missing required
- * fields.  This is a {@code RuntimeException} because it normally represents
- * a programming error:  it happens when some code which constructs a message
- * fails to set all the fields.  {@code parseFrom()} methods <b>do not</b>
- * throw this; they throw an {@link InvalidProtocolBufferException} if
- * required fields are missing, because it is not a programming error to
- * receive an incomplete message.  In other words,
- * {@code UninitializedMessageException} should never be thrown by correct
- * code, but {@code InvalidProtocolBufferException} might be.
- *
+ * fields. This is a {@code RuntimeException} because it normally represents a
+ * programming error: it happens when some code which constructs a message fails
+ * to set all the fields. {@code parseFrom()} methods <b>do not</b> throw this;
+ * they throw an {@link InvalidProtocolBufferException} if required fields are
+ * missing, because it is not a programming error to receive an incomplete
+ * message. In other words, {@code UninitializedMessageException} should never
+ * be thrown by correct code, but {@code InvalidProtocolBufferException} might
+ * be.
+ * 
  * @author kenton@google.com Kenton Varda
  */
 public class UninitializedMessageException extends RuntimeException {
 
-  public UninitializedMessageException(List<String> missingFields) {
-    super(buildDescription(missingFields));
-    this.missingFields = missingFields;
-  }
-
-  private final List<String> missingFields;
-
-  /**
-   * Get a list of human-readable names of required fields missing from this
-   * message.  Each name is a full path to a field, e.g. "foo.bar[5].baz".
-   */
-  public List<String> getMissingFields() {
-    return Collections.unmodifiableList(missingFields);
-  }
-
-  /**
-   * Converts this exception to an {@link InvalidProtocolBufferException}.
-   * When a parsed message is missing required fields, this should be thrown
-   * instead of {@code UninitializedMessageException}.
-   */
-  public com.google.protobuf.InvalidProtocolBufferException asInvalidProtocolBufferException() {
-    return new InvalidProtocolBufferException(getMessage());
-  }
-
-  /** Construct the description string for this exception. */
-  private static String buildDescription(List<String> missingFields) {
-    StringBuilder description =
-      new StringBuilder("Message missing required fields: ");
-    boolean first = true;
-    for (String field : missingFields) {
-      if (first) {
-        first = false;
-      } else {
-        description.append(", ");
-      }
-      description.append(field);
+    public UninitializedMessageException(List<String> missingFields) {
+        super(buildDescription(missingFields));
+        this.missingFields = missingFields;
     }
-    return description.toString();
-  }
+
+    private final List<String> missingFields;
+
+    /**
+     * Get a list of human-readable names of required fields missing from this
+     * message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
+     */
+    public List<String> getMissingFields() {
+        return Collections.unmodifiableList(missingFields);
+    }
+
+    /**
+     * Converts this exception to an {@link InvalidProtocolBufferException}.
+     * When a parsed message is missing required fields, this should be thrown
+     * instead of {@code UninitializedMessageException}.
+     */
+    public InvalidProtocolBufferException asInvalidProtocolBufferException() {
+        return new InvalidProtocolBufferException(getMessage());
+    }
+
+    /** Construct the description string for this exception. */
+    private static String buildDescription(List<String> missingFields) {
+        StringBuilder description = new StringBuilder("Message missing required fields: ");
+        boolean first = true;
+        for (String field : missingFields) {
+            if (first) {
+                first = false;
+            } else {
+                description.append(", ");
+            }
+            description.append(field);
+        }
+        return description.toString();
+    }
 
 }
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java
new file mode 100644
index 0000000..3018bb7
--- /dev/null
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireFormat.java
@@ -0,0 +1,70 @@
+// Protocol Buffers - Google's data interchange format

+// Copyright 2008 Google Inc.

+// http://code.google.com/p/protobuf/

+//

+// Licensed under the Apache License, Version 2.0 (the "License");

+// you may not use this file except in compliance with the License.

+// You may obtain a copy of the License at

+//

+//      http://www.apache.org/licenses/LICENSE-2.0

+//

+// Unless required by applicable law or agreed to in writing, software

+// distributed under the License is distributed on an "AS IS" BASIS,

+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+// See the License for the specific language governing permissions and

+// limitations under the License.

+

+package org.apache.activemq.protobuf;

+

+/**

+ * This class is used internally by the Protocol Buffer library and generated

+ * message implementations. It is public only because those generated messages

+ * do not reside in the {@code protocol2} package. Others should not use this

+ * class directly.

+ * 

+ * This class contains constants and helper functions useful for dealing with

+ * the Protocol Buffer wire format.

+ * 

+ * @author kenton@google.com Kenton Varda

+ */

+public final class WireFormat {

+    // Do not allow instantiation.

+    private WireFormat() {

+    }

+

+    public static final int WIRETYPE_VARINT = 0;

+    public static final int WIRETYPE_FIXED64 = 1;

+    public static final int WIRETYPE_LENGTH_DELIMITED = 2;

+    public static final int WIRETYPE_START_GROUP = 3;

+    public static final int WIRETYPE_END_GROUP = 4;

+    public static final int WIRETYPE_FIXED32 = 5;

+

+    public static final int TAG_TYPE_BITS = 3;

+    public static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;

+

+    /** Given a tag value, determines the wire type (the lower 3 bits). */

+    public static int getTagWireType(int tag) {

+        return tag & TAG_TYPE_MASK;

+    }

+

+    /** Given a tag value, determines the field number (the upper 29 bits). */

+    public static int getTagFieldNumber(int tag) {

+        return tag >>> TAG_TYPE_BITS;

+    }

+

+    /** Makes a tag value given a field number and wire type. */

+    public static int makeTag(int fieldNumber, int wireType) {

+        return (fieldNumber << TAG_TYPE_BITS) | wireType;

+    }

+

+    // Field numbers for feilds in MessageSet wire format.

+    public static final int MESSAGE_SET_ITEM = 1;

+    public static final int MESSAGE_SET_TYPE_ID = 2;

+    public static final int MESSAGE_SET_MESSAGE = 3;

+

+    // Tag numbers.

+    public static final int MESSAGE_SET_ITEM_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);

+    public static final int MESSAGE_SET_ITEM_END_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);

+    public static final int MESSAGE_SET_TYPE_ID_TAG = makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);

+    public static final int MESSAGE_SET_MESSAGE_TAG = makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);

+}

diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java
deleted file mode 100644
index a9c4f41..0000000
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/WireInfo.java
+++ /dev/null
@@ -1,33 +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.protobuf;
-
-public class WireInfo {
-    
-    public static final int WIRETYPE_VARINT = 0;
-    public static final int WIRETYPE_FIXED64 = 1;
-    public static final int WIRETYPE_LENGTH_DELIMITED = 2;
-    public static final int WIRETYPE_START_GROUP = 3;
-    public static final int WIRETYPE_END_GROUP = 4;
-    public static final int WIRETYPE_FIXED32 = 5;
-    
-    public static final int TAG_TYPE_BITS = 3;
-
-    public static int makeTag(int fieldNumber, int wireType) {
-        return (fieldNumber << TAG_TYPE_BITS) | wireType;
-    }
-}
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
index e407ac7..3a29986 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/JavaGenerator.java
@@ -16,12 +16,12 @@
  */
 package org.apache.activemq.protobuf.compiler;
 
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_FIXED32;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_FIXED64;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_LENGTH_DELIMITED;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_START_GROUP;
-import static org.apache.activemq.protobuf.WireInfo.WIRETYPE_VARINT;
-import static org.apache.activemq.protobuf.WireInfo.makeTag;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED32;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_FIXED64;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_START_GROUP;
+import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_VARINT;
+import static org.apache.activemq.protobuf.WireFormat.makeTag;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -446,56 +446,56 @@
         	postMergeProcessing="";
         }
         
-        p("public static "+className+" parseUnframed(com.google.protobuf.CodedInputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+        p("public static "+className+" parseUnframed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
         indent();
         p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
 
-        p("public static "+className+" parseUnframed(com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException {");
+        p("public static "+className+" parseUnframed(org.apache.activemq.protobuf.ByteString data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
         indent();
         p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
 
-        p("public static "+className+" parseUnframed(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {");
+        p("public static "+className+" parseUnframed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
         indent();
         p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
         
-        p("public static "+className+" parseUnframed(java.io.InputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+        p("public static "+className+" parseUnframed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
         indent();
         p("return new "+className+"().mergeUnframed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
         
-        p("public static "+className+" parseFramed(com.google.protobuf.CodedInputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+        p("public static "+className+" parseFramed(org.apache.activemq.protobuf.CodedInputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
         indent();
         p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
         
-        p("public static "+className+" parseFramed(com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException {");
+        p("public static "+className+" parseFramed(org.apache.activemq.protobuf.ByteString data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
         indent();
         p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
 
-        p("public static "+className+" parseFramed(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException {");
+        p("public static "+className+" parseFramed(byte[] data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException {");
         indent();
         p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
         unindent();
         p("}");
         p();
         
-        p("public static "+className+" parseFramed(java.io.InputStream data) throws com.google.protobuf.InvalidProtocolBufferException, java.io.IOException {");
+        p("public static "+className+" parseFramed(java.io.InputStream data) throws org.apache.activemq.protobuf.InvalidProtocolBufferException, java.io.IOException {");
         indent();
         p("return new "+className+"().mergeFramed(data)"+postMergeProcessing+";");
         unindent();
@@ -637,37 +637,37 @@
             }
 
             if( field.getType()==FieldDescriptor.STRING_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeStringSize("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeStringSize("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.BYTES_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeBytesSize("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBytesSize("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.BOOL_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeBoolSize("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeBoolSize("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.DOUBLE_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeDoubleSize("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeDoubleSize("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.FLOAT_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeFloatSize("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFloatSize("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.INT32_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeInt32Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt32Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.INT64_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeInt64Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeInt64Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.SINT32_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeSInt32Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt32Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.SINT64_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeSInt64Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSInt64Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.UINT32_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeUInt32Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt32Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.UINT64_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeUInt64Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeUInt64Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.FIXED32_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeFixed32Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed32Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.FIXED64_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeFixed64Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeFixed64Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.SFIXED32_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeSFixed32Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed32Size("+field.getTag()+", "+getter+");");
             } else if( field.getType()==FieldDescriptor.SFIXED64_TYPE ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeSFixed64Size("+field.getTag()+", "+getter+");");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeSFixed64Size("+field.getTag()+", "+getter+");");
             } else if( field.getTypeDescriptor().isEnum() ) {
-                p("size += com.google.protobuf.CodedOutputStream.computeEnumSize("+field.getTag()+", "+getter+".getNumber());");
+                p("size += org.apache.activemq.protobuf.CodedOutputStream.computeEnumSize("+field.getTag()+", "+getter+".getNumber());");
             } else if ( field.getGroup()!=null ) {
                 p("size += computeGroupSize("+field.getTag()+", "+getter+");");
             } else {
@@ -695,15 +695,15 @@
      * @param m
      */
     private void generateMethodWriteTo(MessageDescriptor m) {
-        p("public void writeUnframed(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {");
+        p("public void writeUnframed(org.apache.activemq.protobuf.CodedOutputStream output) throws java.io.IOException {");
         indent();
         
         if( deferredDecode ) {
 			p("if (encodedForm == null) {");
 			indent();
 			p("encodedForm = new byte[serializedSizeUnframed()];");
-			p("com.google.protobuf.CodedOutputStream original = output;");
-			p("output = com.google.protobuf.CodedOutputStream.newInstance(encodedForm);");
+			p("org.apache.activemq.protobuf.CodedOutputStream original = output;");
+			p("output = org.apache.activemq.protobuf.CodedOutputStream.newInstance(encodedForm);");
         }
         
 
@@ -786,7 +786,7 @@
      * @param className
      */
     private void generateMethodMergeFromStream(MessageDescriptor m, String className) {
-        p("public "+className+" mergeUnframed(com.google.protobuf.CodedInputStream input) throws java.io.IOException {");
+        p("public "+className+" mergeUnframed(org.apache.activemq.protobuf.CodedInputStream input) throws java.io.IOException {");
         indent();
 		{        
 			p("while (true) {");
@@ -1349,7 +1349,7 @@
             if( field.isStringType() ) {
                 return asJavaString(defaultOption.getValue());
             } else if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-                return "com.google.protobuf.ByteString.copyFromUtf8("+asJavaString(defaultOption.getValue())+")";
+                return "org.apache.activemq.protobuf.ByteString.copyFromUtf8("+asJavaString(defaultOption.getValue())+")";
             } else if( field.isInteger32Type() ) {
                 int v;
                 if( field.getType() == FieldDescriptor.UINT32_TYPE ) {
@@ -1529,7 +1529,7 @@
             return "java.lang.String";
         }
         if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-            return "com.google.protobuf.ByteString";
+            return "org.apache.activemq.protobuf.ByteString";
         }
         if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
             return "java.lang.Boolean";
@@ -1556,7 +1556,7 @@
             return "java.lang.String";
         }
         if( field.getType() == FieldDescriptor.BYTES_TYPE ) {
-            return "com.google.protobuf.ByteString";
+            return "org.apache.activemq.protobuf.ByteString";
         }
         if( field.getType() == FieldDescriptor.BOOL_TYPE ) {
             return "boolean";
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
index 58c820a..5ad1285 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/ParserSupport.java
@@ -19,7 +19,6 @@
 import org.apache.activemq.protobuf.compiler.TextFormat.InvalidEscapeSequence;
 import org.apache.activemq.protobuf.compiler.parser.ParseException;
 import org.apache.activemq.protobuf.compiler.parser.Token;
-import com.google.protobuf.ByteString;
 
 public class ParserSupport {
 
diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
index e041e2f..616920a 100644
--- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
+++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TextFormat.java
@@ -16,21 +16,14 @@
 
 package org.apache.activemq.protobuf.compiler;
 
-import com.google.protobuf.ByteString;
-import com.google.protobuf.Descriptors.Descriptor;
-import com.google.protobuf.Descriptors.FieldDescriptor;
-import com.google.protobuf.Descriptors.EnumDescriptor;
-import com.google.protobuf.Descriptors.EnumValueDescriptor;
-
 import java.io.IOException;
-import java.nio.CharBuffer;
 import java.math.BigInteger;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.nio.CharBuffer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.activemq.protobuf.ByteString;
+
 /** 
  * Provide ascii text parsing and formatting support for proto2 instances.
  * The implementation largely follows google/protobuf/text_format.cc.