You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2020/06/28 19:25:59 UTC

[commons-text] branch master updated (10d40b7 -> 1423f88)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git.


    from 10d40b7  Javadoc.
     new a4701a9  Format tweak.
     new 78718b5  Rename internal classes for consistency.
     new fb7c75f  Javadoc.
     new f4e32f0  Sort members.
     new acf5e1b  Add Add org.apache.commons.text.TextStringBuilder.toString(int, int).
     new 1423f88  Better impl.

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/changes/changes.xml                            |    1 +
 .../org/apache/commons/text/TextStringBuilder.java |  100 +-
 .../text/matcher/AbstractStringMatcher.java        |   21 +-
 .../apache/commons/text/TextStringBuilderTest.java | 2713 ++++++++++----------
 4 files changed, 1434 insertions(+), 1401 deletions(-)


[commons-text] 01/06: Format tweak.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit a4701a98a25a081537651cd17749c63d244b71b1
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 14:46:18 2020 -0400

    Format tweak.
---
 src/main/java/org/apache/commons/text/TextStringBuilder.java | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/org/apache/commons/text/TextStringBuilder.java b/src/main/java/org/apache/commons/text/TextStringBuilder.java
index ae44bd8..96cd10b 100644
--- a/src/main/java/org/apache/commons/text/TextStringBuilder.java
+++ b/src/main/java/org/apache/commons/text/TextStringBuilder.java
@@ -78,8 +78,10 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
      * Inner class to allow StrBuilder to operate as a reader.
      */
     class StrBuilderReader extends Reader {
+
         /** The last mark position. */
         private int mark;
+
         /** The current stream position. */
         private int pos;
 


[commons-text] 06/06: Better impl.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit 1423f8837c8fb07e4ad1fbddff94881f6a37e60c
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 15:25:48 2020 -0400

    Better impl.
---
 .../commons/text/matcher/AbstractStringMatcher.java | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/commons/text/matcher/AbstractStringMatcher.java b/src/main/java/org/apache/commons/text/matcher/AbstractStringMatcher.java
index 1192d0e..26befb0 100644
--- a/src/main/java/org/apache/commons/text/matcher/AbstractStringMatcher.java
+++ b/src/main/java/org/apache/commons/text/matcher/AbstractStringMatcher.java
@@ -19,6 +19,8 @@ package org.apache.commons.text.matcher;
 
 import java.util.Arrays;
 
+import org.apache.commons.lang3.ArrayUtils;
+
 /**
  * A matcher that determines if a character array portion matches.
  *
@@ -340,17 +342,20 @@ abstract class AbstractStringMatcher implements StringMatcher {
     /**
      * Green implementation of toCharArray. TODO Reuse Apache Commons Lang 3.11 when released.
      *
-     * @param cs the {@code CharSequence} to be processed
+     * @param source the {@code CharSequence} to be processed
      * @return the resulting char array
      */
-    static char[] toCharArray(final CharSequence cs) {
-        if (cs instanceof String) {
-            return ((String) cs).toCharArray();
+    static char[] toCharArray(final CharSequence source) {
+        final int len = source.length();
+        if (len == 0) {
+            return ArrayUtils.EMPTY_CHAR_ARRAY;
+        }
+        if (source instanceof String) {
+            return ((String) source).toCharArray();
         }
-        final int sz = cs.length();
-        final char[] array = new char[cs.length()];
-        for (int i = 0; i < sz; i++) {
-            array[i] = cs.charAt(i);
+        final char[] array = new char[len];
+        for (int i = 0; i < len; i++) {
+            array[i] = source.charAt(i);
         }
         return array;
     }


[commons-text] 02/06: Rename internal classes for consistency.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit 78718b534d7d3c8c2c22c7ba440931c137dcd94a
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 14:48:07 2020 -0400

    Rename internal classes for consistency.
---
 .../org/apache/commons/text/TextStringBuilder.java | 76 +++++++++++-----------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/src/main/java/org/apache/commons/text/TextStringBuilder.java b/src/main/java/org/apache/commons/text/TextStringBuilder.java
index 96cd10b..7cc0122 100644
--- a/src/main/java/org/apache/commons/text/TextStringBuilder.java
+++ b/src/main/java/org/apache/commons/text/TextStringBuilder.java
@@ -77,7 +77,7 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
     /**
      * Inner class to allow StrBuilder to operate as a reader.
      */
-    class StrBuilderReader extends Reader {
+    class TextStringBuilderReader extends Reader {
 
         /** The last mark position. */
         private int mark;
@@ -88,7 +88,7 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
         /**
          * Default constructor.
          */
-        StrBuilderReader() {
+        TextStringBuilderReader() {
             super();
         }
 
@@ -166,14 +166,46 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
     }
 
     /**
+     * Inner class to allow StrBuilder to operate as a tokenizer.
+     */
+    class TextStringBuilderTokenizer extends StringTokenizer {
+
+        /**
+         * Default constructor.
+         */
+        TextStringBuilderTokenizer() {
+            super();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String getContent() {
+            final String str = super.getContent();
+            if (str == null) {
+                return TextStringBuilder.this.toString();
+            }
+            return str;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        protected List<String> tokenize(final char[] chars, final int offset, final int count) {
+            if (chars == null) {
+                return super.tokenize(TextStringBuilder.this.getBuffer(), 0, TextStringBuilder.this.size());
+            }
+            return super.tokenize(chars, offset, count);
+        }
+    }
+
+    /**
      * Inner class to allow StrBuilder to operate as a writer.
      */
-    class StrBuilderWriter extends Writer {
+    class TextStringBuilderWriter extends Writer {
 
         /**
          * Default constructor.
          */
-        StrBuilderWriter() {
+        TextStringBuilderWriter() {
             super();
         }
 
@@ -221,38 +253,6 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
     }
 
     /**
-     * Inner class to allow StrBuilder to operate as a tokenizer.
-     */
-    class TextStringBuilderTokenizer extends StringTokenizer {
-
-        /**
-         * Default constructor.
-         */
-        TextStringBuilderTokenizer() {
-            super();
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public String getContent() {
-            final String str = super.getContent();
-            if (str == null) {
-                return TextStringBuilder.this.toString();
-            }
-            return str;
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        protected List<String> tokenize(final char[] chars, final int offset, final int count) {
-            if (chars == null) {
-                return super.tokenize(TextStringBuilder.this.getBuffer(), 0, TextStringBuilder.this.size());
-            }
-            return super.tokenize(chars, offset, count);
-        }
-    }
-
-    /**
      * The extra capacity for new builders.
      */
     static final int CAPACITY = 32;
@@ -1542,7 +1542,7 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
      * @return a reader that reads from this builder
      */
     public Reader asReader() {
-        return new StrBuilderReader();
+        return new TextStringBuilderReader();
     }
 
     /**
@@ -1605,7 +1605,7 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
      * @return a writer that populates this builder
      */
     public Writer asWriter() {
-        return new StrBuilderWriter();
+        return new TextStringBuilderWriter();
     }
 
     /**


[commons-text] 03/06: Javadoc.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit fb7c75ffb7f71d50d3b24dbbc2e49ae14d964830
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 14:56:40 2020 -0400

    Javadoc.
---
 src/main/java/org/apache/commons/text/TextStringBuilder.java | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/commons/text/TextStringBuilder.java b/src/main/java/org/apache/commons/text/TextStringBuilder.java
index 7cc0122..b94be8d 100644
--- a/src/main/java/org/apache/commons/text/TextStringBuilder.java
+++ b/src/main/java/org/apache/commons/text/TextStringBuilder.java
@@ -3219,12 +3219,10 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
     }
 
     /**
-     * Validates parameters defining a single index in the builder.
+     * Validates that an index is in the range {@code 0 <= index <= size}.
      *
-     * @param index
-     *            the index, must be valid
-     * @throws IndexOutOfBoundsException
-     *             if the index is invalid
+     * @param index the index, must be valid
+     * @throws IndexOutOfBoundsException Thrown when the index is not the range {@code 0 <= index <= size}.
      */
     protected void validateIndex(final int index) {
         if (index < 0 || index > size) {


[commons-text] 04/06: Sort members.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit f4e32f0d883657a7aedaff62ef9c8d43e79bdfd5
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 15:09:38 2020 -0400

    Sort members.
---
 .../apache/commons/text/TextStringBuilderTest.java | 2713 ++++++++++----------
 1 file changed, 1363 insertions(+), 1350 deletions(-)

diff --git a/src/test/java/org/apache/commons/text/TextStringBuilderTest.java b/src/test/java/org/apache/commons/text/TextStringBuilderTest.java
index e21f147..8be8278 100644
--- a/src/test/java/org/apache/commons/text/TextStringBuilderTest.java
+++ b/src/test/java/org/apache/commons/text/TextStringBuilderTest.java
@@ -47,181 +47,377 @@ import org.junit.jupiter.api.Test;
  */
 public class TextStringBuilderTest {
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testConstructors() {
-        final TextStringBuilder sb0 = new TextStringBuilder();
-        assertEquals(32, sb0.capacity());
-        assertEquals(0, sb0.length());
-        assertEquals(0, sb0.size());
-
-        final TextStringBuilder sb1 = new TextStringBuilder(32);
-        assertEquals(32, sb1.capacity());
-        assertEquals(0, sb1.length());
-        assertEquals(0, sb1.size());
-
-        final TextStringBuilder sb2 = new TextStringBuilder(0);
-        assertEquals(32, sb2.capacity());
-        assertEquals(0, sb2.length());
-        assertEquals(0, sb2.size());
-
-        final TextStringBuilder sb3 = new TextStringBuilder(-1);
-        assertEquals(32, sb3.capacity());
-        assertEquals(0, sb3.length());
-        assertEquals(0, sb3.size());
-
-        final TextStringBuilder sb4 = new TextStringBuilder(1);
-        assertEquals(1, sb4.capacity());
-        assertEquals(0, sb4.length());
-        assertEquals(0, sb4.size());
+    private static class MockReadable implements Readable {
 
-        final TextStringBuilder sb5 = new TextStringBuilder((String) null);
-        assertEquals(32, sb5.capacity());
-        assertEquals(0, sb5.length());
-        assertEquals(0, sb5.size());
+        private final CharBuffer src;
 
-        final TextStringBuilder sb6 = new TextStringBuilder("");
-        assertEquals(32, sb6.capacity());
-        assertEquals(0, sb6.length());
-        assertEquals(0, sb6.size());
+        MockReadable(final String src) {
+            this.src = CharBuffer.wrap(src);
+        }
 
-        final TextStringBuilder sb7 = new TextStringBuilder("foo");
-        assertEquals(35, sb7.capacity());
-        assertEquals(3, sb7.length());
-        assertEquals(3, sb7.size());
+        @Override
+        public int read(final CharBuffer cb) throws IOException {
+            return src.read(cb);
+        }
     }
 
-    // -----------------------------------------------------------------------
+    static final StringMatcher A_NUMBER_MATCHER = (buffer, start, bufferStart, bufferEnd) -> {
+        if (buffer[start] == 'A') {
+            start++;
+            if (start < bufferEnd && buffer[start] >= '0' && buffer[start] <= '9') {
+                return 2;
+            }
+        }
+        return 0;
+    };
+
     @Test
-    public void testChaining() {
+    public void test_LANG_1131_EqualsWithNullTextStringBuilder() throws Exception {
         final TextStringBuilder sb = new TextStringBuilder();
-        assertSame(sb, sb.setNewLineText(null));
-        assertSame(sb, sb.setNullText(null));
-        assertSame(sb, sb.setLength(1));
-        assertSame(sb, sb.setCharAt(0, 'a'));
-        assertSame(sb, sb.ensureCapacity(0));
-        assertSame(sb, sb.minimizeCapacity());
-        assertSame(sb, sb.clear());
-        assertSame(sb, sb.reverse());
-        assertSame(sb, sb.trim());
+        final TextStringBuilder other = null;
+        assertFalse(sb.equals(other));
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testReadFromReader() throws Exception {
-        String s = "";
-        for (int i = 0; i < 100; ++i) {
-            final TextStringBuilder sb = new TextStringBuilder();
-            final int len = sb.readFrom(new StringReader(s));
+    public void testAppendCharBuffer() {
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        final CharBuffer buf = CharBuffer.allocate(10);
+        buf.append("0123456789");
+        buf.flip();
+        sb1.append(buf);
+        assertEquals("0123456789", sb1.toString());
 
-            assertEquals(s.length(), len);
-            assertEquals(s, sb.toString());
+        final TextStringBuilder sb2 = new TextStringBuilder();
+        sb2.append(buf, 1, 8);
+        assertEquals("12345678", sb2.toString());
+    }
 
-            s += Integer.toString(i);
+    @Test
+    public void testAppendCharBufferException() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final String text = "Test";
+        final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
+        buffer.put(text);
+        buffer.flip();
+        try {
+            sb.append(buffer, -1, 12);
+        } catch (final StringIndexOutOfBoundsException e) {
+            assertEquals("startIndex must be valid", e.getMessage());
+        }
+
+        try {
+            sb.append(buffer, 0, -1);
+        } catch (final StringIndexOutOfBoundsException e) {
+            assertEquals("length must be valid", e.getMessage());
         }
+
+        sb.append(buffer);
+        assertEquals("1234567890Test", sb.toString());
     }
 
     @Test
-    public void testReadFromReaderAppendsToEnd() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("Test");
-        sb.readFrom(new StringReader(" 123"));
-        assertEquals("Test 123", sb.toString());
+    public void testAppendCharBufferNull() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final CharBuffer buffer = null;
+        sb.append(buffer);
+        assertEquals("1234567890", sb.toString());
+
+        final TextStringBuilder sb1 = new TextStringBuilder("1234567890");
+        final CharBuffer buffer1 = null;
+        sb.append(buffer1, 0, 0);
+        assertEquals("1234567890", sb1.toString());
     }
 
     @Test
-    public void testReadFromCharBuffer() throws Exception {
-        String s = "";
-        for (int i = 0; i < 100; ++i) {
-            final TextStringBuilder sb = new TextStringBuilder();
-            final int len = sb.readFrom(CharBuffer.wrap(s));
+    public void testAppendCharSequence() {
+        final CharSequence obj0 = null;
+        final CharSequence obj1 = new TextStringBuilder("test1");
+        final CharSequence obj2 = new StringBuilder("test2");
+        final CharSequence obj3 = new StringBuffer("test3");
+        final CharBuffer obj4 = CharBuffer.wrap("test4".toCharArray());
 
-            assertEquals(s.length(), len);
-            assertEquals(s, sb.toString());
+        final TextStringBuilder sb0 = new TextStringBuilder();
+        assertEquals("", sb0.append(obj0).toString());
 
-            s += Integer.toString(i);
-        }
-    }
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        assertEquals("test1", sb1.append(obj1).toString());
 
-    @Test
-    public void testReadFromCharBufferAppendsToEnd() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("Test");
-        sb.readFrom(CharBuffer.wrap(" 123"));
-        assertEquals("Test 123", sb.toString());
-    }
+        final TextStringBuilder sb2 = new TextStringBuilder();
+        assertEquals("test2", sb2.append(obj2).toString());
 
-    @Test
-    public void testReadFromReadable() throws Exception {
-        String s = "";
-        for (int i = 0; i < 100; ++i) {
-            final TextStringBuilder sb = new TextStringBuilder();
-            final int len = sb.readFrom(new MockReadable(s));
+        final TextStringBuilder sb3 = new TextStringBuilder();
+        assertEquals("test3", sb3.append(obj3).toString());
 
-            assertEquals(s.length(), len);
-            assertEquals(s, sb.toString());
+        final TextStringBuilder sb4 = new TextStringBuilder();
+        assertEquals("test4", sb4.append(obj4).toString());
 
-            s += Integer.toString(i);
-        }
+        final TextStringBuilder sb5 = new TextStringBuilder();
+        assertEquals("", sb5.append(obj0, 0, 0).toString());
     }
 
     @Test
-    public void testReadFromReadableAppendsToEnd() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("Test");
-        sb.readFrom(new MockReadable(" 123"));
-        assertEquals("Test 123", sb.toString());
+    public void testAppendln() {
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        final char ch = 'c';
+        assertEquals("c" + System.lineSeparator(), sb1.appendln(ch).toString());
     }
 
-    private static class MockReadable implements Readable {
+    @Test
+    public void testAppendStringBuilderNull() {
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        final StringBuilder b = null;
+        assertEquals("", sb1.append(b).toString());
 
-        private final CharBuffer src;
+        final TextStringBuilder sb2 = new TextStringBuilder();
+        assertEquals("", sb2.append(b, 0, 0).toString());
+    }
 
-        MockReadable(final String src) {
-            this.src = CharBuffer.wrap(src);
-        }
+    @Test
+    public void testAppendTakingTwoIntsWithIndexOutOfBoundsThrowsStringIndexOutOfBoundsExceptionTwo() {
+        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
+            final Charset charset = Charset.defaultCharset();
+            final ByteBuffer byteBuffer = charset.encode("asdf");
+            final CharBuffer charBuffer = charset.decode(byteBuffer);
 
-        @Override
-        public int read(final CharBuffer cb) throws IOException {
-            return src.read(cb);
-        }
+            new TextStringBuilder().append(charBuffer, 933, 654);
+        });
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testGetSetNewLineText() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertNull(sb.getNewLineText());
+    public void testAppendTakingTwoIntsWithZeroThrowsStringIndexOutOfBoundsException() {
+        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
+            final Charset charset = Charset.defaultCharset();
+            final ByteBuffer byteBuffer = charset.encode("end < start");
+            final CharBuffer charBuffer = charset.decode(byteBuffer);
 
-        sb.setNewLineText("#");
-        assertEquals("#", sb.getNewLineText());
+            new TextStringBuilder(630).append(charBuffer, 0, 630);
+        });
+    }
 
-        sb.setNewLineText("");
-        assertEquals("", sb.getNewLineText());
+    @Test
+    public void testAppendToCharBuffer() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final String text = "Test ";
+        final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
+        buffer.put(text);
 
-        sb.setNewLineText((String) null);
-        assertNull(sb.getNewLineText());
+        sb.appendTo(buffer);
+
+        buffer.flip();
+        assertEquals("Test 1234567890", buffer.toString());
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testGetSetNullText() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertNull(sb.getNullText());
+    public void testAppendToStringBuffer() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final StringBuffer buffer = new StringBuffer("Test ");
 
-        sb.setNullText("null");
-        assertEquals("null", sb.getNullText());
+        sb.appendTo(buffer);
 
-        sb.setNullText("");
-        assertNull(sb.getNullText());
+        assertEquals("Test 1234567890", buffer.toString());
+    }
 
-        sb.setNullText("NULL");
-        assertEquals("NULL", sb.getNullText());
+    @Test
+    public void testAppendToStringBuilder() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final StringBuilder builder = new StringBuilder("Test ");
 
-        sb.setNullText((String) null);
-        assertNull(sb.getNullText());
+        sb.appendTo(builder);
+
+        assertEquals("Test 1234567890", builder.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testCapacityAndLength() {
+    public void testAppendToWriter() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("1234567890");
+        final StringWriter writer = new StringWriter();
+        writer.append("Test ");
+
+        sb.appendTo(writer);
+
+        assertEquals("Test 1234567890", writer.toString());
+    }
+
+    @Test
+    public void testAsBuilder() {
+        final TextStringBuilder sb = new TextStringBuilder().appendAll("Lorem", " ", "ipsum", " ", "dolor");
+        assertEquals(sb.toString(), sb.build());
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testAsReader() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("some text");
+        try (Reader reader = sb.asReader()) {
+            assertTrue(reader.ready());
+            final char[] buf = new char[40];
+            assertEquals(9, reader.read(buf));
+            assertEquals("some text", new String(buf, 0, 9));
+
+            assertEquals(-1, reader.read());
+            assertFalse(reader.ready());
+            assertEquals(0, reader.skip(2));
+            assertEquals(0, reader.skip(-1));
+
+            assertTrue(reader.markSupported());
+        }
+        try (Reader reader = sb.asReader()) {
+            assertEquals('s', reader.read());
+            reader.mark(-1);
+            char[] array = new char[3];
+            assertEquals(3, reader.read(array, 0, 3));
+            assertEquals('o', array[0]);
+            assertEquals('m', array[1]);
+            assertEquals('e', array[2]);
+            reader.reset();
+            assertEquals(1, reader.read(array, 1, 1));
+            assertEquals('o', array[0]);
+            assertEquals('o', array[1]);
+            assertEquals('e', array[2]);
+            assertEquals(2, reader.skip(2));
+            assertEquals(' ', reader.read());
+
+            assertTrue(reader.ready());
+            reader.close();
+            assertTrue(reader.ready());
+        }
+        try (Reader reader = sb.asReader()) {
+            char[] array = new char[3];
+            try {
+                reader.read(array, -1, 0);
+                fail("Exception expected!");
+            } catch (final IndexOutOfBoundsException ex) {
+                // expected
+            }
+            try {
+                reader.read(array, 0, -1);
+                fail("Exception expected!");
+            } catch (final IndexOutOfBoundsException ex) {
+                // expected
+            }
+            try {
+                reader.read(array, 100, 1);
+                fail("Exception expected!");
+            } catch (final IndexOutOfBoundsException ex) {
+                // expected
+            }
+            try {
+                reader.read(array, 0, 100);
+                fail("Exception expected!");
+            } catch (final IndexOutOfBoundsException ex) {
+                // expected
+            }
+            try {
+                reader.read(array, Integer.MAX_VALUE, Integer.MAX_VALUE);
+                fail("Exception expected!");
+            } catch (final IndexOutOfBoundsException ex) {
+                // expected
+            }
+
+            assertEquals(0, reader.read(array, 0, 0));
+            assertEquals(0, array[0]);
+            assertEquals(0, array[1]);
+            assertEquals(0, array[2]);
+
+            reader.skip(9);
+            assertEquals(-1, reader.read(array, 0, 1));
+
+            reader.reset();
+            array = new char[30];
+            assertEquals(9, reader.read(array, 0, 30));
+        }
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testAsTokenizer() throws Exception {
+        // from Javadoc
+        final TextStringBuilder b = new TextStringBuilder();
+        b.append("a b ");
+        final StringTokenizer t = b.asTokenizer();
+
+        final String[] tokens1 = t.getTokenArray();
+        assertEquals(2, tokens1.length);
+        assertEquals("a", tokens1[0]);
+        assertEquals("b", tokens1[1]);
+        assertEquals(2, t.size());
+
+        b.append("c d ");
+        final String[] tokens2 = t.getTokenArray();
+        assertEquals(2, tokens2.length);
+        assertEquals("a", tokens2[0]);
+        assertEquals("b", tokens2[1]);
+        assertEquals(2, t.size());
+        assertEquals("a", t.next());
+        assertEquals("b", t.next());
+
+        t.reset();
+        final String[] tokens3 = t.getTokenArray();
+        assertEquals(4, tokens3.length);
+        assertEquals("a", tokens3[0]);
+        assertEquals("b", tokens3[1]);
+        assertEquals("c", tokens3[2]);
+        assertEquals("d", tokens3[3]);
+        assertEquals(4, t.size());
+        assertEquals("a", t.next());
+        assertEquals("b", t.next());
+        assertEquals("c", t.next());
+        assertEquals("d", t.next());
+
+        assertEquals("a b c d ", t.getContent());
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testAsWriter() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("base");
+        try (Writer writer = sb.asWriter()) {
+
+            writer.write('l');
+            assertEquals("basel", sb.toString());
+
+            writer.write(new char[] {'i', 'n'});
+            assertEquals("baselin", sb.toString());
+
+            writer.write(new char[] {'n', 'e', 'r'}, 1, 2);
+            assertEquals("baseliner", sb.toString());
+
+            writer.write(" rout");
+            assertEquals("baseliner rout", sb.toString());
+
+            writer.write("ping that server", 1, 3);
+            assertEquals("baseliner routing", sb.toString());
+
+            writer.flush(); // no effect
+            assertEquals("baseliner routing", sb.toString());
+
+            writer.close(); // no effect
+            assertEquals("baseliner routing", sb.toString());
+
+            writer.write(" hi"); // works after close
+            assertEquals("baseliner routing hi", sb.toString());
+
+            sb.setLength(4); // mix and match
+            writer.write('d');
+            assertEquals("based", sb.toString());
+        }
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testCapacity() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(sb.getBuffer().length, sb.capacity());
+
+        sb.append("HelloWorldHelloWorldHelloWorldHelloWorld");
+        assertEquals(sb.getBuffer().length, sb.capacity());
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testCapacityAndLength() {
         final TextStringBuilder sb = new TextStringBuilder();
         assertEquals(32, sb.capacity());
         assertEquals(0, sb.length());
@@ -301,261 +497,119 @@ public class TextStringBuilderTest {
 
     // -----------------------------------------------------------------------
     @Test
-    public void testLength() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(0, sb.length());
-
-        sb.append("Hello");
-        assertEquals(5, sb.length());
-    }
-
-    @Test
-    public void testSetLength() {
+    public void testChaining() {
         final TextStringBuilder sb = new TextStringBuilder();
-        sb.append("Hello");
-        sb.setLength(2); // shorten
-        assertEquals("He", sb.toString());
-        sb.setLength(2); // no change
-        assertEquals("He", sb.toString());
-        sb.setLength(3); // lengthen
-        assertEquals("He\0", sb.toString());
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.setLength(-1));
+        assertSame(sb, sb.setNewLineText(null));
+        assertSame(sb, sb.setNullText(null));
+        assertSame(sb, sb.setLength(1));
+        assertSame(sb, sb.setCharAt(0, 'a'));
+        assertSame(sb, sb.ensureCapacity(0));
+        assertSame(sb, sb.minimizeCapacity());
+        assertSame(sb, sb.clear());
+        assertSame(sb, sb.reverse());
+        assertSame(sb, sb.trim());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testCapacity() {
+    public void testCharAt() {
         final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(sb.getBuffer().length, sb.capacity());
-
-        sb.append("HelloWorldHelloWorldHelloWorldHelloWorld");
-        assertEquals(sb.getBuffer().length, sb.capacity());
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(0));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(-1));
+        sb.append("foo");
+        assertEquals('f', sb.charAt(0));
+        assertEquals('o', sb.charAt(1));
+        assertEquals('o', sb.charAt(2));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(-1));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(3));
     }
 
     @Test
-    public void testEnsureCapacity() {
+    public void testClear() {
         final TextStringBuilder sb = new TextStringBuilder();
-        sb.ensureCapacity(2);
-        assertTrue(sb.capacity() >= 2);
-
-        sb.ensureCapacity(-1);
-        assertTrue(sb.capacity() >= 0);
-
-        sb.append("HelloWorld");
-        sb.ensureCapacity(40);
-        assertTrue(sb.capacity() >= 40);
+        sb.append("Hello");
+        sb.clear();
+        assertEquals(0, sb.length());
+        assertTrue(sb.getBuffer().length >= 5);
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testMinimizeCapacity() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        sb.minimizeCapacity();
-        assertEquals(0, sb.capacity());
+    public void testConstructors() {
+        final TextStringBuilder sb0 = new TextStringBuilder();
+        assertEquals(32, sb0.capacity());
+        assertEquals(0, sb0.length());
+        assertEquals(0, sb0.size());
 
-        sb.append("HelloWorld");
-        sb.minimizeCapacity();
-        assertEquals(10, sb.capacity());
-    }
-
-    // -----------------------------------------------------------------------
-    @Test
-    public void testSize() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(0, sb.size());
-
-        sb.append("Hello");
-        assertEquals(5, sb.size());
-    }
-
-    @Test
-    public void testIsEmpty() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertTrue(sb.isEmpty());
-
-        sb.append("Hello");
-        assertFalse(sb.isEmpty());
+        final TextStringBuilder sb1 = new TextStringBuilder(32);
+        assertEquals(32, sb1.capacity());
+        assertEquals(0, sb1.length());
+        assertEquals(0, sb1.size());
 
-        sb.clear();
-        assertTrue(sb.isEmpty());
-    }
+        final TextStringBuilder sb2 = new TextStringBuilder(0);
+        assertEquals(32, sb2.capacity());
+        assertEquals(0, sb2.length());
+        assertEquals(0, sb2.size());
 
-    @Test
-    public void testClear() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        sb.append("Hello");
-        sb.clear();
-        assertEquals(0, sb.length());
-        assertTrue(sb.getBuffer().length >= 5);
-    }
+        final TextStringBuilder sb3 = new TextStringBuilder(-1);
+        assertEquals(32, sb3.capacity());
+        assertEquals(0, sb3.length());
+        assertEquals(0, sb3.size());
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testCharAt() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(0));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(-1));
-        sb.append("foo");
-        assertEquals('f', sb.charAt(0));
-        assertEquals('o', sb.charAt(1));
-        assertEquals('o', sb.charAt(2));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(-1));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.charAt(3));
-    }
+        final TextStringBuilder sb4 = new TextStringBuilder(1);
+        assertEquals(1, sb4.capacity());
+        assertEquals(0, sb4.length());
+        assertEquals(0, sb4.size());
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testSetCharAt() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(0, 'f'));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(-1, 'f'));
-        sb.append("foo");
-        sb.setCharAt(0, 'b');
-        sb.setCharAt(1, 'a');
-        sb.setCharAt(2, 'r');
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(3, '!'));
-        assertEquals("bar", sb.toString());
-    }
+        final TextStringBuilder sb5 = new TextStringBuilder((String) null);
+        assertEquals(32, sb5.capacity());
+        assertEquals(0, sb5.length());
+        assertEquals(0, sb5.size());
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testDeleteCharAt() {
-        final TextStringBuilder sb = new TextStringBuilder("abc");
-        sb.deleteCharAt(0);
-        assertEquals("bc", sb.toString());
+        final TextStringBuilder sb6 = new TextStringBuilder("");
+        assertEquals(32, sb6.capacity());
+        assertEquals(0, sb6.length());
+        assertEquals(0, sb6.size());
 
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.deleteCharAt(1000));
+        final TextStringBuilder sb7 = new TextStringBuilder("foo");
+        assertEquals(35, sb7.capacity());
+        assertEquals(3, sb7.length());
+        assertEquals(3, sb7.size());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testToCharArray() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(0, sb.toCharArray().length);
-
-        char[] a = sb.toCharArray();
-        assertNotNull(a, "toCharArray() result is null");
-        assertEquals(0, a.length, "toCharArray() result is too large");
-
-        sb.append("junit");
-        a = sb.toCharArray();
-        assertEquals(5, a.length, "toCharArray() result incorrect length");
-        assertTrue(Arrays.equals("junit".toCharArray(), a), "toCharArray() result does not match");
-    }
-
-    @Test
-    public void testToCharArrayIntInt() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(0, sb.toCharArray(0, 0).length);
-
-        sb.append("junit");
-        char[] a = sb.toCharArray(0, 20); // too large test
-        assertEquals(5, a.length, "toCharArray(int,int) result incorrect length");
-        assertTrue(Arrays.equals("junit".toCharArray(), a), "toCharArray(int,int) result does not match");
-
-        a = sb.toCharArray(0, 4);
-        assertEquals(4, a.length, "toCharArray(int,int) result incorrect length");
-        assertTrue(Arrays.equals("juni".toCharArray(), a), "toCharArray(int,int) result does not match");
-
-        a = sb.toCharArray(0, 4);
-        assertEquals(4, a.length, "toCharArray(int,int) result incorrect length");
-        assertTrue(Arrays.equals("juni".toCharArray(), a), "toCharArray(int,int) result does not match");
-
-        a = sb.toCharArray(0, 1);
-        assertNotNull(a, "toCharArray(int,int) result is null");
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.toCharArray(-1, 5));
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.toCharArray(6, 5));
-    }
-
-    @Test
-    public void testGetChars() {
-        final TextStringBuilder sb = new TextStringBuilder();
-
-        char[] input = new char[10];
-        char[] a = sb.getChars(input);
-        assertSame(input, a);
-        assertTrue(Arrays.equals(new char[10], a));
-
-        sb.append("junit");
-        a = sb.getChars(input);
-        assertSame(input, a);
-        assertTrue(Arrays.equals(new char[] {'j', 'u', 'n', 'i', 't', 0, 0, 0, 0, 0 }, a));
-
-        a = sb.getChars(null);
-        assertNotSame(input, a);
-        assertEquals(5, a.length);
-        assertTrue(Arrays.equals("junit".toCharArray(), a));
-
-        input = new char[5];
-        a = sb.getChars(input);
-        assertSame(input, a);
-
-        input = new char[4];
-        a = sb.getChars(input);
-        assertNotSame(input, a);
+    public void testContains_char() {
+        final TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
+        assertTrue(sb.contains('a'));
+        assertTrue(sb.contains('o'));
+        assertTrue(sb.contains('z'));
+        assertFalse(sb.contains('1'));
     }
 
     @Test
-    public void testGetCharsIntIntCharArrayInt() {
-        final TextStringBuilder sb = new TextStringBuilder();
-
-        sb.append("junit");
-        char[] a = new char[5];
-        sb.getChars(0, 5, a, 0);
-        assertTrue(Arrays.equals(new char[] {'j', 'u', 'n', 'i', 't' }, a));
-
-        a = new char[5];
-        sb.getChars(0, 2, a, 3);
-        assertTrue(Arrays.equals(new char[] {0, 0, 0, 'j', 'u' }, a));
-
-        try {
-            sb.getChars(-1, 0, a, 0);
-            fail("no exception");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
-
-        try {
-            sb.getChars(0, -1, a, 0);
-            fail("no exception");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
-
-        try {
-            sb.getChars(0, 20, a, 0);
-            fail("no exception");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
-
-        try {
-            sb.getChars(4, 2, a, 0);
-            fail("no exception");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
+    public void testContains_String() {
+        final TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
+        assertTrue(sb.contains("a"));
+        assertTrue(sb.contains("pq"));
+        assertTrue(sb.contains("z"));
+        assertFalse(sb.contains("zyx"));
+        assertFalse(sb.contains((String) null));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testDeleteIntInt() {
-        final TextStringBuilder sb = new TextStringBuilder("abc");
-        sb.delete(0, 1);
-        assertEquals("bc", sb.toString());
-        sb.delete(1, 2);
-        assertEquals("b", sb.toString());
-        sb.delete(0, 1);
-        assertEquals("", sb.toString());
-        sb.delete(0, 1000);
-        assertEquals("", sb.toString());
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.delete(1, 2));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.delete(-1, 1));
+    public void testContains_StringMatcher() {
+        TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
+        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.charMatcher('a')));
+        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.stringMatcher("pq")));
+        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.charMatcher('z')));
+        assertFalse(sb.contains(StringMatcherFactory.INSTANCE.stringMatcher("zy")));
+        assertFalse(sb.contains((StringMatcher) null));
 
-        assertThrows(IndexOutOfBoundsException.class, () -> new TextStringBuilder("anything").delete(2, 1));
+        sb = new TextStringBuilder();
+        assertFalse(sb.contains(A_NUMBER_MATCHER));
+        sb.append("B A1 C");
+        assertTrue(sb.contains(A_NUMBER_MATCHER));
     }
 
     // -----------------------------------------------------------------------
@@ -576,23 +630,6 @@ public class TextStringBuilderTest {
         assertEquals("", sb.toString());
     }
 
-    @Test
-    public void testDeleteFirst_char() {
-        TextStringBuilder sb = new TextStringBuilder("abcba");
-        sb.deleteFirst('X');
-        assertEquals("abcba", sb.toString());
-        sb.deleteFirst('a');
-        assertEquals("bcba", sb.toString());
-        sb.deleteFirst('c');
-        assertEquals("bba", sb.toString());
-        sb.deleteFirst('b');
-        assertEquals("ba", sb.toString());
-
-        sb = new TextStringBuilder("");
-        sb.deleteFirst('b');
-        assertEquals("", sb.toString());
-    }
-
     // -----------------------------------------------------------------------
     @Test
     public void testDeleteAll_String() {
@@ -620,6 +657,58 @@ public class TextStringBuilderTest {
         assertEquals("", sb.toString());
     }
 
+    // -----------------------------------------------------------------------
+    @Test
+    public void testDeleteAll_StringMatcher() {
+        TextStringBuilder sb = new TextStringBuilder("A0xA1A2yA3");
+        sb.deleteAll((StringMatcher) null);
+        assertEquals("A0xA1A2yA3", sb.toString());
+        sb.deleteAll(A_NUMBER_MATCHER);
+        assertEquals("xy", sb.toString());
+
+        sb = new TextStringBuilder("Ax1");
+        sb.deleteAll(A_NUMBER_MATCHER);
+        assertEquals("Ax1", sb.toString());
+
+        sb = new TextStringBuilder("");
+        sb.deleteAll(A_NUMBER_MATCHER);
+        assertEquals("", sb.toString());
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testDeleteCharAt() {
+        final TextStringBuilder sb = new TextStringBuilder("abc");
+        sb.deleteCharAt(0);
+        assertEquals("bc", sb.toString());
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.deleteCharAt(1000));
+    }
+
+    @Test
+    public void testDeleteCharAtWithNegative() {
+        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
+            new TextStringBuilder().deleteCharAt((-1258));
+        });
+    }
+
+    @Test
+    public void testDeleteFirst_char() {
+        TextStringBuilder sb = new TextStringBuilder("abcba");
+        sb.deleteFirst('X');
+        assertEquals("abcba", sb.toString());
+        sb.deleteFirst('a');
+        assertEquals("bcba", sb.toString());
+        sb.deleteFirst('c');
+        assertEquals("bba", sb.toString());
+        sb.deleteFirst('b');
+        assertEquals("ba", sb.toString());
+
+        sb = new TextStringBuilder("");
+        sb.deleteFirst('b');
+        assertEquals("", sb.toString());
+    }
+
     @Test
     public void testDeleteFirst_String() {
         TextStringBuilder sb = new TextStringBuilder("abcbccba");
@@ -646,24 +735,6 @@ public class TextStringBuilderTest {
         assertEquals("", sb.toString());
     }
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testDeleteAll_StringMatcher() {
-        TextStringBuilder sb = new TextStringBuilder("A0xA1A2yA3");
-        sb.deleteAll((StringMatcher) null);
-        assertEquals("A0xA1A2yA3", sb.toString());
-        sb.deleteAll(A_NUMBER_MATCHER);
-        assertEquals("xy", sb.toString());
-
-        sb = new TextStringBuilder("Ax1");
-        sb.deleteAll(A_NUMBER_MATCHER);
-        assertEquals("Ax1", sb.toString());
-
-        sb = new TextStringBuilder("");
-        sb.deleteAll(A_NUMBER_MATCHER);
-        assertEquals("", sb.toString());
-    }
-
     @Test
     public void testDeleteFirst_StringMatcher() {
         TextStringBuilder sb = new TextStringBuilder("A0xA1A2yA3");
@@ -683,625 +754,431 @@ public class TextStringBuilderTest {
 
     // -----------------------------------------------------------------------
     @Test
-    public void testReplace_int_int_String() {
-        TextStringBuilder sb = new TextStringBuilder("abc");
-        sb.replace(0, 1, "d");
-        assertEquals("dbc", sb.toString());
-        sb.replace(0, 1, "aaa");
-        assertEquals("aaabc", sb.toString());
-        sb.replace(0, 3, "");
+    public void testDeleteIntInt() {
+        final TextStringBuilder sb = new TextStringBuilder("abc");
+        sb.delete(0, 1);
         assertEquals("bc", sb.toString());
-        sb.replace(1, 2, (String) null);
+        sb.delete(1, 2);
         assertEquals("b", sb.toString());
-        sb.replace(1, 1000, "text");
-        assertEquals("btext", sb.toString());
-        sb.replace(0, 1000, "text");
-        assertEquals("text", sb.toString());
+        sb.delete(0, 1);
+        assertEquals("", sb.toString());
+        sb.delete(0, 1000);
+        assertEquals("", sb.toString());
 
-        sb = new TextStringBuilder("atext");
-        sb.replace(1, 1, "ny");
-        assertEquals("anytext", sb.toString());
-        try {
-            sb.replace(2, 1, "anything");
-            fail("Expected IndexOutOfBoundsException");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.delete(1, 2));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.delete(-1, 1));
 
-        sb = new TextStringBuilder();
-        try {
-            sb.replace(1, 2, "anything");
-            fail("Expected IndexOutOfBoundsException");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
-        try {
-            sb.replace(-1, 1, "anything");
-            fail("Expected IndexOutOfBoundsException");
-        } catch (final IndexOutOfBoundsException e) {
-            // expected
-        }
+        assertThrows(IndexOutOfBoundsException.class, () -> new TextStringBuilder("anything").delete(2, 1));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testReplaceAll_char_char() {
-        final TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceAll('x', 'y');
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll('a', 'd');
-        assertEquals("dbcbccbd", sb.toString());
-        sb.replaceAll('b', 'e');
-        assertEquals("dececced", sb.toString());
-        sb.replaceAll('c', 'f');
-        assertEquals("defeffed", sb.toString());
-        sb.replaceAll('d', 'd');
-        assertEquals("defeffed", sb.toString());
+    public void testEndsWith() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertFalse(sb.endsWith("a"));
+        assertFalse(sb.endsWith("c"));
+        assertTrue(sb.endsWith(""));
+        assertFalse(sb.endsWith(null));
+        sb.append("abc");
+        assertTrue(sb.endsWith("c"));
+        assertTrue(sb.endsWith("bc"));
+        assertTrue(sb.endsWith("abc"));
+        assertFalse(sb.endsWith("cba"));
+        assertFalse(sb.endsWith("abcd"));
+        assertFalse(sb.endsWith(" abc"));
+        assertFalse(sb.endsWith("abc "));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testReplaceFirst_char_char() {
-        final TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceFirst('x', 'y');
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst('a', 'd');
-        assertEquals("dbcbccba", sb.toString());
-        sb.replaceFirst('b', 'e');
-        assertEquals("decbccba", sb.toString());
-        sb.replaceFirst('c', 'f');
-        assertEquals("defbccba", sb.toString());
-        sb.replaceFirst('d', 'd');
-        assertEquals("defbccba", sb.toString());
+    public void testEnsureCapacity() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        sb.ensureCapacity(2);
+        assertTrue(sb.capacity() >= 2);
+
+        sb.ensureCapacity(-1);
+        assertTrue(sb.capacity() >= 0);
+
+        sb.append("HelloWorld");
+        sb.ensureCapacity(40);
+        assertTrue(sb.capacity() >= 40);
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testReplaceAll_String_String() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceAll((String) null, null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll((String) null, "anything");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll("", null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll("", "anything");
-        assertEquals("abcbccba", sb.toString());
+    public void testEquals() {
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        final TextStringBuilder sb2 = new TextStringBuilder();
+        assertTrue(sb1.equals(sb2));
+        assertTrue(sb1.equals(sb1));
+        assertTrue(sb2.equals(sb2));
+        assertTrue(sb1.equals((Object) sb2));
 
-        sb.replaceAll("x", "y");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll("a", "d");
-        assertEquals("dbcbccbd", sb.toString());
-        sb.replaceAll("d", null);
-        assertEquals("bcbccb", sb.toString());
-        sb.replaceAll("cb", "-");
-        assertEquals("b-c-", sb.toString());
+        sb1.append("abc");
+        assertFalse(sb1.equals(sb2));
+        assertFalse(sb1.equals((Object) sb2));
 
-        sb = new TextStringBuilder("abcba");
-        sb.replaceAll("b", "xbx");
-        assertEquals("axbxcxbxa", sb.toString());
+        sb2.append("ABC");
+        assertFalse(sb1.equals(sb2));
+        assertFalse(sb1.equals((Object) sb2));
 
-        sb = new TextStringBuilder("bb");
-        sb.replaceAll("b", "xbx");
-        assertEquals("xbxxbx", sb.toString());
+        sb2.clear().append("abc");
+        assertTrue(sb1.equals(sb2));
+        assertTrue(sb1.equals((Object) sb2));
+
+        assertFalse(sb1.equals(Integer.valueOf(1)));
+        assertFalse(sb1.equals("abc"));
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testReplaceFirst_String_String() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceFirst((String) null, null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst((String) null, "anything");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst("", null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst("", "anything");
-        assertEquals("abcbccba", sb.toString());
+    public void testEqualsIgnoreCase() {
+        final TextStringBuilder sb1 = new TextStringBuilder();
+        final TextStringBuilder sb2 = new TextStringBuilder();
+        assertTrue(sb1.equalsIgnoreCase(sb1));
+        assertTrue(sb1.equalsIgnoreCase(sb2));
+        assertTrue(sb2.equalsIgnoreCase(sb2));
 
-        sb.replaceFirst("x", "y");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst("a", "d");
-        assertEquals("dbcbccba", sb.toString());
-        sb.replaceFirst("d", null);
-        assertEquals("bcbccba", sb.toString());
-        sb.replaceFirst("cb", "-");
-        assertEquals("b-ccba", sb.toString());
+        sb1.append("abc");
+        assertFalse(sb1.equalsIgnoreCase(sb2));
 
-        sb = new TextStringBuilder("abcba");
-        sb.replaceFirst("b", "xbx");
-        assertEquals("axbxcba", sb.toString());
+        sb2.append("ABC");
+        assertTrue(sb1.equalsIgnoreCase(sb2));
 
-        sb = new TextStringBuilder("bb");
-        sb.replaceFirst("b", "xbx");
-        assertEquals("xbxb", sb.toString());
+        sb2.clear().append("abc");
+        assertTrue(sb1.equalsIgnoreCase(sb2));
+        assertTrue(sb1.equalsIgnoreCase(sb1));
+        assertTrue(sb2.equalsIgnoreCase(sb2));
+
+        sb2.clear().append("aBc");
+        assertTrue(sb1.equalsIgnoreCase(sb2));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testReplaceAll_StringMatcher_String() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceAll((StringMatcher) null, null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll((StringMatcher) null, "anything");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll(StringMatcherFactory.INSTANCE.noneMatcher(), null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll(StringMatcherFactory.INSTANCE.noneMatcher(), "anything");
-        assertEquals("abcbccba", sb.toString());
+    public void testGetChars() {
+        final TextStringBuilder sb = new TextStringBuilder();
 
-        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('x'), "y");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('a'), "d");
-        assertEquals("dbcbccbd", sb.toString());
-        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('d'), null);
-        assertEquals("bcbccb", sb.toString());
-        sb.replaceAll(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-");
-        assertEquals("b-c-", sb.toString());
+        char[] input = new char[10];
+        char[] a = sb.getChars(input);
+        assertSame(input, a);
+        assertTrue(Arrays.equals(new char[10], a));
 
-        sb = new TextStringBuilder("abcba");
-        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
-        assertEquals("axbxcxbxa", sb.toString());
+        sb.append("junit");
+        a = sb.getChars(input);
+        assertSame(input, a);
+        assertTrue(Arrays.equals(new char[] {'j', 'u', 'n', 'i', 't', 0, 0, 0, 0, 0 }, a));
 
-        sb = new TextStringBuilder("bb");
-        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
-        assertEquals("xbxxbx", sb.toString());
+        a = sb.getChars(null);
+        assertNotSame(input, a);
+        assertEquals(5, a.length);
+        assertTrue(Arrays.equals("junit".toCharArray(), a));
 
-        sb = new TextStringBuilder("A1-A2A3-A4");
-        sb.replaceAll(A_NUMBER_MATCHER, "***");
-        assertEquals("***-******-***", sb.toString());
+        input = new char[5];
+        a = sb.getChars(input);
+        assertSame(input, a);
 
-        sb = new TextStringBuilder("Dear X, hello X.");
-        sb.replaceAll(StringMatcherFactory.INSTANCE.stringMatcher("X"), "012345678901234567");
-        assertEquals("Dear 012345678901234567, hello 012345678901234567.", sb.toString());
+        input = new char[4];
+        a = sb.getChars(input);
+        assertNotSame(input, a);
     }
 
     @Test
-    public void testReplaceFirst_StringMatcher_String() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replaceFirst((StringMatcher) null, null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst((StringMatcher) null, "anything");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.noneMatcher(), null);
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.noneMatcher(), "anything");
-        assertEquals("abcbccba", sb.toString());
+    public void testGetCharsIntIntCharArrayInt() {
+        final TextStringBuilder sb = new TextStringBuilder();
 
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('x'), "y");
-        assertEquals("abcbccba", sb.toString());
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('a'), "d");
-        assertEquals("dbcbccba", sb.toString());
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('d'), null);
-        assertEquals("bcbccba", sb.toString());
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-");
-        assertEquals("b-ccba", sb.toString());
+        sb.append("junit");
+        char[] a = new char[5];
+        sb.getChars(0, 5, a, 0);
+        assertTrue(Arrays.equals(new char[] {'j', 'u', 'n', 'i', 't' }, a));
 
-        sb = new TextStringBuilder("abcba");
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
-        assertEquals("axbxcba", sb.toString());
+        a = new char[5];
+        sb.getChars(0, 2, a, 3);
+        assertTrue(Arrays.equals(new char[] {0, 0, 0, 'j', 'u' }, a));
 
-        sb = new TextStringBuilder("bb");
-        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
-        assertEquals("xbxb", sb.toString());
+        try {
+            sb.getChars(-1, 0, a, 0);
+            fail("no exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
 
-        sb = new TextStringBuilder("A1-A2A3-A4");
-        sb.replaceFirst(A_NUMBER_MATCHER, "***");
-        assertEquals("***-A2A3-A4", sb.toString());
+        try {
+            sb.getChars(0, -1, a, 0);
+            fail("no exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.getChars(0, 20, a, 0);
+            fail("no exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.getChars(4, 2, a, 0);
+            fail("no exception");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testReplace_StringMatcher_String_int_int_int_VaryMatcher() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replace((StringMatcher) null, "x", 0, sb.length(), -1);
-        assertEquals("abcbccba", sb.toString());
-
-        sb.replace(StringMatcherFactory.INSTANCE.charMatcher('a'), "x", 0, sb.length(), -1);
-        assertEquals("xbcbccbx", sb.toString());
+    public void testGetSetNewLineText() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertNull(sb.getNewLineText());
 
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "x", 0, sb.length(), -1);
-        assertEquals("xbxcxx", sb.toString());
+        sb.setNewLineText("#");
+        assertEquals("#", sb.getNewLineText());
 
-        sb = new TextStringBuilder("A1-A2A3-A4");
-        sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
-        assertEquals("***-******-***", sb.toString());
+        sb.setNewLineText("");
+        assertEquals("", sb.getNewLineText());
 
-        sb = new TextStringBuilder();
-        sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
-        assertEquals("", sb.toString());
+        sb.setNewLineText((String) null);
+        assertNull(sb.getNewLineText());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testReplace_StringMatcher_String_int_int_int_VaryReplace() {
-        TextStringBuilder sb = new TextStringBuilder("abcbccba");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "cb", 0, sb.length(), -1);
-        assertEquals("abcbccba", sb.toString());
+    public void testGetSetNullText() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertNull(sb.getNullText());
 
-        sb = new TextStringBuilder("abcbccba");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-", 0, sb.length(), -1);
-        assertEquals("ab-c-a", sb.toString());
+        sb.setNullText("null");
+        assertEquals("null", sb.getNullText());
 
-        sb = new TextStringBuilder("abcbccba");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "+++", 0, sb.length(), -1);
-        assertEquals("ab+++c+++a", sb.toString());
+        sb.setNullText("");
+        assertNull(sb.getNullText());
 
-        sb = new TextStringBuilder("abcbccba");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "", 0, sb.length(), -1);
-        assertEquals("abca", sb.toString());
+        sb.setNullText("NULL");
+        assertEquals("NULL", sb.getNullText());
 
-        sb = new TextStringBuilder("abcbccba");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), null, 0, sb.length(), -1);
-        assertEquals("abca", sb.toString());
+        sb.setNullText((String) null);
+        assertNull(sb.getNullText());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testReplace_StringMatcher_String_int_int_int_VaryStartIndex() {
-        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, sb.length(), -1);
-        assertEquals("-x--y-", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 1, sb.length(), -1);
-        assertEquals("aax--y-", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 2, sb.length(), -1);
-        assertEquals("aax--y-", sb.toString());
+    public void testHashCode() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        final int hc1a = sb.hashCode();
+        final int hc1b = sb.hashCode();
+        assertEquals(0, hc1a);
+        assertEquals(hc1a, hc1b);
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 3, sb.length(), -1);
-        assertEquals("aax--y-", sb.toString());
+        sb.append("abc");
+        final int hc2a = sb.hashCode();
+        final int hc2b = sb.hashCode();
+        assertTrue(hc2a != 0);
+        assertEquals(hc2a, hc2b);
+    }
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 4, sb.length(), -1);
-        assertEquals("aaxa-ay-", sb.toString());
+    // -----------------------------------------------------------------------
+    @Test
+    public void testIndexOf_char() {
+        final TextStringBuilder sb = new TextStringBuilder("abab");
+        assertEquals(0, sb.indexOf('a'));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 5, sb.length(), -1);
-        assertEquals("aaxaa-y-", sb.toString());
+        // should work like String#indexOf
+        assertEquals("abab".indexOf('a'), sb.indexOf('a'));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 6, sb.length(), -1);
-        assertEquals("aaxaaaay-", sb.toString());
+        assertEquals(1, sb.indexOf('b'));
+        assertEquals("abab".indexOf('b'), sb.indexOf('b'));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 7, sb.length(), -1);
-        assertEquals("aaxaaaay-", sb.toString());
+        assertEquals(-1, sb.indexOf('z'));
+    }
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 8, sb.length(), -1);
-        assertEquals("aaxaaaay-", sb.toString());
+    @Test
+    public void testIndexOf_char_int() {
+        TextStringBuilder sb = new TextStringBuilder("abab");
+        assertEquals(0, sb.indexOf('a', -1));
+        assertEquals(0, sb.indexOf('a', 0));
+        assertEquals(2, sb.indexOf('a', 1));
+        assertEquals(-1, sb.indexOf('a', 4));
+        assertEquals(-1, sb.indexOf('a', 5));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 9, sb.length(), -1);
-        assertEquals("aaxaaaayaa", sb.toString());
+        // should work like String#indexOf
+        assertEquals("abab".indexOf('a', 1), sb.indexOf('a', 1));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 10, sb.length(), -1);
-        assertEquals("aaxaaaayaa", sb.toString());
+        assertEquals(3, sb.indexOf('b', 2));
+        assertEquals("abab".indexOf('b', 2), sb.indexOf('b', 2));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        try {
-            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 11, sb.length(), -1);
-            fail("Exception expected!");
-        } catch (final IndexOutOfBoundsException ex) {
-            // expected
-        }
-        assertEquals("aaxaaaayaa", sb.toString());
+        assertEquals(-1, sb.indexOf('z', 2));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        try {
-            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", -1, sb.length(), -1);
-            fail("Exception expected!");
-        } catch (final IndexOutOfBoundsException ex) {
-            // expected
-        }
-        assertEquals("aaxaaaayaa", sb.toString());
+        sb = new TextStringBuilder("xyzabc");
+        assertEquals(2, sb.indexOf('z', 0));
+        assertEquals(-1, sb.indexOf('z', 3));
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testReplace_StringMatcher_String_int_int_int_VaryEndIndex() {
-        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 0, -1);
-        assertEquals("aaxaaaayaa", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 2, -1);
-        assertEquals("-xaaaayaa", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 3, -1);
-        assertEquals("-xaaaayaa", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 4, -1);
-        assertEquals("-xaaaayaa", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 5, -1);
-        assertEquals("-x-aayaa", sb.toString());
-
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 6, -1);
-        assertEquals("-x-aayaa", sb.toString());
+    public void testIndexOf_String() {
+        final TextStringBuilder sb = new TextStringBuilder("abab");
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 7, -1);
-        assertEquals("-x--yaa", sb.toString());
+        assertEquals(0, sb.indexOf("a"));
+        // should work like String#indexOf
+        assertEquals("abab".indexOf("a"), sb.indexOf("a"));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 8, -1);
-        assertEquals("-x--yaa", sb.toString());
+        assertEquals(0, sb.indexOf("ab"));
+        // should work like String#indexOf
+        assertEquals("abab".indexOf("ab"), sb.indexOf("ab"));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 9, -1);
-        assertEquals("-x--yaa", sb.toString());
+        assertEquals(1, sb.indexOf("b"));
+        assertEquals("abab".indexOf("b"), sb.indexOf("b"));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, -1);
-        assertEquals("-x--y-", sb.toString());
+        assertEquals(1, sb.indexOf("ba"));
+        assertEquals("abab".indexOf("ba"), sb.indexOf("ba"));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 1000, -1);
-        assertEquals("-x--y-", sb.toString());
+        assertEquals(-1, sb.indexOf("z"));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        try {
-            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 2, 1, -1);
-            fail("Exception expected!");
-        } catch (final IndexOutOfBoundsException ex) {
-            // expected
-        }
-        assertEquals("aaxaaaayaa", sb.toString());
+        assertEquals(-1, sb.indexOf((String) null));
     }
 
     @Test
