You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2013/11/19 00:23:16 UTC

[3/3] git commit: Fully implemented StringBuilder and StringBuffer with buffer sharing to String.

Fully implemented StringBuilder and StringBuffer with buffer sharing to
String.  

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

Branch: refs/heads/trunk
Commit: c6e8f8fe6130ef08251b8bdfd5a9dcf182259f44
Parents: 3cdc561
Author: Timothy Bish <ta...@gmai.com>
Authored: Mon Nov 18 18:23:05 2013 -0500
Committer: Timothy Bish <ta...@gmai.com>
Committed: Mon Nov 18 18:23:05 2013 -0500

----------------------------------------------------------------------
 .../main/decaf/lang/AbstractStringBuilder.cpp   |  331 ++++-
 .../src/main/decaf/lang/AbstractStringBuilder.h |  171 ++-
 activemq-cpp/src/main/decaf/lang/String.cpp     |   12 +-
 activemq-cpp/src/main/decaf/lang/String.h       |    3 +-
 .../src/main/decaf/lang/StringBuffer.cpp        |  416 ++++++
 activemq-cpp/src/main/decaf/lang/StringBuffer.h |  551 ++++++-
 .../src/main/decaf/lang/StringBuilder.cpp       |   98 +-
 .../src/main/decaf/lang/StringBuilder.h         |  360 ++++-
 .../src/test/decaf/lang/StringBufferTest.cpp    | 1375 +++++++++++++++++-
 .../src/test/decaf/lang/StringBufferTest.h      |   92 ++
 .../src/test/decaf/lang/StringBuilderTest.cpp   |  799 +++++++++-
 .../src/test/decaf/lang/StringBuilderTest.h     |   40 +
 12 files changed, 4207 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
index 8fd3329..2d520e0 100644
--- a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
+++ b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.cpp
@@ -91,7 +91,7 @@ namespace lang {
             int newCount;
             if (value.length() - length - 1 >= size) {
                 if (!shared) {
-                    // index == count case is no-op
+                    // index == impl->length case is no-op
                     System::arraycopy(value.get(), index, value.get(), index + size, length - index);
                     return;
                 }
@@ -102,12 +102,35 @@ namespace lang {
 
             ArrayPointer<char> newData(newCount);
             System::arraycopy(value.get(), 0, newData.get(), 0, index);
-            // index == count case is no-op
+            // index == impl->length case is no-op
             System::arraycopy(value.get(), index, newData.get(), index + size, length - index);
             value = newData;
             shared = false;
         }
 
+        void fixReversedMultibyte(char* string DECAF_UNUSED, int length DECAF_UNUSED) {
+
+            // TODO fix UTF-8 code points that were revered.
+//            char* left;
+//            char* right;
+//            char* right2;
+//            char temp;
+//
+//            // then scan all bytes and reverse each multibyte character
+//            for (scanl = scanr = str; temp = *scanr++;) {
+//                if ( (temp & 0x80) == 0) // ASCII char
+//                    scanl= scanr;
+//                else if ( (temp & 0xc0) == 0xc0 ) { // start of multibyte
+//                    scanr2= scanr;
+//                    switch (scanr - scanl) {
+//                        case 4: temp= *scanl, *scanl++= *--scanr, *scanr= temp; // fallthrough
+//                        case 3: // fallthrough
+//                        case 2: temp= *scanl, *scanl++= *--scanr, *scanr= temp;
+//                    }
+//                    scanr = scanl = scanr2;
+//                }
+//            }
+        }
     };
 
 }}
