/**
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.informantproject.api;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Trask Stalnaker
 * @since 0.5
 */
// not thread safe
public class LargeStringBuilder implements Appendable {

    private static final int LARGE_THRESHOLD = 100;
    private static final int BLOCK_SIZE = 200;

    final List<CharSequence> csqs = new ArrayList<CharSequence>();
    private StringBuilder curr;
    int count;

    // part of the contract is that char sequences should not be modified after appending
    // this is not an issue with immutable char sequences like String and LargeCharSequence (below)
    // but is an issue with mutable char sequences like StringBuilder and StringBuffer
    public LargeStringBuilder append(CharSequence csq) {
        if (csq.length() >= LARGE_THRESHOLD) {
            if (curr != null) {
                csqs.add(curr);
                curr = null;
            }
            csqs.add(csq);
        } else {
            if (curr == null) {
                curr = new StringBuilder(BLOCK_SIZE);
            }
            if (curr.length() + csq.length() > BLOCK_SIZE) {
                csqs.add(curr);
                curr = new StringBuilder(BLOCK_SIZE);
            }
            curr.append(csq);
        }
        count += csq.length();
        return this;
    }

    public Appendable append(CharSequence csq, int start, int end) throws IOException {
        // this is not currently needed
        throw new UnsupportedOperationException();
    }

    public Appendable append(char c) throws IOException {
        if (curr == null) {
            curr = new StringBuilder(BLOCK_SIZE);
        }
        if (curr.length() + 1 > BLOCK_SIZE) {
            csqs.add(curr);
            curr = new StringBuilder(BLOCK_SIZE);
        }
        curr.append(c);
        count++;
        return this;
    }

    public CharSequence build() {
        if (curr != null) {
            csqs.add(curr);
            curr = null;
        }
        return new LargeCharSequence(csqs, count);
    }

    @Override
    public String toString() {
        return build().toString();
    }
}

@@ -1024,16 +1024,22 @@
 private 
+final 
 StringBu
@@ -1048,16 +1048,48 @@
 der curr
+ = new StringBuilder(BLOCK_SIZE)
 ;%0A    in
@@ -1495,246 +1495,60 @@
     
-if (curr != null) %7B%0A                csqs.add(curr);%0A                curr = null;%0A            %7D%0A            csqs.add(csq);%0A        %7D else %7B%0A            if (curr == null) %7B%0A                curr = new StringBuilder(BLOCK_SIZE);%0A            %7D
+flush();%0A            csqs.add(csq);%0A        %7D else %7B
 %0A   
@@ -1626,32 +1626,43 @@
    csqs.add(curr
+.toString()
 );%0A             
@@ -1672,39 +1672,20 @@
 curr
- = new StringBuilder(BLOCK_SIZE
+.setLength(0
 );%0A 
@@ -2044,96 +2044,8 @@
 n %7B%0A
-        if (curr == null) %7B%0A            curr = new StringBuilder(BLOCK_SIZE);%0A        %7D%0A
     
@@ -2103,32 +2103,43 @@
    csqs.add(curr
+.toString()
 );%0A            c
@@ -2145,39 +2145,20 @@
 curr
- = new StringBuilder(BLOCK_SIZE
+.setLength(0
 );%0A 
@@ -2265,24 +2265,126 @@
 e build() %7B%0A
+        flush();%0A        return new LargeCharSequence(csqs, count);%0A    %7D%0A%0A    private void flush() %7B%0A
         if (
@@ -2424,16 +2424,27 @@
 add(curr
+.toString()
 );%0A     
@@ -2458,77 +2458,32 @@
 curr
- = null;%0A        %7D%0A        return new LargeCharSequence(csqs, count);
+.setLength(0);%0A        %7D
 %0A   

Optimize LargeStringBuilder