-    public void testReplace_StringMatcher_String_int_int_int_VaryCount() {
-        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, -1);
-        assertEquals("-x--y-", sb.toString());
+    public void testIndexOf_String_int() {
+        TextStringBuilder sb = new TextStringBuilder("abab");
+        assertEquals(0, sb.indexOf("a", -1));
+        assertEquals(0, sb.indexOf("a", 0));
+        assertEquals(2, sb.indexOf("a", 1));
+        assertEquals(2, sb.indexOf("a", 2));
+        assertEquals(-1, sb.indexOf("a", 3));
+        assertEquals(-1, sb.indexOf("a", 4));
+        assertEquals(-1, sb.indexOf("a", 5));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 0);
-        assertEquals("aaxaaaayaa", sb.toString());
+        assertEquals(-1, sb.indexOf("abcdef", 0));
+        assertEquals(0, sb.indexOf("", 0));
+        assertEquals(1, sb.indexOf("", 1));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 1);
-        assertEquals("-xaaaayaa", sb.toString());
+        // should work like String#indexOf
+        assertEquals("abab".indexOf("a", 1), sb.indexOf("a", 1));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 2);
-        assertEquals("-x-aayaa", sb.toString());
+        assertEquals(2, sb.indexOf("ab", 1));
+        // should work like String#indexOf
+        assertEquals("abab".indexOf("ab", 1), sb.indexOf("ab", 1));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 3);
-        assertEquals("-x--yaa", sb.toString());
+        assertEquals(3, sb.indexOf("b", 2));
+        assertEquals("abab".indexOf("b", 2), sb.indexOf("b", 2));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 4);
-        assertEquals("-x--y-", sb.toString());
+        assertEquals(1, sb.indexOf("ba", 1));
+        assertEquals("abab".indexOf("ba", 2), sb.indexOf("ba", 2));
 
