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:14 UTC

[1/3] Fully implemented StringBuilder and StringBuffer with buffer sharing to String.

Updated Branches:
  refs/heads/trunk 3cdc56180 -> c6e8f8fe6


http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
index 2c0307e..f315df9 100644
--- a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
+++ b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.cpp
@@ -25,6 +25,7 @@
 #include <decaf/lang/Long.h>
 #include <decaf/lang/Float.h>
 #include <decaf/lang/Double.h>
+#include <decaf/lang/Pointer.h>
 #include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
 #include <decaf/lang/exceptions/NegativeArraySizeException.h>
 #include <decaf/lang/exceptions/NullPointerException.h>
@@ -330,13 +331,12 @@ void StringBuilderTest::testAppendString() {
 ////////////////////////////////////////////////////////////////////////////////
 void StringBuilderTest::testAppendStringBuffer() {
 
-    // TODO
-//    StringBuilder sb;
-//    sb.append(StringBuffer("ab"));
-//    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
-//    sb.setLength(0);
-//    sb.append(StringBuffer("cd"));
-//    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    StringBuilder sb;
+    sb.append(StringBuffer("ab"));
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(StringBuffer("cd"));
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -576,6 +576,7 @@ void StringBuilderTest::testGetChars() {
         StringIndexOutOfBoundsException);
 
     delete [] dst;
+    delete [] fixtureChars;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -642,3 +643,787 @@ void StringBuilderTest::testLastIndexOfStringInt() {
     CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("02", 0));
     CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("89", 5));
 }
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    void reverseTest(const String& org, const String& rev, const String& back) {
+
+        // create non-shared StringBuilder
+        StringBuilder sb1(org);
+        sb1.reverse();
+        String reversed = sb1.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, reversed);
+
+        // create non-shared StringBuilder
+        StringBuilder sb2(reversed);
+        sb2.reverse();
+        reversed = sb2.toString();
+        CPPUNIT_ASSERT_EQUAL(back, reversed);
+
+        // test algorithm when StringBuilder is shared
+        StringBuilder sb3(org);
+        String copy = sb3.toString();
+        CPPUNIT_ASSERT_EQUAL(org, copy);
+        sb3.reverse();
+        reversed = sb3.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, reversed);
+        StringBuilder sb4(reversed);
+        copy = sb4.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, copy);
+        sb4.reverse();
+        reversed = sb4.toString();
+        CPPUNIT_ASSERT_EQUAL(back, reversed);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testReverse() {
+
+    String fixture = "0123456789";
+    StringBuilder sb1(fixture);
+    sb1.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("9876543210"), sb1.toString());
+
+    StringBuilder sb("012345678");
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("876543210"), sb.toString());
+    sb.setLength(1);
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("8"), sb.toString());
+    sb.setLength(0);
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+
+    String str;
+    str = "a";
+    reverseTest(str, str, str);
+
+    str = "ab";
+    reverseTest(str, "ba", str);
+
+    str = "abcdef";
+    reverseTest(str, "fedcba", str);
+
+    str = "abcdefg";
+    reverseTest(str, "gfedcba", str);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testSubSequence() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+    Pointer<CharSequence> ss(sb.subSequence(0, 5));
+    CPPUNIT_ASSERT_EQUAL(std::string("01234"), ss->toString());
+
+    ss.reset(sb.subSequence(0, 0));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), ss->toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(-1, 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(0, fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(0, -1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(3, 2),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testSubstringInt() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+    String ss = sb.substring(0);
+    CPPUNIT_ASSERT_EQUAL(fixture, ss);
+
+    ss = sb.substring(10);
+    CPPUNIT_ASSERT_EQUAL(String(""), ss);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(-1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, -1),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testSubstringIntInt() {
+
+    String fixture = "0123456789";
+    StringBuilder sb(fixture);
+    String ss = sb.substring(0, 5);
+    CPPUNIT_ASSERT_EQUAL(String("01234"), ss);
+
+    ss = sb.substring(0, 0);
+    CPPUNIT_ASSERT_EQUAL(String(), ss);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(-1, 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, -1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(3, 2),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertChar() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, 'a');
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("b0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("00b00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("0000b"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 'a'),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 'a'),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertBoolean() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, true);
+    CPPUNIT_ASSERT_EQUAL(String("true0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, false);
+    CPPUNIT_ASSERT_EQUAL(String("false0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, false);
+    CPPUNIT_ASSERT_EQUAL(String("00false00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, false);
+    CPPUNIT_ASSERT_EQUAL(String("0000false"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, false),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, false),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertCharArray() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.insert(0, (const char*) NULL),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, "Test"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, "Test"),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertCharArrayWithOffset() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00a00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("0000a"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.insert(0, (const char*) NULL, 0, 2),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, "ab", 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, "ab", 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", 0, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertString() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("fixture0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("00fixture00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("0000fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, String("fixture")),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, String("fixture")),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertStdString() {
+
+    std::string fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("fixture0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("00fixture00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("0000fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, std::string("fixture")),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, std::string("fixture")),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertCharSequence() {
+
+    String fixture = "0000";
+    String ab("ab");
+    StringBuilder sb(fixture);
+    sb.insert(0, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (CharSequence*) NULL);
+    CPPUNIT_ASSERT_EQUAL(String("0000null"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, &ab),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertCharSequenceIntInt() {
+
+    String fixture = "0000";
+    String ab("ab");
+    StringBuilder sb(fixture);
+    sb.insert(0, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00a00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("0000a"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (CharSequence*) NULL, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000nu"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, &ab, 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertDouble() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, -1.1);
+    CPPUNIT_ASSERT_EQUAL(String("-1.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0.1);
+    CPPUNIT_ASSERT_EQUAL(String("0.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1.1);
+    CPPUNIT_ASSERT_EQUAL(String("001.100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2.1);
+    CPPUNIT_ASSERT_EQUAL(String("00002.1"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1.0),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1.0),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertFloat() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, -1.1f);
+    CPPUNIT_ASSERT_EQUAL(String("-1.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0.1f);
+    CPPUNIT_ASSERT_EQUAL(String("0.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1.1f);
+    CPPUNIT_ASSERT_EQUAL(String("001.100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2.1f);
+    CPPUNIT_ASSERT_EQUAL(String("00002.1"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1.0f),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1.0f),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertShort() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, (short) -1);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, (short) 0);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, (short) 1);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (short) 2);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, (short) 1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, (short) 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertInt() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, -1);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertLong() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.insert(0, -1LL);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0LL);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1LL);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2LL);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1LL),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1LL),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertRawPointer() {
+
+    String fixture = "0000";
+    MyObject obj;
+    StringBuilder sb;
+    sb.insert(0, &obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1LL),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1LL),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testInsertPointer() {
+
+    String fixture = "0000";
+    Pointer<MyObject> obj(new MyObject);
+    StringBuilder sb;
+    sb.insert(0, obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, obj),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, obj),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBuilderTest::testReplace() {
+
+    String fixture = "0000";
+    StringBuilder sb(fixture);
+    sb.replace(1, 3, "11");
+    CPPUNIT_ASSERT_EQUAL(String("0110"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(4, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(1, 2, "11");
+    CPPUNIT_ASSERT_EQUAL(String("01100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(4, 5, "11");
+    CPPUNIT_ASSERT_EQUAL(String("000011"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(4, 6, "11");
+    CPPUNIT_ASSERT_EQUAL(String("000011"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.replace(1, 2, (const char*) NULL),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(-1, 2, "11"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(5, 2, "11"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(3, 2, "11"),
+        IndexOutOfBoundsException);
+
+    StringBuilder buffer("1234567");
+    buffer.replace(2, 6, "XXX");
+    CPPUNIT_ASSERT_EQUAL(String("12XXX7"), buffer.toString());
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
index f5e2444..d2094fe 100644
--- a/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
+++ b/activemq-cpp/src/test/decaf/lang/StringBuilderTest.h
@@ -56,6 +56,26 @@ namespace lang {
         CPPUNIT_TEST( testIndexOfStringInt );
         CPPUNIT_TEST( testLastIndexOfString );
         CPPUNIT_TEST( testLastIndexOfStringInt );
+        CPPUNIT_TEST( testReverse );
+        CPPUNIT_TEST( testSubSequence );
+        CPPUNIT_TEST( testSubstringInt );
+        CPPUNIT_TEST( testSubstringIntInt );
+        CPPUNIT_TEST( testInsertChar );
+        CPPUNIT_TEST( testInsertBoolean );
+        CPPUNIT_TEST( testInsertCharArray );
+        CPPUNIT_TEST( testInsertCharArrayWithOffset );
+        CPPUNIT_TEST( testInsertString );
+        CPPUNIT_TEST( testInsertStdString );
+        CPPUNIT_TEST( testInsertCharSequence );
+        CPPUNIT_TEST( testInsertCharSequenceIntInt );
+        CPPUNIT_TEST( testInsertShort );
+        CPPUNIT_TEST( testInsertInt );
+        CPPUNIT_TEST( testInsertLong );
+        CPPUNIT_TEST( testInsertFloat );
+        CPPUNIT_TEST( testInsertDouble );
+        CPPUNIT_TEST( testInsertPointer );
+        CPPUNIT_TEST( testInsertRawPointer );
+        CPPUNIT_TEST( testReplace );
         CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -91,6 +111,26 @@ namespace lang {
         void testIndexOfStringInt();
         void testLastIndexOfString();
         void testLastIndexOfStringInt();
+        void testReverse();
+        void testSubSequence();
+        void testSubstringInt();
+        void testSubstringIntInt();
+        void testInsertChar();
+        void testInsertBoolean();
+        void testInsertCharArray();
+        void testInsertCharArrayWithOffset();
+        void testInsertString();
+        void testInsertStdString();
+        void testInsertCharSequence();
+        void testInsertCharSequenceIntInt();
+        void testInsertShort();
+        void testInsertInt();
+        void testInsertLong();
+        void testInsertFloat();
+        void testInsertDouble();
+        void testInsertPointer();
+        void testInsertRawPointer();
+        void testReplace();
 
     };
 


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

Posted by ta...@apache.org.
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;
+}


[2/3] Fully implemented StringBuilder and StringBuffer with buffer sharing to String.

Posted by ta...@apache.org.
http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/main/decaf/lang/StringBuilder.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/main/decaf/lang/StringBuilder.h b/activemq-cpp/src/main/decaf/lang/StringBuilder.h
index 1a9428e..d98b026 100644
--- a/activemq-cpp/src/main/decaf/lang/StringBuilder.h
+++ b/activemq-cpp/src/main/decaf/lang/StringBuilder.h
@@ -137,6 +137,9 @@ namespace lang {
         /**
          * Appends the string representation of the given boolean value.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(bool value);
@@ -144,6 +147,9 @@ namespace lang {
         /**
          * Appends the given char value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(char value);
@@ -151,6 +157,9 @@ namespace lang {
         /**
          * Appends the given short value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(short value);
@@ -158,6 +167,9 @@ namespace lang {
         /**
          * Appends the given int value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(int value);
@@ -165,6 +177,9 @@ namespace lang {
         /**
          * Appends the given long long value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(long long value);
@@ -172,6 +187,9 @@ namespace lang {
         /**
          * Appends the given float value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(float value);
@@ -179,6 +197,9 @@ namespace lang {
         /**
          * Appends the given double value into the internal char buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(double value);
@@ -186,6 +207,9 @@ namespace lang {
         /**
          * Appends the contents of the given C string into this buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(const char* value);
@@ -193,27 +217,53 @@ namespace lang {
         /**
          * Appends the given subsequence of the given C string into this buffer.
          *
-         * @returns a reference to this StringBuilder so that operations can be chained.
+         * @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.
          */
         StringBuilder& append(const char* value, int offset, int length);
 
         /**
-         * Appends the contents of the CharSequence into this buffer.
+         * 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 StringBuilder so that operations can be chained.
          */
         StringBuilder& append(const CharSequence* value);
 
         /**
-         * Appends the given subsequence of the given CharSequence into this buffer.
+         * 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".
          *
-         * @returns a reference to this StringBuilder so that operations can be chained.
+         * @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.
          */
         StringBuilder& 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 StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(const String& value);
@@ -221,6 +271,9 @@ namespace lang {
         /**
          * Appends the contents of the StringBuffer into this buffer.
          *
+         * @param value
+         *      The value to append to the contents of the StringBuilder.
+         *
          * @returns a reference to this StringBuilder so that operations can be chained.
          */
         StringBuilder& append(const StringBuffer& value);
@@ -249,11 +302,310 @@ namespace lang {
          * @param index
          *      The index in this buffer where the character to delete is located.
          *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         *
          * @throws StringIndexOutOfBoundsException
          *      if the index is negative or greater than or equal to length().
          */
         StringBuilder& 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 StringBuilder.
+         *
+         * @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 StringBuilder so that operations can be chained.
+         */
+        template<typename POINTER>
+        StringBuilder& 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 StringBuilder.
+         *
+         * @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 StringBuilder so that operations can be chained.
+         */
+        template<typename TYPE>
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder 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().
+         */
+        StringBuilder& 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 StringBuilder 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().
+         */
+        StringBuilder& 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 StringBuilder 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().
+         */
+        StringBuilder& 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 StringBuilder 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.
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException
+         *      if the index is negative or greater than or equal to length().
+         */
+        StringBuilder& 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 StringBuilder 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.
+         */
+        StringBuilder& 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 StringBuilder so that operations can be chained.
+         *
+         * @throws IndexOutOfBoundsException if start is negative, greater than end or greater than length().
+         */
+        StringBuilder& replace(int start, int end, const String& value);
+
+        /**
+         * Reverses the order of characters in this builder.
+         *
+         * @returns a reference to this StringBuilder so that operations can be chained.
+         */
+        StringBuilder& reverse();
+
     };
 
 }}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp b/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
index e3411f5..f3a636b 100644
--- a/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
+++ b/activemq-cpp/src/test/decaf/lang/StringBufferTest.cpp
@@ -19,13 +19,22 @@
 
 #include <decaf/lang/String.h>
 #include <decaf/lang/StringBuffer.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>
+#include <decaf/lang/Pointer.h>
 #include <decaf/lang/exceptions/IndexOutOfBoundsException.h>
 #include <decaf/lang/exceptions/NegativeArraySizeException.h>
 #include <decaf/lang/exceptions/NullPointerException.h>
 #include <decaf/lang/exceptions/StringIndexOutOfBoundsException.h>
+#include <decaf/util/Arrays.h>
 
 using namespace std;
 using namespace decaf;
+using namespace decaf::util;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
 
@@ -39,8 +48,8 @@ StringBufferTest::~StringBufferTest() {
 
 ////////////////////////////////////////////////////////////////////////////////
 void StringBufferTest::testDefaultConstructor() {
-    StringBuffer buffer;
-    CPPUNIT_ASSERT_EQUAL(16, buffer.capacity());
+    StringBuffer builder;
+    CPPUNIT_ASSERT_EQUAL(16, builder.capacity());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,3 +65,1365 @@ void StringBufferTest::testConstructorInt() {
 
     CPPUNIT_ASSERT_NO_THROW(StringBuffer(0));
 }
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testConstructorString() {
+
+    StringBuffer sb("fixture");
+    CPPUNIT_ASSERT_EQUAL(String("fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(String("fixture").length() + 16, sb.capacity());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendBoolean() {
+
+    StringBuffer sb;
+    sb.append(true);
+    CPPUNIT_ASSERT_EQUAL(String("true"), sb.toString());
+    sb.setLength(0);
+    sb.append(false);
+    CPPUNIT_ASSERT_EQUAL(String("false"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendChar() {
+    StringBuffer sb;
+    sb.append('a');
+    CPPUNIT_ASSERT_EQUAL(String("a"), sb.toString());
+    sb.setLength(0);
+    sb.append('b');
+    CPPUNIT_ASSERT_EQUAL(String("b"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendCharArray() {
+
+    StringBuffer sb;
+    sb.append("ab");
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append("cd");
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.append((const char*) NULL),
+        NullPointerException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendCharArrayIntInt() {
+
+    StringBuffer sb;
+    sb.append("ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append("cd");
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 2, 2);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+
+    sb.setLength(0);
+    sb.append("abcd", 2, 0);
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.append((const char*) NULL, 0, 2),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.append("abcd", 2, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendCharSequence() {
+
+    String ab("ab");
+    String cd("cd");
+
+    StringBuffer sb;
+    sb.append(&ab);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&cd);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append((CharSequence*) NULL);
+    CPPUNIT_ASSERT_EQUAL(String("null"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendCharSequenceIntInt() {
+
+    String ab("ab");
+    String cd("cd");
+    String abcd("abcd");
+
+    StringBuffer sb;
+    sb.append(&ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&cd, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append(&abcd, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(&abcd, 2, 4);
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+    sb.setLength(0);
+    sb.append((CharSequence*) NULL, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("nu"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendShort() {
+
+    short a = 1;
+    short b = 0;
+    short c = -1;
+
+    StringBuffer sb;
+    sb.append(a);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(a), sb.toString());
+    sb.setLength(0);
+    sb.append(0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(b), sb.toString());
+    sb.setLength(0);
+    sb.append(c);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(c), sb.toString());
+    sb.setLength(0);
+    sb.append(Short::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Short::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Short::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Short::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendInt() {
+
+    int a = 1;
+    int b = 0;
+    int c = -1;
+
+    StringBuffer sb;
+    sb.append(a);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(a), sb.toString());
+    sb.setLength(0);
+    sb.append(0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(b), sb.toString());
+    sb.setLength(0);
+    sb.append(c);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(c), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendLong() {
+    StringBuffer sb;
+    sb.append(1LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1LL), sb.toString());
+    sb.setLength(0);
+    sb.append(0LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0LL), sb.toString());
+    sb.setLength(0);
+    sb.append(-1LL);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1LL), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Integer::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Integer::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendDouble() {
+    StringBuffer sb;
+    sb.append(1.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1.0), sb.toString());
+    sb.setLength(0);
+    sb.append(0.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0.0), sb.toString());
+    sb.setLength(0);
+    sb.append(-1.0);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1.0), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::NaN);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::NaN), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::NEGATIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::NEGATIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::POSITIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::POSITIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Double::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Double::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendFloat() {
+    StringBuffer sb;
+    sb.append(1.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(1.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(0.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(0.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(-1.0f);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(-1.0f), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::NaN);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::NaN), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::NEGATIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::NEGATIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::POSITIVE_INFINITY);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::POSITIVE_INFINITY), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::MIN_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::MIN_VALUE), sb.toString());
+    sb.setLength(0);
+    sb.append(Float::MAX_VALUE);
+    CPPUNIT_ASSERT_EQUAL(String::valueOf(Float::MAX_VALUE), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendString() {
+    StringBuffer sb;
+    sb.append(String("ab"));
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(String("cd"));
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendStringBuilder() {
+
+    StringBuffer sb;
+    sb.append(StringBuilder("ab"));
+    CPPUNIT_ASSERT_EQUAL(String("ab"), sb.toString());
+    sb.setLength(0);
+    sb.append(StringBuilder("cd"));
+    CPPUNIT_ASSERT_EQUAL(String("cd"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class MyObject {
+    public:
+
+        String toString() const {
+            return "MyObject";
+        }
+
+    };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendRawPointer() {
+
+    MyObject obj;
+    StringBuffer sb;
+    sb.append(&obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testAppendPointer() {
+
+    Pointer<MyObject> obj(new MyObject);
+    StringBuffer sb;
+    sb.append(obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testCapacity() {
+    StringBuffer sb;
+    CPPUNIT_ASSERT_EQUAL(16, sb.capacity());
+    sb.append("0123456789ABCDEF0123456789ABCDEF");
+    CPPUNIT_ASSERT(sb.capacity() > 16);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testCharAt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+
+    for (int i = 0; i < fixture.length(); i++) {
+        CPPUNIT_ASSERT_EQUAL((char) ('0' + i), sb.charAt(i));
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(-1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(fixture.length()),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.charAt(fixture.length() + 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testDeleteRange() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+
+    sb.deleteRange(0, 0);
+    CPPUNIT_ASSERT_EQUAL(fixture, sb.toString());
+    sb.deleteRange(5, 5);
+    CPPUNIT_ASSERT_EQUAL(fixture, sb.toString());
+    sb.deleteRange(0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("123456789"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.deleteRange(0, sb.length());
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(0, sb.length());
+
+    {
+        StringBuffer sb(fixture);
+        sb.deleteRange(0, 11);
+        CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(0, sb.length());
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteRange(-1, 2),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteRange(13, 12),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteRange(11, 12),
+        StringIndexOutOfBoundsException);
+
+    {
+        StringBuffer sb;
+        sb.append("abcde");
+        String str = sb.toString();
+        sb.deleteRange(0, sb.length());
+        sb.append("YY");
+        CPPUNIT_ASSERT_EQUAL(String("abcde"), str);
+        CPPUNIT_ASSERT_EQUAL(String("YY"), sb.toString());
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testDeleteCharAt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+
+    sb.deleteCharAt(0);
+    CPPUNIT_ASSERT_EQUAL(String("123456789"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    {
+        StringBuffer sb(fixture);
+        sb.deleteCharAt(5);
+        CPPUNIT_ASSERT_EQUAL(String("012346789"), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    }
+    {
+        StringBuffer sb(fixture);
+        sb.deleteCharAt(9);
+        CPPUNIT_ASSERT_EQUAL(String("012345678"), sb.toString());
+        CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteCharAt(-1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteCharAt(fixture.length()),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        StringBuffer(fixture).deleteCharAt(fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testEnsureCapacity() {
+
+    StringBuffer sb(5);
+    CPPUNIT_ASSERT_EQUAL(5, sb.capacity());
+    sb.ensureCapacity(10);
+    CPPUNIT_ASSERT_EQUAL(12, sb.capacity());
+    sb.ensureCapacity(26);
+    CPPUNIT_ASSERT_EQUAL(26, sb.capacity());
+    sb.ensureCapacity(55);
+    CPPUNIT_ASSERT_EQUAL(55, sb.capacity());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testGetChars() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    char* dst = new char[10];
+    sb.getChars(0, 10, dst, 10, 0);
+    for (int i = 0; i < 10; ++i) {
+        CPPUNIT_ASSERT_EQUAL(dst[i], fixture.charAt(i));
+    }
+
+    Arrays::fill(dst, 10, '\0');
+    sb.getChars(0, 5, dst, 10, 0);
+    char* fixtureChars = new char[10];
+    for (int i = 0; i < 5; ++i) {
+        CPPUNIT_ASSERT_EQUAL(dst[i], fixture.charAt(i));
+    }
+
+    Arrays::fill(dst, 10, '\0');
+    Arrays::fill(fixtureChars, 10, '\0');
+    sb.getChars(0, 5, dst, 10, 5);
+    fixture.getChars(0, 5, fixtureChars, 10, 5);
+    for (int i = 0; i < 10; ++i) {
+        CPPUNIT_ASSERT_EQUAL(dst[i], fixtureChars[i]);
+    }
+
+    Arrays::fill(dst, 10, '\0');
+    Arrays::fill(fixtureChars, 10, '\0');
+    sb.getChars(5, 10, dst, 10, 1);
+    fixture.getChars(5, 10, fixtureChars, 10, 1);
+    for (int i = 0; i < 10; ++i) {
+        CPPUNIT_ASSERT_EQUAL(dst[i], fixtureChars[i]);
+    }
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(0, 10, dst, -1, 0),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.getChars(0, 10, (char*) NULL, 10, 0),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(-1, 10, dst, 10, 0),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(0, 10, dst, 10, -1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(5, 4, dst, 10, 0),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(0, 11, dst, 10, 0),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.getChars(0, 10, dst, 10, 5),
+        StringIndexOutOfBoundsException);
+
+    delete [] dst;
+    delete [] fixtureChars;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testIndexOfString() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("0"));
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("012"));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("02"));
+    CPPUNIT_ASSERT_EQUAL(8, sb.indexOf("89"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testIndexOfStringInt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("0"));
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("012"));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("02"));
+    CPPUNIT_ASSERT_EQUAL(8, sb.indexOf("89"));
+
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("0", 0));
+    CPPUNIT_ASSERT_EQUAL(0, sb.indexOf("012", 0));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("02", 0));
+    CPPUNIT_ASSERT_EQUAL(8, sb.indexOf("89", 0));
+
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("0", 5));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("012", 5));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.indexOf("02", 0));
+    CPPUNIT_ASSERT_EQUAL(8, sb.indexOf("89", 5));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testLastIndexOfString() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("0"));
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("012"));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("02"));
+    CPPUNIT_ASSERT_EQUAL(8, sb.lastIndexOf("89"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testLastIndexOfStringInt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("0"));
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("012"));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("02"));
+    CPPUNIT_ASSERT_EQUAL(8, sb.lastIndexOf("89"));
+
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("0", 0));
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("012", 0));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("02", 0));
+    CPPUNIT_ASSERT_EQUAL(8, sb.lastIndexOf("89", 10));
+
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("0", 5));
+    CPPUNIT_ASSERT_EQUAL(0, sb.lastIndexOf("012", 5));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("02", 0));
+    CPPUNIT_ASSERT_EQUAL(-1, sb.lastIndexOf("89", 5));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    void reverseTest(const String& org, const String& rev, const String& back) {
+
+        // create non-shared StringBuffer
+        StringBuffer sb1(org);
+        sb1.reverse();
+        String reversed = sb1.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, reversed);
+
+        // create non-shared StringBuffer
+        StringBuffer sb2(reversed);
+        sb2.reverse();
+        reversed = sb2.toString();
+        CPPUNIT_ASSERT_EQUAL(back, reversed);
+
+        // test algorithm when StringBuffer is shared
+        StringBuffer sb3(org);
+        String copy = sb3.toString();
+        CPPUNIT_ASSERT_EQUAL(org, copy);
+        sb3.reverse();
+        reversed = sb3.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, reversed);
+        StringBuffer sb4(reversed);
+        copy = sb4.toString();
+        CPPUNIT_ASSERT_EQUAL(rev, copy);
+        sb4.reverse();
+        reversed = sb4.toString();
+        CPPUNIT_ASSERT_EQUAL(back, reversed);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testReverse() {
+
+    String fixture = "0123456789";
+    StringBuffer sb1(fixture);
+    sb1.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("9876543210"), sb1.toString());
+
+    StringBuffer sb("012345678");
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("876543210"), sb.toString());
+    sb.setLength(1);
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String("8"), sb.toString());
+    sb.setLength(0);
+    sb.reverse();
+    CPPUNIT_ASSERT_EQUAL(String(""), sb.toString());
+
+    String str;
+    str = "a";
+    reverseTest(str, str, str);
+
+    str = "ab";
+    reverseTest(str, "ba", str);
+
+    str = "abcdef";
+    reverseTest(str, "fedcba", str);
+
+    str = "abcdefg";
+    reverseTest(str, "gfedcba", str);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testSubSequence() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    Pointer<CharSequence> ss(sb.subSequence(0, 5));
+    CPPUNIT_ASSERT_EQUAL(std::string("01234"), ss->toString());
+
+    ss.reset(sb.subSequence(0, 0));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), ss->toString());
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(-1, 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(0, fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(0, -1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.subSequence(3, 2),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testSubstringInt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    String ss = sb.substring(0);
+    CPPUNIT_ASSERT_EQUAL(fixture, ss);
+
+    ss = sb.substring(10);
+    CPPUNIT_ASSERT_EQUAL(String(""), ss);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(-1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, -1),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testSubstringIntInt() {
+
+    String fixture = "0123456789";
+    StringBuffer sb(fixture);
+    String ss = sb.substring(0, 5);
+    CPPUNIT_ASSERT_EQUAL(String("01234"), ss);
+
+    ss = sb.substring(0, 0);
+    CPPUNIT_ASSERT_EQUAL(String(), ss);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(-1, 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, fixture.length() + 1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(0, -1),
+        StringIndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a StringIndexOutOfBoundsException",
+        sb.substring(3, 2),
+        StringIndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertChar() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, 'a');
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("b0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("00b00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 'b');
+    CPPUNIT_ASSERT_EQUAL(String("0000b"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 'a'),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 'a'),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertBoolean() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, true);
+    CPPUNIT_ASSERT_EQUAL(String("true0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, false);
+    CPPUNIT_ASSERT_EQUAL(String("false0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, false);
+    CPPUNIT_ASSERT_EQUAL(String("00false00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, false);
+    CPPUNIT_ASSERT_EQUAL(String("0000false"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(9, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, false),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, false),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertCharArray() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab");
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.insert(0, (const char*) NULL),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, "Test"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, "Test"),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertCharArrayWithOffset() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00a00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab", 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, "ab", 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("0000a"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.insert(0, (const char*) NULL, 0, 2),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, "ab", 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, "ab", 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(4, "ab", 0, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertString() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("fixture0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("00fixture00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, String("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("0000fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, String("fixture")),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, String("fixture")),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertStdString() {
+
+    std::string fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("fixture0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("00fixture00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, std::string("fixture"));
+    CPPUNIT_ASSERT_EQUAL(String("0000fixture"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(11, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, std::string("fixture")),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, std::string("fixture")),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertCharSequence() {
+
+    String fixture = "0000";
+    String ab("ab");
+    StringBuffer sb(fixture);
+    sb.insert(0, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (CharSequence*) NULL);
+    CPPUNIT_ASSERT_EQUAL(String("0000null"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, &ab),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertCharSequenceIntInt() {
+
+    String fixture = "0000";
+    String ab("ab");
+    StringBuffer sb(fixture);
+    sb.insert(0, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("ab0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("a0000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00ab00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00a00"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000ab"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, &ab, 0, 1);
+    CPPUNIT_ASSERT_EQUAL(String("0000a"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (CharSequence*) NULL, 0, 2);
+    CPPUNIT_ASSERT_EQUAL(String("0000nu"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, &ab, 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, -1, 2),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, -1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, &ab, 0, 3),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertDouble() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, -1.1);
+    CPPUNIT_ASSERT_EQUAL(String("-1.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0.1);
+    CPPUNIT_ASSERT_EQUAL(String("0.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1.1);
+    CPPUNIT_ASSERT_EQUAL(String("001.100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2.1);
+    CPPUNIT_ASSERT_EQUAL(String("00002.1"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1.0),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1.0),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertFloat() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, -1.1f);
+    CPPUNIT_ASSERT_EQUAL(String("-1.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(8, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0.1f);
+    CPPUNIT_ASSERT_EQUAL(String("0.10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1.1f);
+    CPPUNIT_ASSERT_EQUAL(String("001.100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2.1f);
+    CPPUNIT_ASSERT_EQUAL(String("00002.1"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(7, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1.0f),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1.0f),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertShort() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, (short) -1);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, (short) 0);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, (short) 1);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, (short) 2);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, (short) 1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, (short) 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertInt() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, -1);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertLong() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.insert(0, -1LL);
+    CPPUNIT_ASSERT_EQUAL(String("-10000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(0, 0LL);
+    CPPUNIT_ASSERT_EQUAL(String("00000"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(2, 1LL);
+    CPPUNIT_ASSERT_EQUAL(String("00100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.insert(4, 2LL);
+    CPPUNIT_ASSERT_EQUAL(String("00002"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1LL),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1LL),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertRawPointer() {
+
+    String fixture = "0000";
+    MyObject obj;
+    StringBuffer sb;
+    sb.insert(0, &obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, 1LL),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, 1LL),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testInsertPointer() {
+
+    String fixture = "0000";
+    Pointer<MyObject> obj(new MyObject);
+    StringBuffer sb;
+    sb.insert(0, obj);
+    CPPUNIT_ASSERT_EQUAL(String("MyObject"), sb.toString());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(-1, obj),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.insert(5, obj),
+        IndexOutOfBoundsException);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void StringBufferTest::testReplace() {
+
+    String fixture = "0000";
+    StringBuffer sb(fixture);
+    sb.replace(1, 3, "11");
+    CPPUNIT_ASSERT_EQUAL(String("0110"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(4, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(1, 2, "11");
+    CPPUNIT_ASSERT_EQUAL(String("01100"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(5, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(4, 5, "11");
+    CPPUNIT_ASSERT_EQUAL(String("000011"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+    sb.replace(4, 6, "11");
+    CPPUNIT_ASSERT_EQUAL(String("000011"), sb.toString());
+    CPPUNIT_ASSERT_EQUAL(6, sb.length());
+    sb.setLength(0);
+    sb.append(fixture);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a NullPointerException",
+        sb.replace(1, 2, (const char*) NULL),
+        NullPointerException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(-1, 2, "11"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(5, 2, "11"),
+        IndexOutOfBoundsException);
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown a IndexOutOfBoundsException",
+        sb.replace(3, 2, "11"),
+        IndexOutOfBoundsException);
+
+    StringBuffer buffer("1234567");
+    buffer.replace(2, 6, "XXX");
+    CPPUNIT_ASSERT_EQUAL(String("12XXX7"), buffer.toString());
+}

http://git-wip-us.apache.org/repos/asf/activemq-cpp/blob/c6e8f8fe/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
----------------------------------------------------------------------
diff --git a/activemq-cpp/src/test/decaf/lang/StringBufferTest.h b/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
index 0823c89..8765827 100644
--- a/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
+++ b/activemq-cpp/src/test/decaf/lang/StringBufferTest.h
@@ -30,6 +30,52 @@ namespace lang {
         CPPUNIT_TEST_SUITE( StringBufferTest );
         CPPUNIT_TEST( testDefaultConstructor );
         CPPUNIT_TEST( testConstructorInt );
+        CPPUNIT_TEST( testConstructorString );
+        CPPUNIT_TEST( testAppendBoolean );
+        CPPUNIT_TEST( testAppendChar );
+        CPPUNIT_TEST( testAppendCharArray );
+        CPPUNIT_TEST( testAppendCharArrayIntInt );
+        CPPUNIT_TEST( testAppendCharSequence );
+        CPPUNIT_TEST( testAppendCharSequenceIntInt );
+        CPPUNIT_TEST( testAppendShort );
+        CPPUNIT_TEST( testAppendInt );
+        CPPUNIT_TEST( testAppendLong );
+        CPPUNIT_TEST( testAppendDouble );
+        CPPUNIT_TEST( testAppendFloat );
+        CPPUNIT_TEST( testAppendString );
+        CPPUNIT_TEST( testAppendStringBuilder );
+        CPPUNIT_TEST( testAppendRawPointer );
+        CPPUNIT_TEST( testAppendPointer );
+        CPPUNIT_TEST( testCapacity );
+        CPPUNIT_TEST( testCharAt );
+        CPPUNIT_TEST( testDeleteRange );
+        CPPUNIT_TEST( testDeleteCharAt );
+        CPPUNIT_TEST( testEnsureCapacity );
+        CPPUNIT_TEST( testGetChars );
+        CPPUNIT_TEST( testIndexOfString );
+        CPPUNIT_TEST( testIndexOfStringInt );
+        CPPUNIT_TEST( testLastIndexOfString );
+        CPPUNIT_TEST( testLastIndexOfStringInt );
+        CPPUNIT_TEST( testReverse );
+        CPPUNIT_TEST( testSubSequence );
+        CPPUNIT_TEST( testSubstringInt );
+        CPPUNIT_TEST( testSubstringIntInt );
+        CPPUNIT_TEST( testInsertChar );
+        CPPUNIT_TEST( testInsertBoolean );
+        CPPUNIT_TEST( testInsertCharArray );
+        CPPUNIT_TEST( testInsertCharArrayWithOffset );
+        CPPUNIT_TEST( testInsertString );
+        CPPUNIT_TEST( testInsertStdString );
+        CPPUNIT_TEST( testInsertCharSequence );
+        CPPUNIT_TEST( testInsertCharSequenceIntInt );
+        CPPUNIT_TEST( testInsertShort );
+        CPPUNIT_TEST( testInsertInt );
+        CPPUNIT_TEST( testInsertLong );
+        CPPUNIT_TEST( testInsertFloat );
+        CPPUNIT_TEST( testInsertDouble );
+        CPPUNIT_TEST( testInsertPointer );
+        CPPUNIT_TEST( testInsertRawPointer );
+        CPPUNIT_TEST( testReplace );
         CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -39,6 +85,52 @@ namespace lang {
 
         void testDefaultConstructor();
         void testConstructorInt();
+        void testConstructorString();
+        void testAppendBoolean();
+        void testAppendChar();
+        void testAppendCharArray();
+        void testAppendCharArrayIntInt();
+        void testAppendCharSequence();
+        void testAppendCharSequenceIntInt();
+        void testAppendShort();
+        void testAppendInt();
+        void testAppendLong();
+        void testAppendDouble();
+        void testAppendFloat();
+        void testAppendString();
+        void testAppendStringBuilder();
+        void testAppendRawPointer();
+        void testAppendPointer();
+        void testCapacity();
+        void testCharAt();
+        void testDeleteRange();
+        void testDeleteCharAt();
+        void testEnsureCapacity();
+        void testGetChars();
+        void testIndexOfString();
+        void testIndexOfStringInt();
+        void testLastIndexOfString();
+        void testLastIndexOfStringInt();
+        void testReverse();
+        void testSubSequence();
+        void testSubstringInt();
+        void testSubstringIntInt();
+        void testInsertChar();
+        void testInsertBoolean();
+        void testInsertCharArray();
+        void testInsertCharArrayWithOffset();
+        void testInsertString();
+        void testInsertStdString();
+        void testInsertCharSequence();
+        void testInsertCharSequenceIntInt();
+        void testInsertShort();
+        void testInsertInt();
+        void testInsertLong();
+        void testInsertFloat();
+        void testInsertDouble();
+        void testInsertPointer();
+        void testInsertRawPointer();
+        void testReplace();
 
     };