Program: 152042
Project: 152042
Buggy source:
/** 
 * Replaces the specified run of text with the supplied new text.
 * @param offset a starting (cursor) position for the edit.
 * @param length the length of the area to replace with any new text. Can be negativeto "edit leftwards".
 * @param text text to insert at the offset, or "".
 * @param undoId an id used to group compound edits for undo (-1 if not undoable).
 * @return the new cursor position, or -1 if the edit was rejected.
 */
public int replace(final int offset,final int length,final String text,int undoId){
  int docLength=_text.length();
  int insLength=text.length();
  final int cutStart=Math.max(0,offset + Math.min(length,0));
  int cutEnd=Math.min(docLength,offset + Math.max(length,0));
  String ntext=new StringBuilder().append(_text,0,cutStart).append(text).append(_text,cutEnd,docLength).toString();
  if (!validateEdit(_text,ntext)) {
    return -1;
  }
  if (undoId > 0) {
    if (undoId != _lastUndoId) {
      _undosup.postEdit(_compoundEdit=new AbstractUndoableEdit(){
        public boolean addEdit(        UndoableEdit edit){
          return edit.isSignificant() ? false : _edits.add(edit);
        }
        public void undo(){
          super.undo();
          for (int ii=_edits.size() - 1; ii >= 0; ii--) {
            _edits.get(ii).undo();
          }
        }
        public void redo(){
          super.redo();
          for (int ii=0, nn=_edits.size(); ii < nn; ii++) {
            _edits.get(ii).redo();
          }
        }
        protected ArrayList<UndoableEdit> _edits=new ArrayList<UndoableEdit>();
      }
);
    }
    final String otext=_text.substring(cutStart,cutEnd);
    _compoundEdit.addEdit(new AbstractUndoableEdit(){
      public void undo(){
        super.undo();
        replace(cutStart,text.length(),otext,-1);
      }
      public void redo(){
        super.redo();
        replace(offset,length,text,-1);
      }
      public boolean isSignificant(){
        return false;
      }
    }
);
  }
  _lastUndoId=undoId;
  _text=ntext;
  int cutLength=cutEnd - cutStart;
  if (cutLength > 0) {
    notify(false,cutStart,cutLength);
  }
  if (insLength > 0) {
    notify(true,cutEnd,insLength);
  }
  return cutStart + insLength;
}

Fixed version (ground truth):
/** 
 * Replaces the specified run of text with the supplied new text.
 * @param offset a starting (cursor) position for the edit.
 * @param length the length of the area to replace with any new text. Can be negativeto "edit leftwards".
 * @param text text to insert at the offset, or "".
 * @param undoId an id used to group compound edits for undo (-1 if not undoable).
 * @return the new cursor position, or -1 if the edit was rejected.
 */
public int replace(final int offset,final int length,final String text,int undoId){
  int docLength=_text.length();
  int insLength=text.length();
  final int cutStart=Math.max(0,offset + Math.min(length,0));
  int cutEnd=Math.min(docLength,offset + Math.max(length,0));
  String ntext=new StringBuilder().append(_text,0,cutStart).append(text).append(_text,cutEnd,docLength).toString();
  if (!validateEdit(_text,ntext)) {
    return -1;
  }
  if (undoId > 0) {
    if (undoId != _lastUndoId) {
      _undosup.postEdit(_compoundEdit=new AbstractUndoableEdit(){
        public boolean addEdit(        UndoableEdit edit){
          return edit.isSignificant() ? false : _edits.add(edit);
        }
        public void undo(){
          super.undo();
          for (int ii=_edits.size() - 1; ii >= 0; ii--) {
            _edits.get(ii).undo();
          }
        }
        public void redo(){
          super.redo();
          for (int ii=0, nn=_edits.size(); ii < nn; ii++) {
            _edits.get(ii).redo();
          }
        }
        protected ArrayList<UndoableEdit> _edits=new ArrayList<UndoableEdit>();
      }
);
    }
    final String otext=_text.substring(cutStart,cutEnd);
    _compoundEdit.addEdit(new AbstractUndoableEdit(){
      public void undo(){
        super.undo();
        replace(cutStart,text.length(),otext,-1);
      }
      public void redo(){
        super.redo();
        replace(offset,length,text,-1);
      }
      public boolean isSignificant(){
        return false;
      }
    }
);
  }
  _lastUndoId=undoId;
  _text=ntext;
  int cutLength=cutEnd - cutStart;
  if (cutLength > 0) {
    notify(false,cutStart,cutLength);
  }
  if (insLength > 0) {
    notify(true,cutStart,insLength);
  }
  return cutStart + insLength;
}