-        sb = new TextStringBuilder("aaxaaaayaa");
-        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 5);
-        assertEquals("-x--y-", sb.toString());
+        assertEquals(-1, sb.indexOf("z", 2));
+
+        sb = new TextStringBuilder("xyzabc");
+        assertEquals(2, sb.indexOf("za", 0));
+        assertEquals(-1, sb.indexOf("za", 3));
+
+        assertEquals(-1, sb.indexOf((String) null, 2));
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testReverse() {
+    public void testIndexOf_StringMatcher() {
         final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals("", sb.reverse().toString());
+        assertEquals(-1, sb.indexOf((StringMatcher) null));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a')));
 
-        sb.clear().append(true);
-        assertEquals("eurt", sb.reverse().toString());
-        assertEquals("true", sb.reverse().toString());
+        sb.append("ab bd");
+        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a')));
+        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b')));
+        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher()));
+        assertEquals(4, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('d')));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.noneMatcher()));
+        assertEquals(-1, sb.indexOf((StringMatcher) null));
+
+        sb.append(" A1 junction");
+        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testTrim() {
+    public void testIndexOf_StringMatcher_int() {
         final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals("", sb.reverse().toString());
+        assertEquals(-1, sb.indexOf((StringMatcher) null, 2));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 2));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 0));
 
