/**
 * MVEL (The MVFLEX Expression Language)
 *
 * Copyright (C) 2007 Christopher Brock, MVFLEX/Valhalla Project and the Codehaus
 *
 * 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.mvel.util;

public class StringAppender implements CharSequence {
    private static final int DEFAULT_SIZE = 15;

    private char[] str;
    private int capacity;
    private int size = 0;


    public StringAppender() {
        str = new char[capacity = DEFAULT_SIZE];
    }

    public StringAppender(int capacity) {
        str = new char[this.capacity = capacity];
    }

    public StringAppender(char c) {
        (str = new char[this.capacity = DEFAULT_SIZE])[0] = c;
    }

    public StringAppender(char[] s) {
        capacity = size = (str = s).length;
    }

    public StringAppender(CharSequence s) {
        str = new char[this.capacity = size = s.length()];
        for (int i = 0; i < str.length; i++)
            str[i] = s.charAt(i);
    }

    public StringAppender(String s) {
        capacity = size = (str = s.toCharArray()).length;
    }

    public StringAppender append(char[] chars) {
        if (chars.length > (capacity - size)) grow(chars.length);
        for (int i = 0; i < chars.length; size++) {
            str[size] = chars[i++];
        }
  //      size += chars.length;
        return this;
    }

    public StringAppender append(Object o) {
        return append(String.valueOf(o));
    }

    public StringAppender append(CharSequence s) {
        if (s.length() > (capacity - size)) grow(s.length());
        for (int i = 0; size < capacity; size++) {
            str[size] = s.charAt(i++);
        }
     //   size += s.length();
        return this;
    }

    public StringAppender append(String s) {
        if (s == null) return this;

        int len = s.length();
        if (len > (capacity - size)) {
            grow(len);
        }

        s.getChars(0, len, str, size);
        size += len;

        return this;
    }

    public StringAppender append(char c) {
        if (size >= capacity) grow(1);
        str[size++] = c;
        return this;
    }

    public int length() {
        return size;
    }

    private void grow(int s) {
        if (capacity == 0) capacity = DEFAULT_SIZE;
        final char[] newArray = new char[capacity += s * 2];
        System.arraycopy(str, 0, newArray, 0, size);
        str = newArray;
    }

    public char[] getChars(int start, int count) {
        char[] chars = new char[count];
        System.arraycopy(str, start, chars, 0, count);
        return chars;
    }

    public char[] toChars() {
        char[] chars = new char[size];
        System.arraycopy(str, 0, chars, 0, size);
        return chars;
    }


    public String toString() {
        if (size == capacity) return new String(str);
        else return new String(str, 0, size);
    }


    public void getChars(int start, int count, char[] target, int offset) {
        int delta = offset;
        for (int i = start; i < count; i++) {
            target[delta++] = str[i];
        }
    }

    public void reset() {
        size = 0;
    }

    public char charAt(int index) {
        return str[index];
    }

    public CharSequence subSequence(int start, int end) {
        return new String(str, start, (end - start));
    }


}


@@ -733,16 +733,61 @@
 til;%0D%0A%0D%0A
+import static java.lang.System.arraycopy;%0D%0A%0D%0A
 public c
@@ -1939,32 +1939,315 @@
 this;%0D%0A    %7D%0D%0A%0D%0A
+    public StringAppender append(char%5B%5D chars, int start, int length) %7B%0D%0A        if (length %3E (capacity - size)) grow(length);%0D%0A        int x = start + length;%0D%0A        for (int i = start; i %3C x; i++) %7B%0D%0A            str%5Bsize++%5D = chars%5Bi%5D;%0D%0A        %7D%0D%0A        return this;%0D%0A    %7D%0D%0A%0D%0A
     public Strin
@@ -2550,39 +2550,8 @@
  %7D%0D%0A
-     //   size += s.length();%0D%0A
     
@@ -3211,39 +3211,32 @@
  * 2%5D;%0D%0A        
-System.
 arraycopy(str, 0
@@ -3385,39 +3385,32 @@
 ount%5D;%0D%0A        
-System.
 arraycopy(str, s
@@ -3537,24 +3537,24 @@
 size%5D;%0D%0A
+
         
 System.a
@@ -3545,23 +3545,16 @@
         
-System.
 arraycop

fix to StringAppender