@@ -273,7 +296,7 @@ void AbstractStringBuilder::doAppend(const CharSequence* value, int start, int e
     int arrayLength = value->length();
 
     if ((start | end) < 0 || start > end || end > arrayLength) {
-        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid offset or length value given.");
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid start or end value given.");
     }
 
     int length = end - start;
@@ -308,25 +331,23 @@ void AbstractStringBuilder::doAppend(const String& value) {
     int length = value.length();
     int newLength = impl->length + length;
     impl->ensureCapacity(newLength);
-
-    for (int i = 0; i < length; ++i) {
-        impl->value[impl->length++] = value.charAt(i);
-    }
-
-    // TODO direct access: string._getChars(0, length, value, count);
-    // impl->length = newLength;
+    value.getChars(0, length, impl->value.get(), impl->length);
+    impl->length = newLength;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void AbstractStringBuilder::doAppend(const AbstractStringBuilder& value) {
 
+    if (value.length() > 0) {
+        doAppend(value.impl->value.get(), 0, value.impl->length);
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void AbstractStringBuilder::doDeleteRange(int start, int end) {
 
     // This method is specified not to throw if the end index is >= length(), as
-    // long as it's >= start. This means we have to clamp it to count here.
+    // long as it's >= start. This means we have to clamp it to impl->length here.
     if (end > impl->length) {
         end = impl->length;
     }
@@ -335,7 +356,7 @@ void AbstractStringBuilder::doDeleteRange(int start, int end) {
         throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid start index: %d", start);
     }
 
-    // This method is defined to throw only if start > count and start == count is a NO-OP
+    // This method is defined to throw only if start > impl->length and start == impl->length is a NO-OP
     // Since 'end' is already a clamped value, that case is handled here.
     if (end == start) {
         return;
@@ -367,6 +388,238 @@ void AbstractStringBuilder::doDeleteCharAt(int index) {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, char value) {
+    if (index < 0 || index > impl->length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Given index is invalid: %d", index);
+    }
+
+    impl->move(1, index);
+    impl->value[index] = value;
+    impl->length++;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const char* value) {
+
+    if (index < 0 || index > impl->length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Given index is invalid: %d", index);
+    }
+
+    if (value == NULL) {
+        throw NullPointerException(__FILE__, __LINE__, "C String pointer was NULL");
+    }
+
+    int arrayLength = StringUtils::stringLength(value);
+
+    if (arrayLength != 0) {
+        impl->move(arrayLength, index);
+        System::arraycopy(value, 0, impl->value.get(), index, arrayLength);
+        impl->length += arrayLength;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const String& value) {
+
+    if (index < 0 || index > impl->length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Given index is invalid: %d", index);
+    }
+
+    int stringLength = value.length();
+
+    if (stringLength != 0) {
+        impl->move(stringLength, index);
+        value.getChars(0, stringLength, impl->value.get(), index);
+        impl->length += stringLength;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const std::string& value) {
+
+    if (index < 0 || index > impl->length) {
+        throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Given index is invalid: %d", index);
+    }
+
+    int stringLength = (int) value.length();
+
+    if (stringLength != 0) {
+        impl->move(stringLength, index);
+
+        for (int i = 0; i < stringLength; ++i) {
+            impl->value[index++] = value.at(i);
+        }
+
+        impl->length += stringLength;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const char* value, int offset, int length) {
+
+    if (index >= 0 && index <= impl->length) {
+
+        if (value == NULL) {
+            throw NullPointerException(__FILE__, __LINE__, "C string pointer was NULL");
+        }
+
+        int arrayLength = StringUtils::stringLength(value);
+
+        // start + length could overflow, start/length maybe MaxInt
+        if (offset >= 0 && length >= 0 && length <= arrayLength - offset) {
+            if (length != 0) {
+                impl->move(length, index);
+                System::arraycopy(value, offset, impl->value.get(), index, length);
+                impl->length += length;
+            }
+            return;
+        }
+
+        throw StringIndexOutOfBoundsException(__FILE__, __LINE__,
+                "Invalid string offsets, offset=%d length=%d but C string length=%d",
+                offset, length, arrayLength);
+    }
+
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Index value given was invalid: %d", index);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const CharSequence* value) {
+
+    if (index >= 0 && index <= impl->length) {
+
+        if (value == NULL) {
+            throw NullPointerException(__FILE__, __LINE__, "CharSequence pointer was NULL");
+        }
+
+        doInsert(index, value->toString());
+        return;
+    }
+
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Index value given was invalid: %d", index);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doInsert(int index, const CharSequence* value, int start, int end) {
+
+    if (value == NULL) {
+        String nullString("null");
+        doInsert(index, nullString.c_str(), start, end - start);
+        return;
+    }
+
+    if (index >= 0 && index <= impl->length) {
+
+        int arrayLength = value->length();
+
+        if ((start | end) < 0 || start > end || end > arrayLength) {
+            throw ArrayIndexOutOfBoundsException(__FILE__, __LINE__, "Invalid start or end value given.");
+        }
+
+        int length = end - start;
+
+        if (length == 0) {
+            return;
+        }
+
+        impl->move(length, index);
+
+        for (int i = start; i < end; ++i) {
+            impl->value[index++] = value->charAt(i);
+        }
+
+        impl->length += length;
+        return;
+    }
+
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Index value given was invalid: %d", index);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doReplace(int start, int end, const String& value) {
+
+    if (start >= 0) {
+        if (end > impl->length) {
+            end = impl->length;
+        }
+        if (end > start) {
+            int stringLength = value.length();
+            int diff = end - start - stringLength;
+            if (diff > 0) { // replacing with fewer characters
+                if (!impl->shared) {
+                    // index == impl->length case is no-op
+                    System::arraycopy(impl->value.get(), end, impl->value.get(),
+                                      start + stringLength, impl->length - end);
+                } else {
+                    ArrayPointer<char> newData(impl->value.length());
+                    System::arraycopy(impl->value.get(), 0, newData.get(), 0, start);
+                    // index == impl->length case is no-op
+                    System::arraycopy(impl->value.get(), end, newData.get(),
+                                      start + stringLength, impl->length - end);
+                    impl->value = newData;
+                    impl->shared = false;
+                }
+            } else if (diff < 0) {
+                // replacing with more characters...need some room
+                impl->move(-diff, end);
+            } else if (impl->shared) {
+                impl->value = impl->value.clone();
+                impl->shared = false;
+            }
+
+            value.getChars(0, stringLength, impl->value.get(), start);
+            impl->length -= diff;
+            return;
+        }
+
+        if (start == end) {
+            doInsert(start, value);
+            return;
+        }
+    }
+
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__, "Index value given was invalid: %d", start);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractStringBuilder::doReverse() {
+
+    if (impl->length < 2) {
+        return;
+    }
+
+    if (!impl->shared) {
+
+        char* original = impl->value.get();
+        char* left;
+        char* right;
+        char temp;
+
+        // Reverse from shared buffer to newly allocated buffer.
+        for (left = original, right = original + impl->length; left < right;) {
+            temp = *left;
+            *(left++) = *(--right),
+            *right = temp;
+        }
+
+        impl->fixReversedMultibyte(original, impl->length);
+
+    } else {
+
+        // Reverse from shared buffer to newly allocated buffer.
+        ArrayPointer<char> newData(impl->value.length());
+        for (int i = 0; i < impl->length; i++) {
+            newData[impl->length - i] = impl->value[i];
+        }
+
+        impl->fixReversedMultibyte(newData.get(), impl->length);
+
+        impl->value = newData;
+        impl->shared = false;
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
 int AbstractStringBuilder::capacity() const {
     return impl->capacity();
 }
@@ -442,7 +695,7 @@ int AbstractStringBuilder::indexOf(const String& value, int start) const {
                 }
             }
             if (!found || subCount + i > impl->length) {
-                return -1; // handles subCount > count || start >= count
+                return -1; // handles subCount > impl->length || start >= impl->length
             }
 
             int o1 = i;
@@ -471,7 +724,7 @@ int AbstractStringBuilder::lastIndexOf(const String& value, int start) const {
     if (subCount <= impl->length && start >= 0) {
         if (subCount > 0) {
             if (start > impl->length - subCount) {
-                start = impl->length - subCount; // count and subCount are both >= 1
+                start = impl->length - subCount; // impl->length and subCount are both >= 1
             }
 
             char firstChar = value.charAt(0);
@@ -524,9 +777,7 @@ void AbstractStringBuilder::setCharAt(int index, char value) {
     }
 
     if (impl->shared) {
-        ArrayPointer<char> newValue(impl->value.length());
-        System::arraycopy(impl->value.get(), 0, newValue.get(), 0, impl->length);
-        impl->value = newValue;
+        impl->value = impl->value.clone();
         impl->shared = false;
     }
 
@@ -558,8 +809,54 @@ void AbstractStringBuilder::setLength(int length) {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+String AbstractStringBuilder::substring(int start) const {
+
+    if (start >= 0 && start <= impl->length) {
+        if (start == impl->length) {
+            return "";
+        }
+
+        // Remove String sharing for more performance
+        return String(impl->value.get(), start, impl->length - start);
+    }
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__, start);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+String AbstractStringBuilder::substring(int start, int end) const {
+
+    if (start >= 0 && start <= end && end <= impl->length) {
+        if (start == end) {
+            return "";
+        }
+
+        // Remove String sharing for more performance
+        return String(impl->value.get(), start, end - start);
+    }
+
+    throw StringIndexOutOfBoundsException(__FILE__, __LINE__,
+        "Start [%d] or end [%d] index value are invalid.", start, end);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+CharSequence* AbstractStringBuilder::subSequence(int start, int end) const {
+    return new String(substring(start, end));
+}
+
+////////////////////////////////////////////////////////////////////////////////
 String AbstractStringBuilder::toString() const {
 
+    if (impl->length == 0) {
+        return "";
+    }
+
+    int wasted = impl->value.length() - 1 - impl->length;
+    if (wasted >= 256 || (wasted >= INITIAL_CAPACITY && wasted >= (impl->length >> 1))) {
+        return String(impl->value.get(), 0, impl->length);
+    }
+
+    impl->shared = true;
+
     // TODO optimize so that internal data can be shared with the returned String
     //      and discarded only after a new mutating method call is made.
     //      ensure the shared flag is set once we do this.

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
index 6ab194e..34c4cee 100644
--- a/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
+++ b/activemq-cpp/src/main/decaf/lang/AbstractStringBuilder.h
@@ -201,6 +201,58 @@ namespace lang {
         virtual void setCharAt(int index, char value);
 
         /**
+         * Returns a new String that contains a subset of the characters currently contained
+         * in this character buffer. The substring starts at the specified index and extends
+         * to the end of this character buffer.
+         *
+         * @param start
+         *      The starting index of the substring to create.
+         *
+         * @returns a new String that is a subset of this character buffer.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if start is less than zero, or greater than the length of this buffer.
+         */
+        virtual String substring(int start) const;
+
+        /**
+         * Returns a new String that contains a subset of the characters currently contained
+         * in this character buffer. The substring starts at the specified index and extends
+         * to the given end index.
+         *
+         * @param start
+         *      The starting index of the substring to create. (inclusive)
+         * @param end
+         *      The ending index of the substring to create. (exclusive)
+         *
+         * @returns a new String that is a subset of this character buffer.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if start or end is less than zero, or end is greater than the length of this buffer
+         *      or start is greater than end.
+         */
+        virtual String substring(int start, int end) const;
+
+        /**
+         * Creates and returns a new CharSequence object that is a subset of the characters
+         * contained in this character buffer.  This method behaves the same as the two parameter
+         * substring method except that it returns a pointer value instead of a String, this
+         * allows for subclasses to implement CharSequence.
+         *
+         * @param start
+         *      The starting index of the substring to create. (inclusive)
+         * @param end
+         *      The ending index of the substring to create. (exclusive)
+         *
+         * @returns a new CharSequence pointer that is a subset of this character buffer.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if start or end is less than zero, or end is greater than the length of this buffer
+         *      or start is greater than end.
+         */
+        virtual CharSequence* subSequence(int start, int end) const;
+
+        /**
          * Returns a String that represents the contents of this buffer.  Any changes
          * made to this buffer after calling this method will not be reflected in the
          * String value that is returned.
@@ -243,7 +295,7 @@ namespace lang {
 
         /**
          * Appends the given C string to this buffer starting at the given offset and
-         * ending after the length number of characters has been appened.
+         * ending after the length number of characters has been appended.
          *
          * @param value
          *      The C string value to be appended into this buffer.
@@ -270,7 +322,7 @@ namespace lang {
 
         /**
          * Appends the given CharSequence to this buffer starting at the given offset and
-         * ending after the length number of characters has been appened.
+         * ending after the length number of characters has been appended.
          *
          * @param value
          *      The CharSequence value to be appended into this buffer.
@@ -327,6 +379,121 @@ namespace lang {
          */
         void doDeleteCharAt(int index);
 
+        /**
+         * Inserts a single char value at the given index
+         *
+         * @param index
+         *      The index to insert the char at
+         * @param value
+         *      The char value to insert.
+         */
+        void doInsert(int index, char value);
+
+        /**
+         * Inserts a C string value at the given index.
+         *
+         * @param index
+         *      The index to insert the C string at
+         * @param value
+         *      The char value to insert.
+         */
+        void doInsert(int index, const char* value);
+
+        /**
+         * Inserts a String value at the given index.
+         *
+         * @param index
+         *      The index to insert the String at
+         * @param value
+         *      The char value to insert.
+         */
+        void doInsert(int index, const String& value);
+
+        /**
+         * Inserts a std::string value at the given index.
+         *
+         * @param index
+         *      The index to insert the std::string at
+         * @param value
+         *      The char value to insert.
+         */
+        void doInsert(int index, const std::string& value);
+
+        /**
+         * Inserts the given C string at the given index in this buffer starting at the
+         * given offset and ending after the length number of characters has been appended.
+         *
+         * @param index
+         *      The index in this buffer to start inserting the C string.
+         * @param value
+         *      The C string value to be appended into this buffer.
+         * @param offset
+         *      The starting position into the C string array.
+         * @param length
+         *      The number of characters to copy from the given array.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         * @throws IndexOutOfBoundsException if index, offset or length is negative or the value
+         *         of offset + length is greater than the strings length.
+         */
+        void doInsert(int index, const char* value, int offset, int length);
+
+        /**
+         * Inserts the given CharSequence at the given index in this buffer.
+         *
+         * @param index
+         *      The index in this buffer to start inserting the CharSequence.
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         * @throws IndexOutOfBoundsException if index is negative or greater than length().
+         */
+        void doInsert(int index, const CharSequence* value);
+
+        /**
+         * Inserts the given CharSequence at the given index in this buffer starting at the
+         * given index and ending at the specified end index.
+         *
+         * If the CharSequence pointer is NULL the string "null" is inserted.
+         *
+         * @param index
+         *      The index in this buffer to start inserting the CharSequence.
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         * @param start
+         *      The starting index into the CharSequence.
+         * @param end
+         *      The end index in the CharSequence to be inserted into this Buffer.
+         *
+         * @throws IndexOutOfBoundsException if index, start or end is negative or the value
+         *         of start < end or the end index is greater than the sequence length.
+         */
+        void doInsert(int index, const CharSequence* value, int start, int end);
+
+        /**
+         * Replace some number of characters in this Buffer with the value given.
+         *
+         * The characters replaced start at the given index and end at the given end value
+         * (exclusive).  If the replacement string value is longer the internal buffer is
+         * lengthened to accommodate the new value.
+         *
+         * @param start
+         *      The starting index to replace in the buffer (inclusive).
+         * @param end
+         *      The ending index of the replacement operation (exclusive).
+         * @param value
+         *      The new string value to replace the older value.
+         *
+         * @throws IndexOutOfBoundsException if start is negative, greater than end or greater than length().
+         */
+        void doReplace(int start, int end, const String& value);
+
+        /**
+         * Reverses the characters contained in this character buffer.
+         */
+        void doReverse();
+
     };
 
 }}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/String.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/String.cpp b/activemq-cpp/src/main/decaf/lang/String.cpp
index 7e173ac..d3fe4fb 100644
--- a/activemq-cpp/src/main/decaf/lang/String.cpp
+++ b/activemq-cpp/src/main/decaf/lang/String.cpp
@@ -81,8 +81,8 @@ String::String(Contents* content) :
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-String::String(int offset, int length, Contents* content) :
-    contents(new Contents(offset, length, content->value)) {
+String::String(int offset, int length, const ArrayPointer<char> content) :
+    contents(new Contents(offset, length, content)) {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -831,7 +831,7 @@ int String::findFirstNotOf(const String& chars, int start) const {
 ////////////////////////////////////////////////////////////////////////////////
 void String::getChars(int srcBegin, int srcEnd, char* dest, int destSize, int destBegin) const {
 
-    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd >= contents->length) {
+    if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > contents->length) {
         throw StringIndexOutOfBoundsException(__FILE__, __LINE__,
             "Invalid start or end parameters: %d, %d", srcBegin, srcEnd);
     }
@@ -1304,7 +1304,7 @@ String String::substring(int start) const {
     }
 
     if (0 <= start && start <= contents->length) {
-        return String(contents->offset + start, contents->length - start, contents);
+        return String(contents->offset + start, contents->length - start, contents->value);
     }
 
     throw StringIndexOutOfBoundsException(__FILE__, __LINE__, start);
@@ -1326,7 +1326,7 @@ String String::substring(int start, int end) const {
     }
 
     // NOTE last character not copied!
-    return String(contents->offset + start, end - start, contents);
+    return String(contents->offset + start, end - start, contents->value);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1417,7 +1417,7 @@ String String::trim() const {
         return *this;
     }
 
-    return String(start, end - start + 1, contents);
+    return String(start, end - start + 1, contents->value);
 }
 
 ////////////////////////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/String.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/String.h b/activemq-cpp/src/main/decaf/lang/String.h
index 694ce30..d2c3adf 100644
--- a/activemq-cpp/src/main/decaf/lang/String.h
+++ b/activemq-cpp/src/main/decaf/lang/String.h
@@ -22,6 +22,7 @@
 
 #include <decaf/lang/CharSequence.h>
 #include <decaf/lang/Comparable.h>
+#include <decaf/lang/ArrayPointer.h>
 
 #include <string>
 #include <ostream>
@@ -1145,7 +1146,7 @@ namespace lang {
         void getChars(int start, int end, char* buffer, int index) const;
 
         String(Contents* content);
-        String(int offset, int length, Contents* content);
+        String(int offset, int length, const ArrayPointer<char> content);
 
         friend class AbstractStringBuilder;
     };

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp b/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
index 9419a10..bdd15ac 100644
--- a/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
+++ b/activemq-cpp/src/main/decaf/lang/StringBuffer.cpp
@@ -20,6 +20,13 @@
 #include <decaf/lang/exceptions/NegativeArraySizeException.h>
 #include <decaf/lang/exceptions/NullPointerException.h>
 
+#include <decaf/lang/StringBuilder.h>
+#include <decaf/lang/Short.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/Long.h>
+#include <decaf/lang/Float.h>
+#include <decaf/lang/Double.h>
+
 using namespace decaf;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
@@ -54,3 +61,412 @@ int StringBuffer::capacity() const {
 
     return capacity;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+char StringBuffer::charAt(int index) const {
+
+    char result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::charAt(index);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuffer::ensureCapacity(int minCapacity) {
+    synchronized(&this->mutex) {
+        AbstractStringBuilder::ensureCapacity(minCapacity);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuffer::getChars(int start, int end, char* dst, int dstSize, int dstStart) const {
+    synchronized(&this->mutex) {
+        AbstractStringBuilder::getChars(start, end, dst, dstSize, dstStart);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::indexOf(const String& value) const {
+
+    int result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::indexOf(value);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::indexOf(const String& value, int start) const {
+
+    int result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::indexOf(value, start);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::lastIndexOf(const String& value) const {
+
+    int result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::lastIndexOf(value);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::lastIndexOf(const String& value, int start) const {
+
+    int result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::lastIndexOf(value, start);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int StringBuffer::length() const {
+
+    int result = 0;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::length();
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuffer::setLength(int length) {
+    synchronized(&this->mutex) {
+        AbstractStringBuilder::setLength(length);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuffer::setCharAt(int index, char value) {
+    synchronized(&this->mutex) {
+        AbstractStringBuilder::setCharAt(index, value);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+String StringBuffer::substring(int start) const {
+
+    String result;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::substring(start);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+String StringBuffer::substring(int start, int end) const {
+
+    String result;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::substring(start, end);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+CharSequence* StringBuffer::subSequence(int start, int end) const {
+
+    CharSequence* result = NULL;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::subSequence(start, end);
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+String StringBuffer::toString() const {
+
+    String result;
+
+    synchronized(&this->mutex) {
+        result = AbstractStringBuilder::toString();
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuffer::trimToSize() {
+    synchronized(&this->mutex) {
+        AbstractStringBuilder::trimToSize();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(bool value) {
+    synchronized(&this->mutex) {
+        doAppend(value ? "true" : "false");
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(char value) {
+    synchronized(&this->mutex) {
+        doAppend(value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(short value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    synchronized(&this->mutex) {
+        doAppend(Short::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(int value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    synchronized(&this->mutex) {
+        doAppend(Integer::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(long long value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    synchronized(&this->mutex) {
+        doAppend(Long::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(float value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    synchronized(&this->mutex) {
+        doAppend(Float::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(double value) {
+    // TODO optimize this for direct buffer access and no temporaries.
+    synchronized(&this->mutex) {
+        doAppend(Double::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const char* value) {
+    synchronized(&this->mutex) {
+        doAppend(value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const char* value, int offset, int length) {
+    synchronized(&this->mutex) {
+        doAppend(value, offset, length);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const CharSequence* value) {
+    synchronized(&this->mutex) {
+        if (value == NULL) {
+            doAppendNull();
+        } else {
+            doAppend(value);
+        }
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const CharSequence* value, int offset, int length) {
+    synchronized(&this->mutex) {
+        doAppend(value, offset, length);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const String& value) {
+    synchronized(&this->mutex) {
+        doAppend(value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::append(const StringBuilder& value) {
+    synchronized(&this->mutex) {
+        doAppend(value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::deleteRange(int start, int end) {
+    synchronized(&this->mutex) {
+        doDeleteRange(start, end);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::deleteCharAt(int index) {
+    synchronized(&this->mutex) {
+        doDeleteCharAt(index);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, char value) {
+    synchronized(&this->mutex) {
+        doInsert(index, value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, bool value) {
+    synchronized(&this->mutex) {
+        doInsert(index, (value ? "true" : "false"));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, short value) {
+    synchronized(&this->mutex) {
+        doInsert(index, Short::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, int value) {
+    synchronized(&this->mutex) {
+        doInsert(index, Integer::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, long long value) {
+    synchronized(&this->mutex) {
+        doInsert(index, Long::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, float value) {
+    synchronized(&this->mutex) {
+        doInsert(index, Float::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, double value) {
+    synchronized(&this->mutex) {
+        doInsert(index, Double::toString(value));
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const char* value) {
+    synchronized(&this->mutex) {
+        doInsert(index, value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const String& value) {
+    synchronized(&this->mutex) {
+        doInsert(index, value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const std::string& value) {
+    synchronized(&this->mutex) {
+        doInsert(index, value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const char* value, int offset, int length) {
+    synchronized(&this->mutex) {
+        doInsert(index, value, offset, length);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const CharSequence* value) {
+
+    synchronized(&this->mutex) {
+        if (value == NULL) {
+            doAppendNull();
+        } else {
+            doInsert(index, value);
+        }
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::insert(int index, const CharSequence* value, int offset, int length) {
+    synchronized(&this->mutex) {
+        doInsert(index, value, offset, length);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::replace(int start, int end, const String& value) {
+    synchronized(&this->mutex) {
+        doReplace(start, end, value);
+    }
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuffer& StringBuffer::reverse() {
+    synchronized(&this->mutex) {
+        doReverse();
+    }
+    return *this;
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/StringBuffer.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuffer.h b/activemq-cpp/src/main/decaf/lang/StringBuffer.h
index f779d5d..30789b3 100644
--- a/activemq-cpp/src/main/decaf/lang/StringBuffer.h
+++ b/activemq-cpp/src/main/decaf/lang/StringBuffer.h
@@ -23,11 +23,14 @@
 #include <decaf/lang/String.h>
 #include <decaf/lang/CharSequence.h>
 #include <decaf/lang/Appendable.h>
+#include <decaf/lang/Pointer.h>
 #include <decaf/util/concurrent/Mutex.h>
 
 namespace decaf {
 namespace lang {
 
+    class StringBuilder;
+
     /**
      * StringBuffer is a variable size contiguous indexable array of characters. The
      * length of the StringBuffer is the number of characters it contains. The capacity
@@ -47,7 +50,7 @@ namespace lang {
      * the method calls made by each of the individual threads involved.
      *
      * @see String
-     * @see StringBuilder
+     * @see StringBuffer
      *
      * @since 1.0
      */
@@ -97,6 +100,552 @@ namespace lang {
 
         virtual int capacity() const;
 
+        virtual char charAt(int index) const;
+
+        virtual void ensureCapacity(int minCapacity);
+
+        virtual void getChars(int start, int end, char* dst, int dstSize, int dstStart) const;
+
+        virtual int indexOf(const String& value) const;
+
+        virtual int indexOf(const String& value, int start) const;
+
+        virtual int lastIndexOf(const String& value) const;
+
+        virtual int lastIndexOf(const String& value, int start) const;
+
+        virtual int length() const;
+
+        virtual void setLength(int length);
+
+        virtual void setCharAt(int index, char value);
+
+        virtual String substring(int start) const;
+
+        virtual String substring(int start, int end) const;
+
+        virtual CharSequence* subSequence(int start, int end) const;
+
+        virtual String toString() const;
+
+        virtual void trimToSize();
+
+    public:
+
+        /**
+         * Appends the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is appended to this StringBuffer.
+         *
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        template<typename POINTER>
+        StringBuffer& append(const POINTER* pointer) {
+
+            if (pointer == NULL) {
+                doAppendNull();
+            } else {
+                doAppend(pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Appends the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is appended to this StringBuffer.
+         *
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        template<typename TYPE>
+        StringBuffer& append(const Pointer<TYPE> pointer) {
+
+            if (pointer == NULL) {
+                doAppendNull();
+            } else {
+                doAppend(pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Appends the string representation of the given boolean value.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(bool value);
+
+        /**
+         * Appends the given char value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(char value);
+
+        /**
+         * Appends the given short value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(short value);
+
+        /**
+         * Appends the given int value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(int value);
+
+        /**
+         * Appends the given long long value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(long long value);
+
+        /**
+         * Appends the given float value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(float value);
+
+        /**
+         * Appends the given double value into the internal char buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(double value);
+
+        /**
+         * Appends the contents of the given C string into this buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(const char* value);
+
+        /**
+         * Appends the given subsequence of the given C string into this buffer.
+         *
+         * @param value
+         *      The C string value to be appended into this buffer.
+         * @param offset
+         *      The starting position into the C string array.
+         * @param length
+         *      The number of characters to copy from the given array.
+         *
+         * @throws NullPointerException if the pointer is NULL.
+         * @throws IndexOutOfBoundsException if offset or length is negative or the value of
+         *         offset + length is greater than the strings length.
+         */
+        StringBuffer& append(const char* value, int offset, int length);
+
+        /**
+         * Appends the contents of the CharSequence into this buffer, if the CharSequence
+         * pointer is NULL then this method appends the string "null" to this Buffer.
+         *
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(const CharSequence* value);
+
+        /**
+         * Appends the given CharSequence to this buffer starting at the given offset and
+         * ending after the length number of characters has been append.  If the given
+         * CharSequence pointer is NULL then this method appends the string "null".
+         *
+         * @param value
+         *      The CharSequence value to be appended into this buffer.
+         * @param offset
+         *      The starting position into the CharSequence.
+         * @param length
+         *      The number of characters to copy from the given CharSequence.
+         *
+         * @throws IndexOutOfBoundsException if offset or length is negative or the value of
+         *         offset + length is greater than the strings length.
+         */
+        StringBuffer& append(const CharSequence* value, int offset, int length);
+
+        /**
+         * Appends the contents of the String into this buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(const String& value);
+
+        /**
+         * Appends the contents of the StringBuffer into this buffer.
+         *
+         * @param value
+         *      The value to append to the contents of the StringBuffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& append(const StringBuilder& value);
+
+        /**
+         * Removes the characters in a substring of this buffer. The substring begins at
+         * the specified start and extends to the character at index end - 1 or to the
+         * end of the sequence if end is greater than the current length() value. If
+         * start is equal to end, no changes are made.
+         *
+         * @param start
+         *      The starting index to delete from this buffer.
+         * @param end
+         *      The ending index (exclusive) to delete from this buffer.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if start is negative, greater than length(), or greater than end.
+         */
+        StringBuffer& deleteRange(int start, int end);
+
+        /**
+         * Deletes the char at the specified position in this buffer, length decreases by one.
+         *
+         * @param index
+         *      The index in this buffer where the character to delete is located.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws StringIndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& deleteCharAt(int index);
+
+        /**
+         * Inserts the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is inserted to this StringBuffer.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        template<typename POINTER>
+        StringBuffer& insert(int index, const POINTER* pointer) {
+
+            if (pointer == NULL) {
+                doInsert(index, "null");
+            } else {
+                doInsert(index, pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Inserts the string representation of the given object pointer.  If the pointer
+         * is NULL then the value "null" is inserted to this StringBuffer.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param pointer
+         *      A pointer to some object that must define a toString method.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        template<typename TYPE>
+        StringBuffer& insert(int index, const Pointer<TYPE> pointer) {
+
+            if (pointer == NULL) {
+                doInsert(index, "null");
+            } else {
+                doInsert(index, pointer->toString());
+            }
+
+            return *this;
+        }
+
+        /**
+         * Inserts the given char into the character buffer at the given index.  The contents
+         * of the buffer are shifted up by one from the given index prior to insertion.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, char value);
+
+        /**
+         * Inserts the given boolean into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(bool).
+         *
+         * @param index
+         *      The position in the buffer to insert the boolean value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, bool value);
+
+        /**
+         * Inserts the given short into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(short).
+         *
+         * @param index
+         *      The position in the buffer to insert the short value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, short value);
+
+        /**
+         * Inserts the given int into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(int).
+         *
+         * @param index
+         *      The position in the buffer to insert the int value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, int value);
+
+        /**
+         * Inserts the given long long into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(long long).
+         *
+         * @param index
+         *      The position in the buffer to insert the long long value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, long long value);
+
+        /**
+         * Inserts the given float into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(float).
+         *
+         * @param index
+         *      The position in the buffer to insert the float value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, float value);
+
+        /**
+         * Inserts the given double into the character buffer at the given index.  The value
+         * is converted to a String in the same fashion as calling String::valueOf(double).
+         *
+         * @param index
+         *      The position in the buffer to insert the double value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, double value);
+
+        /**
+         * Inserts the given C string into the character buffer at the given index.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws NullPointerException if the target C string pointer is NULL.
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, const char* value);
+
+        /**
+         * Inserts the given String into the character buffer at the given index.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws NullPointerException if the target C string pointer is NULL.
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, const String& value);
+
+        /**
+         * Inserts the given std::string into the character buffer at the given index.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws NullPointerException if the target std::string pointer is NULL.
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, const std::string& value);
+
+        /**
+         * Inserts the given C string into the character buffer at the given index starting
+         * from the given offset into the string and copying up to length chars from the string
+         * into this buffer.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         * @param offset
+         *      The offset into the C string to start the copy from.
+         * @param length
+         *      The number of characters to copy from the given C string.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws NullPointerException if the target C string pointer is NULL.
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         *      If offset or length is negative or offset > the string length + length.
+         */
+        StringBuffer& insert(int index, const char* value, int offset, int length);
+
+        /**
+         * Inserts the given CharSequence into the character buffer at the given index starting
+         * from the given offset into the string and copying up to length chars from the string
+         * into this buffer.  If the CharSequence pointer is NULL then this method inserts the
+         * string "null" into this Buffer.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuffer& insert(int index, const CharSequence* value);
+
+        /**
+         * Inserts the given CharSequence into the character buffer at the given index starting
+         * from the given offset into the string and copying up to length chars from the string
+         * into this buffer.  If the CharSequence pointer is NULL then this method inserts the
+         * string "null" into this Buffer.
+         *
+         * @param index
+         *      The position in the buffer to insert the char value.
+         * @param value
+         *      The value to insert at the given index.
+         * @param offset
+         *      The offset into the CharSequence to start the copy from.
+         * @param length
+         *      The number of characters to copy from the given CharSequence.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         *      If offset or length is negative or offset > the string length + length.
+         */
+        StringBuffer& insert(int index, const CharSequence* value, int offset, int length);
+
+        /**
+         * Replace some number of characters in this Buffer with the value given.
+         *
+         * The characters replaced start at the given index and end at the given end value
+         * (exclusive).  If the replacement string value is longer the internal buffer is
+         * lengthened to accommodate the new value.
+         *
+         * @param start
+         *      The starting index to replace in the buffer (inclusive).
+         * @param end
+         *      The ending index of the replacement operation (exclusive).
+         * @param value
+         *      The new string value to replace the older value.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException if start is negative, greater than end or greater than length().
+         */
+        StringBuffer& replace(int start, int end, const String& value);
+
+        /**
+         * Reverses the order of characters in this builder.
+         *
+         * @returns a reference to this StringBuffer so that operations can be chained.
+         */
+        StringBuffer& reverse();
+
     };
 
 }}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp b/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
index 3ea67b8..49e6451 100644
--- a/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
+++ b/activemq-cpp/src/main/decaf/lang/StringBuilder.cpp
@@ -134,7 +134,7 @@ StringBuilder& StringBuilder::append(const String& value) {
 
 ////////////////////////////////////////////////////////////////////////////////
 StringBuilder& StringBuilder::append(const StringBuffer& value) {
-    // TODO doAppend(value);
+    doAppend(value);
     return *this;
 }
 
@@ -149,3 +149,99 @@ StringBuilder& StringBuilder::deleteCharAt(int index) {
     doDeleteCharAt(index);
     return *this;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, char value) {
+    doInsert(index, value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, bool value) {
+    doInsert(index, (value ? "true" : "false"));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, short value) {
+    doInsert(index, Short::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, int value) {
+    doInsert(index, Integer::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, long long value) {
+    doInsert(index, Long::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, float value) {
+    doInsert(index, Float::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, double value) {
+    doInsert(index, Double::toString(value));
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const char* value) {
+    doInsert(index, value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const String& value) {
+    doInsert(index, value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const std::string& value) {
+    doInsert(index, value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const char* value, int offset, int length) {
+    doInsert(index, value, offset, length);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const CharSequence* value) {
+
+    if (value == NULL) {
+        doAppendNull();
+    } else {
+        doInsert(index, value);
+    }
+
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::insert(int index, const CharSequence* value, int offset, int length) {
+    doInsert(index, value, offset, length);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::replace(int start, int end, const String& value) {
+    doReplace(start, end, value);
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StringBuilder& StringBuilder::reverse() {
+    doReverse();
+    return *this;
+}