-        sb.clear().append(" \u0000 ");
-        assertEquals("", sb.trim().toString());
+        sb.append("ab bd");
+        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), -2));
+        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 0));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 2));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 20));
 
-        sb.clear().append(" \u0000 a b c");
-        assertEquals("a b c", sb.trim().toString());
+        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), -1));
+        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 0));
+        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 1));
+        assertEquals(3, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 2));
+        assertEquals(3, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 3));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 4));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 5));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 6));
 
-        sb.clear().append("a b c \u0000 ");
-        assertEquals("a b c", sb.trim().toString());
+        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), -2));
+        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 0));
+        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 2));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 4));
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 20));
 
-        sb.clear().append(" \u0000 a b c \u0000 ");
-        assertEquals("a b c", sb.trim().toString());
+        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.noneMatcher(), 0));
+        assertEquals(-1, sb.indexOf((StringMatcher) null, 0));
 
-        sb.clear().append("a b c");
-        assertEquals("a b c", sb.trim().toString());
+        sb.append(" A1 junction with A2");
+        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 5));
+        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 6));
+        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 7));
+        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 22));
+        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 23));
+        assertEquals(-1, sb.indexOf(A_NUMBER_MATCHER, 24));
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testStartsWith() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertFalse(sb.startsWith("a"));
-        assertFalse(sb.startsWith(null));
-        assertTrue(sb.startsWith(""));
-        sb.append("abc");
-        assertTrue(sb.startsWith("a"));
-        assertTrue(sb.startsWith("ab"));
-        assertTrue(sb.startsWith("abc"));
-        assertFalse(sb.startsWith("cba"));
+    public void testIndexOfLang294() {
+        final TextStringBuilder sb = new TextStringBuilder("onetwothree");
+        sb.deleteFirst("three");
+        assertEquals(-1, sb.indexOf("three"));
     }
 
     @Test
