/*
   * @see org.eclipse.jface.text.ITextStore#get(int)
   */
  public char get(int offset) {
    if (fReplaceList.size() == 0) return fSource.get(offset);

    Replace firstReplace = (Replace) fReplaceList.get(0);
    Replace lastReplace = (Replace) fReplaceList.get(fReplaceList.size() - 1);

    // before
    if (offset < firstReplace.newOffset) {
      return fSource.get(offset);

      // after
    } else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
      int delta = getDelta(lastReplace);
      return fSource.get(offset - delta);

    } else if (ASSERT_SEQUENTIALITY) {
      throw new IllegalArgumentException();

    } else {

      int delta = 0;
      for (Iterator i = fReplaceList.iterator(); i.hasNext(); ) {
        Replace replace = (Replace) i.next();

        if (offset < replace.newOffset) return fSource.get(offset - delta);
        else if (offset < replace.newOffset + replace.text.length())
          return replace.text.charAt(offset - replace.newOffset);

        delta = getDelta(replace);
      }

      return fSource.get(offset - delta);
    }
  }
  /** Commits all buffered replace commands. */
  private void commit() {

    if (fReplaceList.size() == 0) return;

    StringBuffer buffer = new StringBuffer();

    int delta = 0;
    for (Iterator i = fReplaceList.iterator(); i.hasNext(); ) {
      Replace replace = (Replace) i.next();

      int offset = buffer.length() - delta;
      buffer.append(fSource.get(offset, replace.offset - offset));
      buffer.append(replace.text);
      delta = getDelta(replace);
    }

    int offset = buffer.length() - delta;
    buffer.append(fSource.get(offset, fSource.getLength() - offset));

    fSource.set(buffer.toString());
    fReplaceList.clear();
  }
  /*
   * @see org.eclipse.jface.text.ITextStore#get(int, int)
   */
  public String get(int offset, int length) {

    if (fReplaceList.size() == 0) return fSource.get(offset, length);

    Replace firstReplace = (Replace) fReplaceList.get(0);
    Replace lastReplace = (Replace) fReplaceList.get(fReplaceList.size() - 1);

    // before
    if (offset + length <= firstReplace.newOffset) {
      return fSource.get(offset, length);

      // after
    } else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
      int delta = getDelta(lastReplace);
      return fSource.get(offset - delta, length);

    } else if (ASSERT_SEQUENTIALITY) {
      throw new IllegalArgumentException();

    } else {

      int delta = 0;
      for (Iterator i = fReplaceList.iterator(); i.hasNext(); ) {
        Replace replace = (Replace) i.next();

        if (offset + length < replace.newOffset) {
          return fSource.get(offset - delta, length);

        } else if (offset >= replace.newOffset
            && offset + length <= replace.newOffset + replace.text.length()) {
          return replace.text.substring(
              offset - replace.newOffset, offset - replace.newOffset + length);

        } else if (offset >= replace.newOffset + replace.text.length()) {
          delta = getDelta(replace);
          continue;

        } else {
          commit();
          return fSource.get(offset, length);
        }
      }

      return fSource.get(offset - delta, length);
    }
  }
  /*
   * @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
   */
  public void replace(int offset, int length, String text) {
    if (text == null) text = ""; // $NON-NLS-1$

    if (fReplaceList.size() == 0) {
      fReplaceList.add(new Replace(offset, offset, length, text));

    } else {
      Replace firstReplace = (Replace) fReplaceList.get(0);
      Replace lastReplace = (Replace) fReplaceList.get(fReplaceList.size() - 1);

      // backward
      if (offset + length <= firstReplace.newOffset) {
        int delta = text.length() - length;
        if (delta != 0) {
          for (Iterator i = fReplaceList.iterator(); i.hasNext(); ) {
            Replace replace = (Replace) i.next();
            replace.newOffset += delta;
          }
        }

        fReplaceList.add(0, new Replace(offset, offset, length, text));

        // forward
      } else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
        int delta = getDelta(lastReplace);
        fReplaceList.add(new Replace(offset - delta, offset, length, text));

      } else if (ASSERT_SEQUENTIALITY) {
        throw new IllegalArgumentException();

      } else {
        commit();
        fSource.replace(offset, length, text);
      }
    }
  }
  /*
   * @see org.eclipse.jface.text.ITextStore#getLength()
   */
  public int getLength() {
    if (fReplaceList.size() == 0) return fSource.getLength();

    Replace lastReplace = (Replace) fReplaceList.get(fReplaceList.size() - 1);
    return fSource.getLength() + getDelta(lastReplace);
  }
 /*
  * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
  */
 public void set(String text) {
   fSource.set(text);
   fReplaceList.clear();
 }