-    public void testEndsWith() {
+    public void testIsEmpty() {
         final TextStringBuilder sb = new TextStringBuilder();
-        assertFalse(sb.endsWith("a"));
-        assertFalse(sb.endsWith("c"));
-        assertTrue(sb.endsWith(""));
-        assertFalse(sb.endsWith(null));
-        sb.append("abc");
-        assertTrue(sb.endsWith("c"));
-        assertTrue(sb.endsWith("bc"));
-        assertTrue(sb.endsWith("abc"));
-        assertFalse(sb.endsWith("cba"));
-        assertFalse(sb.endsWith("abcd"));
-        assertFalse(sb.endsWith(" abc"));
-        assertFalse(sb.endsWith("abc "));
+        assertTrue(sb.isEmpty());
+
+        sb.append("Hello");
+        assertFalse(sb.isEmpty());
+
+        sb.clear();
+        assertTrue(sb.isEmpty());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testSubSequenceIntInt() {
-        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
-        // Start index is negative
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(-1, 5));
-
-        // End index is negative
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(2, -1));
-
-        // End index greater than length()
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(2, sb.length() + 1));
-
-        // Start index greater then end index
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(3, 2));
-
-        // Normal cases
-        assertEquals("hello", sb.subSequence(0, 5));
-        assertEquals("hello goodbye".subSequence(0, 6), sb.subSequence(0, 6));
-        assertEquals("goodbye", sb.subSequence(6, 13));
-        assertEquals("hello goodbye".subSequence(6, 13), sb.subSequence(6, 13));
+    public void testLang294() {
+        final TextStringBuilder sb = new TextStringBuilder("\n%BLAH%\nDo more stuff\neven more stuff\n%BLAH%\n");
+        sb.deleteAll("\n%BLAH%");
+        assertEquals("\nDo more stuff\neven more stuff\n", sb.toString());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testSubstringInt() {
-        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
-        assertEquals("goodbye", sb.substring(6));
-        assertEquals("hello goodbye".substring(6), sb.substring(6));
-        assertEquals("hello goodbye", sb.substring(0));
-        assertEquals("hello goodbye".substring(0), sb.substring(0));
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(-1));
+    public void testLang295() {
+        final TextStringBuilder sb = new TextStringBuilder("onetwothree");
+        sb.deleteFirst("three");
+        assertFalse(sb.contains('h'), "The contains(char) method is looking beyond the end of the string");
+        assertEquals(-1, sb.indexOf('h'), "The indexOf(char) method is looking beyond the end of the string");
+    }
 
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(15));
+    @Test
+    public void testLang412Left() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        sb.appendFixedWidthPadLeft(null, 10, '*');
+        assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadLeft correctly");
+    }
 
-    }
-
-    @Test
-    public void testSubstringIntInt() {
-        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
-        assertEquals("hello", sb.substring(0, 5));
-        assertEquals("hello goodbye".substring(0, 6), sb.substring(0, 6));
-
-        assertEquals("goodbye", sb.substring(6, 13));
-        assertEquals("hello goodbye".substring(6, 13), sb.substring(6, 13));
-
-        assertEquals("goodbye", sb.substring(6, 20));
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(-1, 5));
-
-        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(15, 20));
-    }
-
-    // -----------------------------------------------------------------------
-    @Test
-    public void testMidString() {
-        final TextStringBuilder sb = new TextStringBuilder("hello goodbye hello");
-        assertEquals("goodbye", sb.midString(6, 7));
-        assertEquals("hello", sb.midString(0, 5));
-        assertEquals("hello", sb.midString(-5, 5));
-        assertEquals("", sb.midString(0, -1));
-        assertEquals("", sb.midString(20, 2));
-        assertEquals("hello", sb.midString(14, 22));
-    }
-
-    @Test
-    public void testRightString() {
-        final TextStringBuilder sb = new TextStringBuilder("left right");
-        assertEquals("right", sb.rightString(5));
-        assertEquals("", sb.rightString(0));
-        assertEquals("", sb.rightString(-5));
-        assertEquals("left right", sb.rightString(15));
-    }
-
-    @Test
-    public void testLeftString() {
-        final TextStringBuilder sb = new TextStringBuilder("left right");
-        assertEquals("left", sb.leftString(4));
-        assertEquals("", sb.leftString(0));
-        assertEquals("", sb.leftString(-5));
-        assertEquals("left right", sb.leftString(15));
-    }
-
-    // -----------------------------------------------------------------------
-    @Test
-    public void testContains_char() {
-        final TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
-        assertTrue(sb.contains('a'));
-        assertTrue(sb.contains('o'));
-        assertTrue(sb.contains('z'));
-        assertFalse(sb.contains('1'));
-    }
-
-    @Test
-    public void testContains_String() {
-        final TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
-        assertTrue(sb.contains("a"));
-        assertTrue(sb.contains("pq"));
-        assertTrue(sb.contains("z"));
-        assertFalse(sb.contains("zyx"));
-        assertFalse(sb.contains((String) null));
-    }
-
-    @Test
-    public void testContains_StringMatcher() {
-        TextStringBuilder sb = new TextStringBuilder("abcdefghijklmnopqrstuvwxyz");
-        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.charMatcher('a')));
-        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.stringMatcher("pq")));
-        assertTrue(sb.contains(StringMatcherFactory.INSTANCE.charMatcher('z')));
-        assertFalse(sb.contains(StringMatcherFactory.INSTANCE.stringMatcher("zy")));
-        assertFalse(sb.contains((StringMatcher) null));
-
-        sb = new TextStringBuilder();
-        assertFalse(sb.contains(A_NUMBER_MATCHER));
-        sb.append("B A1 C");
-        assertTrue(sb.contains(A_NUMBER_MATCHER));
-    }
-
-    // -----------------------------------------------------------------------
-    @Test
-    public void testIndexOf_char() {
-        final TextStringBuilder sb = new TextStringBuilder("abab");
-        assertEquals(0, sb.indexOf('a'));
-
-        // should work like String#indexOf
-        assertEquals("abab".indexOf('a'), sb.indexOf('a'));
-
-        assertEquals(1, sb.indexOf('b'));
-        assertEquals("abab".indexOf('b'), sb.indexOf('b'));
-
-        assertEquals(-1, sb.indexOf('z'));
-    }
-
-    @Test
-    public void testIndexOf_char_int() {
-        TextStringBuilder sb = new TextStringBuilder("abab");
-        assertEquals(0, sb.indexOf('a', -1));
-        assertEquals(0, sb.indexOf('a', 0));
-        assertEquals(2, sb.indexOf('a', 1));
-        assertEquals(-1, sb.indexOf('a', 4));
-        assertEquals(-1, sb.indexOf('a', 5));
-
-        // should work like String#indexOf
-        assertEquals("abab".indexOf('a', 1), sb.indexOf('a', 1));
-
-        assertEquals(3, sb.indexOf('b', 2));
-        assertEquals("abab".indexOf('b', 2), sb.indexOf('b', 2));
-
-        assertEquals(-1, sb.indexOf('z', 2));
-
-        sb = new TextStringBuilder("xyzabc");
-        assertEquals(2, sb.indexOf('z', 0));
-        assertEquals(-1, sb.indexOf('z', 3));
+    // -----------------------------------------------------------------------
+    @Test
+    public void testLang412Right() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        sb.appendFixedWidthPadRight(null, 10, '*');
+        assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadRight correctly");
     }
 
     @Test
@@ -1338,67 +1215,6 @@ public class TextStringBuilderTest {
         assertEquals(-1, sb.lastIndexOf('z', 1));
     }
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testIndexOf_String() {
-        final TextStringBuilder sb = new TextStringBuilder("abab");
-
-        assertEquals(0, sb.indexOf("a"));
-        // should work like String#indexOf
-        assertEquals("abab".indexOf("a"), sb.indexOf("a"));
-
-        assertEquals(0, sb.indexOf("ab"));
-        // should work like String#indexOf
-        assertEquals("abab".indexOf("ab"), sb.indexOf("ab"));
-
-        assertEquals(1, sb.indexOf("b"));
-        assertEquals("abab".indexOf("b"), sb.indexOf("b"));
-
-        assertEquals(1, sb.indexOf("ba"));
-        assertEquals("abab".indexOf("ba"), sb.indexOf("ba"));
-
-        assertEquals(-1, sb.indexOf("z"));
-
-        assertEquals(-1, sb.indexOf((String) null));
-    }
-
-    @Test
-    public void testIndexOf_String_int() {
-        TextStringBuilder sb = new TextStringBuilder("abab");
-        assertEquals(0, sb.indexOf("a", -1));
-        assertEquals(0, sb.indexOf("a", 0));
-        assertEquals(2, sb.indexOf("a", 1));
-        assertEquals(2, sb.indexOf("a", 2));
-        assertEquals(-1, sb.indexOf("a", 3));
-        assertEquals(-1, sb.indexOf("a", 4));
-        assertEquals(-1, sb.indexOf("a", 5));
-
-        assertEquals(-1, sb.indexOf("abcdef", 0));
-        assertEquals(0, sb.indexOf("", 0));
-        assertEquals(1, sb.indexOf("", 1));
-
-        // should work like String#indexOf
-        assertEquals("abab".indexOf("a", 1), sb.indexOf("a", 1));
-
-        assertEquals(2, sb.indexOf("ab", 1));
-        // should work like String#indexOf
-        assertEquals("abab".indexOf("ab", 1), sb.indexOf("ab", 1));
-
-        assertEquals(3, sb.indexOf("b", 2));
-        assertEquals("abab".indexOf("b", 2), sb.indexOf("b", 2));
-
-        assertEquals(1, sb.indexOf("ba", 1));
-        assertEquals("abab".indexOf("ba", 2), sb.indexOf("ba", 2));
-
-        assertEquals(-1, sb.indexOf("z", 2));
-
-        sb = new TextStringBuilder("xyzabc");
-        assertEquals(2, sb.indexOf("za", 0));
-        assertEquals(-1, sb.indexOf("za", 3));
-
-        assertEquals(-1, sb.indexOf((String) null, 2));
-    }
-
     @Test
     public void testLastIndexOf_String() {
         final TextStringBuilder sb = new TextStringBuilder("abab");
@@ -1459,65 +1275,6 @@ public class TextStringBuilderTest {
         assertEquals(-1, sb.lastIndexOf((String) null, 2));
     }
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testIndexOf_StringMatcher() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(-1, sb.indexOf((StringMatcher) null));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a')));
-
-        sb.append("ab bd");
-        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a')));
-        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b')));
-        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher()));
-        assertEquals(4, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('d')));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.noneMatcher()));
-        assertEquals(-1, sb.indexOf((StringMatcher) null));
-
-        sb.append(" A1 junction");
-        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER));
-    }
-
-    @Test
-    public void testIndexOf_StringMatcher_int() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(-1, sb.indexOf((StringMatcher) null, 2));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 2));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 0));
-
-        sb.append("ab bd");
-        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), -2));
-        assertEquals(0, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 0));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 2));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('a'), 20));
-
-        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), -1));
-        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 0));
-        assertEquals(1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 1));
-        assertEquals(3, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 2));
-        assertEquals(3, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 3));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 4));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 5));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.charMatcher('b'), 6));
-
-        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), -2));
-        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 0));
-        assertEquals(2, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 2));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 4));
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.spaceMatcher(), 20));
-
-        assertEquals(-1, sb.indexOf(StringMatcherFactory.INSTANCE.noneMatcher(), 0));
-        assertEquals(-1, sb.indexOf((StringMatcher) null, 0));
-
-        sb.append(" A1 junction with A2");
-        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 5));
-        assertEquals(6, sb.indexOf(A_NUMBER_MATCHER, 6));
-        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 7));
-        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 22));
-        assertEquals(23, sb.indexOf(A_NUMBER_MATCHER, 23));
-        assertEquals(-1, sb.indexOf(A_NUMBER_MATCHER, 24));
-    }
-
     @Test
     public void testLastIndexOf_StringMatcher() {
         final TextStringBuilder sb = new TextStringBuilder();
@@ -1581,487 +1338,743 @@ public class TextStringBuilderTest {
         assertEquals(23, sb.lastIndexOf(A_NUMBER_MATCHER, 24));
     }
 
-    static final StringMatcher A_NUMBER_MATCHER = (buffer, start, bufferStart, bufferEnd) -> {
-        if (buffer[start] == 'A') {
-            start++;
-            if (start < bufferEnd && buffer[start] >= '0' && buffer[start] <= '9') {
-                return 2;
-            }
-        }
-        return 0;
-    };
+    @Test
+    public void testLeftString() {
+        final TextStringBuilder sb = new TextStringBuilder("left right");
+        assertEquals("left", sb.leftString(4));
+        assertEquals("", sb.leftString(0));
+        assertEquals("", sb.leftString(-5));
+        assertEquals("left right", sb.leftString(15));
+    }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testAsTokenizer() throws Exception {
-        // from Javadoc
-        final TextStringBuilder b = new TextStringBuilder();
-        b.append("a b ");
-        final StringTokenizer t = b.asTokenizer();
+    public void testLength() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(0, sb.length());
 
-        final String[] tokens1 = t.getTokenArray();
-        assertEquals(2, tokens1.length);
-        assertEquals("a", tokens1[0]);
-        assertEquals("b", tokens1[1]);
-        assertEquals(2, t.size());
+        sb.append("Hello");
+        assertEquals(5, sb.length());
+    }
 
-        b.append("c d ");
-        final String[] tokens2 = t.getTokenArray();
-        assertEquals(2, tokens2.length);
-        assertEquals("a", tokens2[0]);
-        assertEquals("b", tokens2[1]);
-        assertEquals(2, t.size());
-        assertEquals("a", t.next());
-        assertEquals("b", t.next());
+    // -----------------------------------------------------------------------
+    @Test
+    public void testMidString() {
+        final TextStringBuilder sb = new TextStringBuilder("hello goodbye hello");
+        assertEquals("goodbye", sb.midString(6, 7));
+        assertEquals("hello", sb.midString(0, 5));
+        assertEquals("hello", sb.midString(-5, 5));
+        assertEquals("", sb.midString(0, -1));
+        assertEquals("", sb.midString(20, 2));
+        assertEquals("hello", sb.midString(14, 22));
+    }
 
-        t.reset();
-        final String[] tokens3 = t.getTokenArray();
-        assertEquals(4, tokens3.length);
-        assertEquals("a", tokens3[0]);
-        assertEquals("b", tokens3[1]);
-        assertEquals("c", tokens3[2]);
-        assertEquals("d", tokens3[3]);
-        assertEquals(4, t.size());
-        assertEquals("a", t.next());
-        assertEquals("b", t.next());
-        assertEquals("c", t.next());
-        assertEquals("d", t.next());
+    @Test
+    public void testMinimizeCapacity() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        sb.minimizeCapacity();
+        assertEquals(0, sb.capacity());
 
-        assertEquals("a b c d ", t.getContent());
+        sb.append("HelloWorld");
+        sb.minimizeCapacity();
+        assertEquals(10, sb.capacity());
+    }
+
+    @Test
+    public void testReadFromCharBuffer() throws Exception {
+        String s = "";
+        for (int i = 0; i < 100; ++i) {
+            final TextStringBuilder sb = new TextStringBuilder();
+            final int len = sb.readFrom(CharBuffer.wrap(s));
+
+            assertEquals(s.length(), len);
+            assertEquals(s, sb.toString());
+
+            s += Integer.toString(i);
+        }
+    }
+
+    @Test
+    public void testReadFromCharBufferAppendsToEnd() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("Test");
+        sb.readFrom(CharBuffer.wrap(" 123"));
+        assertEquals("Test 123", sb.toString());
+    }
+
+    @Test
+    public void testReadFromReadable() throws Exception {
+        String s = "";
+        for (int i = 0; i < 100; ++i) {
+            final TextStringBuilder sb = new TextStringBuilder();
+            final int len = sb.readFrom(new MockReadable(s));
+
+            assertEquals(s.length(), len);
+            assertEquals(s, sb.toString());
+
+            s += Integer.toString(i);
+        }
+    }
+
+    @Test
+    public void testReadFromReadableAppendsToEnd() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("Test");
+        sb.readFrom(new MockReadable(" 123"));
+        assertEquals("Test 123", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testAsReader() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("some text");
-        try (Reader reader = sb.asReader()) {
-            assertTrue(reader.ready());
-            final char[] buf = new char[40];
-            assertEquals(9, reader.read(buf));
-            assertEquals("some text", new String(buf, 0, 9));
+    public void testReadFromReader() throws Exception {
+        String s = "";
+        for (int i = 0; i < 100; ++i) {
+            final TextStringBuilder sb = new TextStringBuilder();
+            final int len = sb.readFrom(new StringReader(s));
 
-            assertEquals(-1, reader.read());
-            assertFalse(reader.ready());
-            assertEquals(0, reader.skip(2));
-            assertEquals(0, reader.skip(-1));
+            assertEquals(s.length(), len);
+            assertEquals(s, sb.toString());
 
-            assertTrue(reader.markSupported());
+            s += Integer.toString(i);
         }
-        try (Reader reader = sb.asReader()) {
-            assertEquals('s', reader.read());
-            reader.mark(-1);
-            char[] array = new char[3];
-            assertEquals(3, reader.read(array, 0, 3));
-            assertEquals('o', array[0]);
-            assertEquals('m', array[1]);
-            assertEquals('e', array[2]);
-            reader.reset();
-            assertEquals(1, reader.read(array, 1, 1));
-            assertEquals('o', array[0]);
-            assertEquals('o', array[1]);
-            assertEquals('e', array[2]);
-            assertEquals(2, reader.skip(2));
-            assertEquals(' ', reader.read());
+    }
 
-            assertTrue(reader.ready());
-            reader.close();
-            assertTrue(reader.ready());
+    @Test
+    public void testReadFromReaderAppendsToEnd() throws Exception {
+        final TextStringBuilder sb = new TextStringBuilder("Test");
+        sb.readFrom(new StringReader(" 123"));
+        assertEquals("Test 123", sb.toString());
+    }
+
+    // -----------------------------------------------------------------------
+    @Test
+    public void testReplace_int_int_String() {
+        TextStringBuilder sb = new TextStringBuilder("abc");
+        sb.replace(0, 1, "d");
+        assertEquals("dbc", sb.toString());
+        sb.replace(0, 1, "aaa");
+        assertEquals("aaabc", sb.toString());
+        sb.replace(0, 3, "");
+        assertEquals("bc", sb.toString());
+        sb.replace(1, 2, (String) null);
+        assertEquals("b", sb.toString());
+        sb.replace(1, 1000, "text");
+        assertEquals("btext", sb.toString());
+        sb.replace(0, 1000, "text");
+        assertEquals("text", sb.toString());
+
+        sb = new TextStringBuilder("atext");
+        sb.replace(1, 1, "ny");
+        assertEquals("anytext", sb.toString());
+        try {
+            sb.replace(2, 1, "anything");
+            fail("Expected IndexOutOfBoundsException");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
         }
-        try (Reader reader = sb.asReader()) {
-            char[] array = new char[3];
-            try {
-                reader.read(array, -1, 0);
-                fail("Exception expected!");
-            } catch (final IndexOutOfBoundsException ex) {
-                // expected
-            }
-            try {
-                reader.read(array, 0, -1);
-                fail("Exception expected!");
-            } catch (final IndexOutOfBoundsException ex) {
-                // expected
-            }
-            try {
-                reader.read(array, 100, 1);
-                fail("Exception expected!");
-            } catch (final IndexOutOfBoundsException ex) {
-                // expected
-            }
-            try {
-                reader.read(array, 0, 100);
-                fail("Exception expected!");
-            } catch (final IndexOutOfBoundsException ex) {
-                // expected
-            }
-            try {
-                reader.read(array, Integer.MAX_VALUE, Integer.MAX_VALUE);
-                fail("Exception expected!");
-            } catch (final IndexOutOfBoundsException ex) {
-                // expected
-            }
 
-            assertEquals(0, reader.read(array, 0, 0));
-            assertEquals(0, array[0]);
-            assertEquals(0, array[1]);
-            assertEquals(0, array[2]);
+        sb = new TextStringBuilder();
+        try {
+            sb.replace(1, 2, "anything");
+            fail("Expected IndexOutOfBoundsException");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
+        try {
+            sb.replace(-1, 1, "anything");
+            fail("Expected IndexOutOfBoundsException");
+        } catch (final IndexOutOfBoundsException e) {
+            // expected
+        }
+    }
 
-            reader.skip(9);
-            assertEquals(-1, reader.read(array, 0, 1));
+    @Test
+    public void testReplace_StringMatcher_String_int_int_int_VaryCount() {
+        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, -1);
+        assertEquals("-x--y-", sb.toString());
 
-            reader.reset();
-            array = new char[30];
-            assertEquals(9, reader.read(array, 0, 30));
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 0);
+        assertEquals("aaxaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 1);
+        assertEquals("-xaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 2);
+        assertEquals("-x-aayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 3);
+        assertEquals("-x--yaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 4);
+        assertEquals("-x--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, 5);
+        assertEquals("-x--y-", sb.toString());
+    }
+
+    @Test
+    public void testReplace_StringMatcher_String_int_int_int_VaryEndIndex() {
+        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 0, -1);
+        assertEquals("aaxaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 2, -1);
+        assertEquals("-xaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 3, -1);
+        assertEquals("-xaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 4, -1);
+        assertEquals("-xaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 5, -1);
+        assertEquals("-x-aayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 6, -1);
+        assertEquals("-x-aayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 7, -1);
+        assertEquals("-x--yaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 8, -1);
+        assertEquals("-x--yaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 9, -1);
+        assertEquals("-x--yaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 10, -1);
+        assertEquals("-x--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, 1000, -1);
+        assertEquals("-x--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        try {
+            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 2, 1, -1);
+            fail("Exception expected!");
+        } catch (final IndexOutOfBoundsException ex) {
+            // expected
         }
+        assertEquals("aaxaaaayaa", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testAsWriter() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("base");
-        try (Writer writer = sb.asWriter()) {
+    public void testReplace_StringMatcher_String_int_int_int_VaryMatcher() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replace((StringMatcher) null, "x", 0, sb.length(), -1);
+        assertEquals("abcbccba", sb.toString());
 
-            writer.write('l');
-            assertEquals("basel", sb.toString());
+        sb.replace(StringMatcherFactory.INSTANCE.charMatcher('a'), "x", 0, sb.length(), -1);
+        assertEquals("xbcbccbx", sb.toString());
 
-            writer.write(new char[] {'i', 'n'});
-            assertEquals("baselin", sb.toString());
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "x", 0, sb.length(), -1);
+        assertEquals("xbxcxx", sb.toString());
 
-            writer.write(new char[] {'n', 'e', 'r'}, 1, 2);
-            assertEquals("baseliner", sb.toString());
+        sb = new TextStringBuilder("A1-A2A3-A4");
+        sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
+        assertEquals("***-******-***", sb.toString());
 
-            writer.write(" rout");
-            assertEquals("baseliner rout", sb.toString());
+        sb = new TextStringBuilder();
+        sb.replace(A_NUMBER_MATCHER, "***", 0, sb.length(), -1);
+        assertEquals("", sb.toString());
+    }
 
-            writer.write("ping that server", 1, 3);
-            assertEquals("baseliner routing", sb.toString());
+    @Test
+    public void testReplace_StringMatcher_String_int_int_int_VaryReplace() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "cb", 0, sb.length(), -1);
+        assertEquals("abcbccba", sb.toString());
 
-            writer.flush(); // no effect
-            assertEquals("baseliner routing", sb.toString());
+        sb = new TextStringBuilder("abcbccba");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-", 0, sb.length(), -1);
+        assertEquals("ab-c-a", sb.toString());
 
-            writer.close(); // no effect
-            assertEquals("baseliner routing", sb.toString());
+        sb = new TextStringBuilder("abcbccba");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "+++", 0, sb.length(), -1);
+        assertEquals("ab+++c+++a", sb.toString());
 
-            writer.write(" hi"); // works after close
-            assertEquals("baseliner routing hi", sb.toString());
+        sb = new TextStringBuilder("abcbccba");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "", 0, sb.length(), -1);
+        assertEquals("abca", sb.toString());
+
+        sb = new TextStringBuilder("abcbccba");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("cb"), null, 0, sb.length(), -1);
+        assertEquals("abca", sb.toString());
+    }
+
+    @Test
+    public void testReplace_StringMatcher_String_int_int_int_VaryStartIndex() {
+        TextStringBuilder sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 0, sb.length(), -1);
+        assertEquals("-x--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 1, sb.length(), -1);
+        assertEquals("aax--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 2, sb.length(), -1);
+        assertEquals("aax--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 3, sb.length(), -1);
+        assertEquals("aax--y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 4, sb.length(), -1);
+        assertEquals("aaxa-ay-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 5, sb.length(), -1);
+        assertEquals("aaxaa-y-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 6, sb.length(), -1);
+        assertEquals("aaxaaaay-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 7, sb.length(), -1);
+        assertEquals("aaxaaaay-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 8, sb.length(), -1);
+        assertEquals("aaxaaaay-", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 9, sb.length(), -1);
+        assertEquals("aaxaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 10, sb.length(), -1);
+        assertEquals("aaxaaaayaa", sb.toString());
 
-            sb.setLength(4); // mix and match
-            writer.write('d');
-            assertEquals("based", sb.toString());
+        sb = new TextStringBuilder("aaxaaaayaa");
+        try {
+            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", 11, sb.length(), -1);
+            fail("Exception expected!");
+        } catch (final IndexOutOfBoundsException ex) {
+            // expected
+        }
+        assertEquals("aaxaaaayaa", sb.toString());
+
+        sb = new TextStringBuilder("aaxaaaayaa");
+        try {
+            sb.replace(StringMatcherFactory.INSTANCE.stringMatcher("aa"), "-", -1, sb.length(), -1);
+            fail("Exception expected!");
+        } catch (final IndexOutOfBoundsException ex) {
+            // expected
         }
+        assertEquals("aaxaaaayaa", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testEqualsIgnoreCase() {
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        final TextStringBuilder sb2 = new TextStringBuilder();
-        assertTrue(sb1.equalsIgnoreCase(sb1));
-        assertTrue(sb1.equalsIgnoreCase(sb2));
-        assertTrue(sb2.equalsIgnoreCase(sb2));
+    public void testReplaceAll_char_char() {
+        final TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceAll('x', 'y');
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll('a', 'd');
+        assertEquals("dbcbccbd", sb.toString());
+        sb.replaceAll('b', 'e');
+        assertEquals("dececced", sb.toString());
+        sb.replaceAll('c', 'f');
+        assertEquals("defeffed", sb.toString());
+        sb.replaceAll('d', 'd');
+        assertEquals("defeffed", sb.toString());
+    }
 
-        sb1.append("abc");
-        assertFalse(sb1.equalsIgnoreCase(sb2));
+    // -----------------------------------------------------------------------
+    @Test
+    public void testReplaceAll_String_String() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceAll((String) null, null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll((String) null, "anything");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll("", null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll("", "anything");
+        assertEquals("abcbccba", sb.toString());
 
-        sb2.append("ABC");
-        assertTrue(sb1.equalsIgnoreCase(sb2));
+        sb.replaceAll("x", "y");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll("a", "d");
+        assertEquals("dbcbccbd", sb.toString());
+        sb.replaceAll("d", null);
+        assertEquals("bcbccb", sb.toString());
+        sb.replaceAll("cb", "-");
+        assertEquals("b-c-", sb.toString());
 
-        sb2.clear().append("abc");
-        assertTrue(sb1.equalsIgnoreCase(sb2));
-        assertTrue(sb1.equalsIgnoreCase(sb1));
-        assertTrue(sb2.equalsIgnoreCase(sb2));
+        sb = new TextStringBuilder("abcba");
+        sb.replaceAll("b", "xbx");
+        assertEquals("axbxcxbxa", sb.toString());
 
-        sb2.clear().append("aBc");
-        assertTrue(sb1.equalsIgnoreCase(sb2));
+        sb = new TextStringBuilder("bb");
+        sb.replaceAll("b", "xbx");
+        assertEquals("xbxxbx", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testEquals() {
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        final TextStringBuilder sb2 = new TextStringBuilder();
-        assertTrue(sb1.equals(sb2));
-        assertTrue(sb1.equals(sb1));
-        assertTrue(sb2.equals(sb2));
-        assertTrue(sb1.equals((Object) sb2));
+    public void testReplaceAll_StringMatcher_String() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceAll((StringMatcher) null, null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll((StringMatcher) null, "anything");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll(StringMatcherFactory.INSTANCE.noneMatcher(), null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll(StringMatcherFactory.INSTANCE.noneMatcher(), "anything");
+        assertEquals("abcbccba", sb.toString());
 
-        sb1.append("abc");
-        assertFalse(sb1.equals(sb2));
-        assertFalse(sb1.equals((Object) sb2));
+        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('x'), "y");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('a'), "d");
+        assertEquals("dbcbccbd", sb.toString());
+        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('d'), null);
+        assertEquals("bcbccb", sb.toString());
+        sb.replaceAll(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-");
+        assertEquals("b-c-", sb.toString());
 
-        sb2.append("ABC");
-        assertFalse(sb1.equals(sb2));
-        assertFalse(sb1.equals((Object) sb2));
+        sb = new TextStringBuilder("abcba");
+        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
+        assertEquals("axbxcxbxa", sb.toString());
 
-        sb2.clear().append("abc");
-        assertTrue(sb1.equals(sb2));
-        assertTrue(sb1.equals((Object) sb2));
+        sb = new TextStringBuilder("bb");
+        sb.replaceAll(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
+        assertEquals("xbxxbx", sb.toString());
 
-        assertFalse(sb1.equals(Integer.valueOf(1)));
-        assertFalse(sb1.equals("abc"));
-    }
+        sb = new TextStringBuilder("A1-A2A3-A4");
+        sb.replaceAll(A_NUMBER_MATCHER, "***");
+        assertEquals("***-******-***", sb.toString());
 
-    @Test
-    public void test_LANG_1131_EqualsWithNullTextStringBuilder() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder();
-        final TextStringBuilder other = null;
-        assertFalse(sb.equals(other));
+        sb = new TextStringBuilder("Dear X, hello X.");
+        sb.replaceAll(StringMatcherFactory.INSTANCE.stringMatcher("X"), "012345678901234567");
+        assertEquals("Dear 012345678901234567, hello 012345678901234567.", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testHashCode() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        final int hc1a = sb.hashCode();
-        final int hc1b = sb.hashCode();
-        assertEquals(0, hc1a);
-        assertEquals(hc1a, hc1b);
-
-        sb.append("abc");
-        final int hc2a = sb.hashCode();
-        final int hc2b = sb.hashCode();
-        assertTrue(hc2a != 0);
-        assertEquals(hc2a, hc2b);
+    public void testReplaceFirst_char_char() {
+        final TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceFirst('x', 'y');
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst('a', 'd');
+        assertEquals("dbcbccba", sb.toString());
+        sb.replaceFirst('b', 'e');
+        assertEquals("decbccba", sb.toString());
+        sb.replaceFirst('c', 'f');
+        assertEquals("defbccba", sb.toString());
+        sb.replaceFirst('d', 'd');
+        assertEquals("defbccba", sb.toString());
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testToString() {
-        final TextStringBuilder sb = new TextStringBuilder("abc");
-        assertEquals("abc", sb.toString());
-    }
+    public void testReplaceFirst_String_String() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceFirst((String) null, null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst((String) null, "anything");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst("", null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst("", "anything");
+        assertEquals("abcbccba", sb.toString());
 
-    // -----------------------------------------------------------------------
-    @Test
-    public void testToStringBuffer() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(new StringBuffer().toString(), sb.toStringBuffer().toString());
+        sb.replaceFirst("x", "y");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst("a", "d");
+        assertEquals("dbcbccba", sb.toString());
+        sb.replaceFirst("d", null);
+        assertEquals("bcbccba", sb.toString());
+        sb.replaceFirst("cb", "-");
+        assertEquals("b-ccba", sb.toString());
 
-        sb.append("junit");
-        assertEquals(new StringBuffer("junit").toString(), sb.toStringBuffer().toString());
+        sb = new TextStringBuilder("abcba");
+        sb.replaceFirst("b", "xbx");
+        assertEquals("axbxcba", sb.toString());
+
+        sb = new TextStringBuilder("bb");
+        sb.replaceFirst("b", "xbx");
+        assertEquals("xbxb", sb.toString());
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testToStringBuilder() {
-        final TextStringBuilder sb = new TextStringBuilder();
-        assertEquals(new StringBuilder().toString(), sb.toStringBuilder().toString());
+    public void testReplaceFirst_StringMatcher_String() {
+        TextStringBuilder sb = new TextStringBuilder("abcbccba");
+        sb.replaceFirst((StringMatcher) null, null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst((StringMatcher) null, "anything");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.noneMatcher(), null);
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.noneMatcher(), "anything");
+        assertEquals("abcbccba", sb.toString());
 
-        sb.append("junit");
-        assertEquals(new StringBuilder("junit").toString(), sb.toStringBuilder().toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('x'), "y");
+        assertEquals("abcbccba", sb.toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('a'), "d");
+        assertEquals("dbcbccba", sb.toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('d'), null);
+        assertEquals("bcbccba", sb.toString());
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.stringMatcher("cb"), "-");
+        assertEquals("b-ccba", sb.toString());
+
+        sb = new TextStringBuilder("abcba");
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
+        assertEquals("axbxcba", sb.toString());
+
+        sb = new TextStringBuilder("bb");
+        sb.replaceFirst(StringMatcherFactory.INSTANCE.charMatcher('b'), "xbx");
+        assertEquals("xbxb", sb.toString());
+
+        sb = new TextStringBuilder("A1-A2A3-A4");
+        sb.replaceFirst(A_NUMBER_MATCHER, "***");
+        assertEquals("***-A2A3-A4", sb.toString());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testLang294() {
-        final TextStringBuilder sb = new TextStringBuilder("\n%BLAH%\nDo more stuff\neven more stuff\n%BLAH%\n");
-        sb.deleteAll("\n%BLAH%");
-        assertEquals("\nDo more stuff\neven more stuff\n", sb.toString());
+    public void testReverse() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals("", sb.reverse().toString());
+
+        sb.clear().append(true);
+        assertEquals("eurt", sb.reverse().toString());
+        assertEquals("true", sb.reverse().toString());
     }
 
     @Test
-    public void testIndexOfLang294() {
-        final TextStringBuilder sb = new TextStringBuilder("onetwothree");
-        sb.deleteFirst("three");
-        assertEquals(-1, sb.indexOf("three"));
+    public void testRightString() {
+        final TextStringBuilder sb = new TextStringBuilder("left right");
+        assertEquals("right", sb.rightString(5));
+        assertEquals("", sb.rightString(0));
+        assertEquals("", sb.rightString(-5));
+        assertEquals("left right", sb.rightString(15));
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testLang295() {
-        final TextStringBuilder sb = new TextStringBuilder("onetwothree");
-        sb.deleteFirst("three");
-        assertFalse(sb.contains('h'), "The contains(char) method is looking beyond the end of the string");
-        assertEquals(-1, sb.indexOf('h'), "The indexOf(char) method is looking beyond the end of the string");
+    public void testSetCharAt() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(0, 'f'));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(-1, 'f'));
+        sb.append("foo");
+        sb.setCharAt(0, 'b');
+        sb.setCharAt(1, 'a');
+        sb.setCharAt(2, 'r');
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.setCharAt(3, '!'));
+        assertEquals("bar", sb.toString());
     }
 
-    // -----------------------------------------------------------------------
     @Test
-    public void testLang412Right() {
+    public void testSetLength() {
         final TextStringBuilder sb = new TextStringBuilder();
-        sb.appendFixedWidthPadRight(null, 10, '*');
-        assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadRight correctly");
+        sb.append("Hello");
+        sb.setLength(2); // shorten
+        assertEquals("He", sb.toString());
+        sb.setLength(2); // no change
+        assertEquals("He", sb.toString());
+        sb.setLength(3); // lengthen
+        assertEquals("He\0", sb.toString());
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.setLength(-1));
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testLang412Left() {
+    public void testSize() {
         final TextStringBuilder sb = new TextStringBuilder();
-        sb.appendFixedWidthPadLeft(null, 10, '*');
-        assertEquals("**********", sb.toString(), "Failed to invoke appendFixedWidthPadLeft correctly");
-    }
+        assertEquals(0, sb.size());
 
-    @Test
-    public void testAsBuilder() {
-        final TextStringBuilder sb = new TextStringBuilder().appendAll("Lorem", " ", "ipsum", " ", "dolor");
-        assertEquals(sb.toString(), sb.build());
+        sb.append("Hello");
+        assertEquals(5, sb.size());
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testAppendCharBuffer() {
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        final CharBuffer buf = CharBuffer.allocate(10);
-        buf.append("0123456789");
-        buf.flip();
-        sb1.append(buf);
-        assertEquals("0123456789", sb1.toString());
-
-        final TextStringBuilder sb2 = new TextStringBuilder();
-        sb2.append(buf, 1, 8);
-        assertEquals("12345678", sb2.toString());
+    public void testStartsWith() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertFalse(sb.startsWith("a"));
+        assertFalse(sb.startsWith(null));
+        assertTrue(sb.startsWith(""));
+        sb.append("abc");
+        assertTrue(sb.startsWith("a"));
+        assertTrue(sb.startsWith("ab"));
+        assertTrue(sb.startsWith("abc"));
+        assertFalse(sb.startsWith("cba"));
     }
 
     // -----------------------------------------------------------------------
     @Test
-    public void testAppendToWriter() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final StringWriter writer = new StringWriter();
-        writer.append("Test ");
-
-        sb.appendTo(writer);
+    public void testSubSequenceIntInt() {
+        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
+        // Start index is negative
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(-1, 5));
 
-        assertEquals("Test 1234567890", writer.toString());
-    }
+        // End index is negative
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(2, -1));
 
-    @Test
-    public void testAppendToStringBuilder() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final StringBuilder builder = new StringBuilder("Test ");
+        // End index greater than length()
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(2, sb.length() + 1));
 
-        sb.appendTo(builder);
+        // Start index greater then end index
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.subSequence(3, 2));
 
-        assertEquals("Test 1234567890", builder.toString());
+        // Normal cases
+        assertEquals("hello", sb.subSequence(0, 5));
+        assertEquals("hello goodbye".subSequence(0, 6), sb.subSequence(0, 6));
+        assertEquals("goodbye", sb.subSequence(6, 13));
+        assertEquals("hello goodbye".subSequence(6, 13), sb.subSequence(6, 13));
     }
 
     @Test
-    public void testAppendToStringBuffer() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final StringBuffer buffer = new StringBuffer("Test ");
+    public void testSubstringInt() {
+        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
+        assertEquals("goodbye", sb.substring(6));
+        assertEquals("hello goodbye".substring(6), sb.substring(6));
+        assertEquals("hello goodbye", sb.substring(0));
+        assertEquals("hello goodbye".substring(0), sb.substring(0));
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(-1));
 
-        sb.appendTo(buffer);
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(15));
 
-        assertEquals("Test 1234567890", buffer.toString());
     }
 
     @Test
-    public void testAppendToCharBuffer() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final String text = "Test ";
-        final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
-        buffer.put(text);
+    public void testSubstringIntInt() {
+        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
+        assertEquals("hello", sb.substring(0, 5));
+        assertEquals("hello goodbye".substring(0, 6), sb.substring(0, 6));
 
-        sb.appendTo(buffer);
+        assertEquals("goodbye", sb.substring(6, 13));
+        assertEquals("hello goodbye".substring(6, 13), sb.substring(6, 13));
 
-        buffer.flip();
-        assertEquals("Test 1234567890", buffer.toString());
+        assertEquals("goodbye", sb.substring(6, 20));
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(-1, 5));
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.substring(15, 20));
     }
 
     @Test
-    public void testAppendCharBufferNull() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final CharBuffer buffer = null;
-        sb.append(buffer);
-        assertEquals("1234567890", sb.toString());
+    public void testToStringIntInt() {
+        final TextStringBuilder sb = new TextStringBuilder("hello goodbye");
+        assertEquals("hello", sb.substring(0, 5));
+        assertEquals("hello goodbye".substring(0, 6), sb.toString(0, 6));
 
-        final TextStringBuilder sb1 = new TextStringBuilder("1234567890");
-        final CharBuffer buffer1 = null;
-        sb.append(buffer1, 0, 0);
-        assertEquals("1234567890", sb1.toString());
+        assertEquals("goodbye", sb.toString(6, 7));
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.toString(-1, 5));
+
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.toString(15, 20));
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testAppendCharBufferException() throws Exception {
-        final TextStringBuilder sb = new TextStringBuilder("1234567890");
-        final String text = "Test";
-        final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
-        buffer.put(text);
-        buffer.flip();
-        try {
-            sb.append(buffer, -1, 12);
-        } catch (final StringIndexOutOfBoundsException e) {
-            assertEquals("startIndex must be valid", e.getMessage());
-        }
+    public void testToCharArray() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(0, sb.toCharArray().length);
 
-        try {
-            sb.append(buffer, 0, -1);
-        } catch (final StringIndexOutOfBoundsException e) {
-            assertEquals("length must be valid", e.getMessage());
-        }
+        char[] a = sb.toCharArray();
+        assertNotNull(a, "toCharArray() result is null");
+        assertEquals(0, a.length, "toCharArray() result is too large");
 
-        sb.append(buffer);
-        assertEquals("1234567890Test", sb.toString());
+        sb.append("junit");
+        a = sb.toCharArray();
+        assertEquals(5, a.length, "toCharArray() result incorrect length");
+        assertTrue(Arrays.equals("junit".toCharArray(), a), "toCharArray() result does not match");
     }
 
     @Test
-    public void testAppendCharSequence() {
-        final CharSequence obj0 = null;
-        final CharSequence obj1 = new TextStringBuilder("test1");
-        final CharSequence obj2 = new StringBuilder("test2");
-        final CharSequence obj3 = new StringBuffer("test3");
-        final CharBuffer obj4 = CharBuffer.wrap("test4".toCharArray());
+    public void testToCharArrayIntInt() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(0, sb.toCharArray(0, 0).length);
 
-        final TextStringBuilder sb0 = new TextStringBuilder();
-        assertEquals("", sb0.append(obj0).toString());
+        sb.append("junit");
+        char[] a = sb.toCharArray(0, 20); // too large test
+        assertEquals(5, a.length, "toCharArray(int,int) result incorrect length");
+        assertTrue(Arrays.equals("junit".toCharArray(), a), "toCharArray(int,int) result does not match");
 
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        assertEquals("test1", sb1.append(obj1).toString());
+        a = sb.toCharArray(0, 4);
+        assertEquals(4, a.length, "toCharArray(int,int) result incorrect length");
+        assertTrue(Arrays.equals("juni".toCharArray(), a), "toCharArray(int,int) result does not match");
 
-        final TextStringBuilder sb2 = new TextStringBuilder();
-        assertEquals("test2", sb2.append(obj2).toString());
+        a = sb.toCharArray(0, 4);
+        assertEquals(4, a.length, "toCharArray(int,int) result incorrect length");
+        assertTrue(Arrays.equals("juni".toCharArray(), a), "toCharArray(int,int) result does not match");
 
-        final TextStringBuilder sb3 = new TextStringBuilder();
-        assertEquals("test3", sb3.append(obj3).toString());
+        a = sb.toCharArray(0, 1);
+        assertNotNull(a, "toCharArray(int,int) result is null");
 
-        final TextStringBuilder sb4 = new TextStringBuilder();
-        assertEquals("test4", sb4.append(obj4).toString());
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.toCharArray(-1, 5));
 
-        final TextStringBuilder sb5 = new TextStringBuilder();
-        assertEquals("", sb5.append(obj0, 0, 0).toString());
+        assertThrows(IndexOutOfBoundsException.class, () -> sb.toCharArray(6, 5));
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testAppendStringBuilderNull() {
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        final StringBuilder b = null;
-        assertEquals("", sb1.append(b).toString());
-
-        final TextStringBuilder sb2 = new TextStringBuilder();
-        assertEquals("", sb2.append(b, 0, 0).toString());
+    public void testToString() {
+        final TextStringBuilder sb = new TextStringBuilder("abc");
+        assertEquals("abc", sb.toString());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testAppendln() {
-        final TextStringBuilder sb1 = new TextStringBuilder();
-        final char ch = 'c';
-        assertEquals("c" + System.lineSeparator(), sb1.appendln(ch).toString());
+    public void testToStringBuffer() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(new StringBuffer().toString(), sb.toStringBuffer().toString());
+
+        sb.append("junit");
+        assertEquals(new StringBuffer("junit").toString(), sb.toStringBuffer().toString());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testAppendTakingTwoIntsWithZeroThrowsStringIndexOutOfBoundsException() {
-        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
-            final Charset charset = Charset.defaultCharset();
-            final ByteBuffer byteBuffer = charset.encode("end < start");
-            final CharBuffer charBuffer = charset.decode(byteBuffer);
+    public void testToStringBuilder() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals(new StringBuilder().toString(), sb.toStringBuilder().toString());
 
-            new TextStringBuilder(630).append(charBuffer, 0, 630);
-        });
+        sb.append("junit");
+        assertEquals(new StringBuilder("junit").toString(), sb.toStringBuilder().toString());
     }
 
+    // -----------------------------------------------------------------------
     @Test
-    public void testAppendTakingTwoIntsWithIndexOutOfBoundsThrowsStringIndexOutOfBoundsExceptionTwo() {
-        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
-            final Charset charset = Charset.defaultCharset();
-            final ByteBuffer byteBuffer = charset.encode("asdf");
-            final CharBuffer charBuffer = charset.decode(byteBuffer);
+    public void testTrim() {
+        final TextStringBuilder sb = new TextStringBuilder();
+        assertEquals("", sb.reverse().toString());
 
-            new TextStringBuilder().append(charBuffer, 933, 654);
-        });
-    }
+        sb.clear().append(" \u0000 ");
+        assertEquals("", sb.trim().toString());
 
-    @Test
-    public void testDeleteCharAtWithNegative() {
-        assertThatExceptionOfType(StringIndexOutOfBoundsException.class).isThrownBy(() -> {
-            new TextStringBuilder().deleteCharAt((-1258));
-        });
+        sb.clear().append(" \u0000 a b c");
+        assertEquals("a b c", sb.trim().toString());
+
+        sb.clear().append("a b c \u0000 ");
+        assertEquals("a b c", sb.trim().toString());
+
+        sb.clear().append(" \u0000 a b c \u0000 ");
+        assertEquals("a b c", sb.trim().toString());
+
+        sb.clear().append("a b c");
+        assertEquals("a b c", sb.trim().toString());
     }
 
 }


[commons-text] 05/06: Add Add org.apache.commons.text.TextStringBuilder.toString(int, int).

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git

commit acf5e1baa28e5bdf0134b5abc7f7895381a73242
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 28 15:10:26 2020 -0400

    Add Add org.apache.commons.text.TextStringBuilder.toString(int, int).
---
 src/changes/changes.xml                                    |  1 +
 .../java/org/apache/commons/text/TextStringBuilder.java    | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bf5a2d5..d10edb9 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -57,6 +57,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action                  type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.text.matcher.StringMatcher.isMatch(CharSequence, int, int, int).</action>
     <action                  type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.text.lookup.StringLookupFactory.functionStringLookup(Function&lt;String, V&gt;).</action>
     <action                  type="add" dev="ggregory" due-to="Gary Gregory">Add BiStringLookup and implementation BiFunctionStringLookup.</action>
+    <action                  type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.text.TextStringBuilder.toString(int, int).</action>
     <action                  type="update" dev="ggregory" due-to="Gary Gregory">[test] junit-jupiter 5.5.1 -> 5.5.2.</action>
     <action                  type="update" dev="ggregory" due-to="Gary Gregory">[test] org.assertj:assertj-core 3.13.2 -> 3.16.1.</action>
     <action                  type="update" dev="ggregory" due-to="Gary Gregory">[build] com.puppycrawl.tools:checkstyle 8.23 -> 8.27.</action>
diff --git a/src/main/java/org/apache/commons/text/TextStringBuilder.java b/src/main/java/org/apache/commons/text/TextStringBuilder.java
index b94be8d..58af923 100644
--- a/src/main/java/org/apache/commons/text/TextStringBuilder.java
+++ b/src/main/java/org/apache/commons/text/TextStringBuilder.java
@@ -3174,6 +3174,20 @@ public class TextStringBuilder implements CharSequence, Appendable, Serializable
     }
 
     /**
+     * Extracts a portion of this string builder as a string.
+     *
+     * @param startIndex The initial offset
+     * @param count the desired length
+     * @return The new string
+     * @throws IndexOutOfBoundsException if the index is invalid
+     * @since 1.9
+     */
+    public String toString(final int startIndex, int count) {
+        validateRange(startIndex, startIndex + count);
+        return new String(buffer, startIndex, count);
+    }
+
+    /**
      * Gets a StringBuffer version of the string builder, creating a new instance each time the method is called.
      *
      * @return The builder as a StringBuffer