/**
   * Move the cursor <i>where</i> characters, withough checking the current buffer.
   *
   * @see #where
   * @param where the number of characters to move to the right or left.
   */
  private final void moveInternal(final int where) throws IOException {
    // debug ("move cursor " + where + " ("
    // + buf.cursor + " => " + (buf.cursor + where) + ")");
    buf.cursor += where;

    char c;

    if (where < 0) {
      int len = 0;
      for (int i = buf.cursor; i < buf.cursor - where; i++) {
        if (buf.getBuffer().charAt(i) == '\t') len += TAB_WIDTH;
        else len++;
      }

      char cbuf[] = new char[len];
      Arrays.fill(cbuf, BACKSPACE);
      out.write(cbuf);

      return;
    } else if (buf.cursor == 0) {
      return;
    } else if (mask != null) {
      c = mask.charValue();
    } else {
      printCharacters(buf.buffer.substring(buf.cursor - where, buf.cursor).toCharArray());
      return;
    }

    // null character mask: don't output anything
    if (NULL_MASK.equals(mask)) {
      return;
    }

    printCharacters(c, Math.abs(where));
  }
  /**
   * Clear the buffer and add its contents to the history.
   *
   * @return the former contents of the buffer.
   */
  final String finishBuffer() {
    String str = buf.buffer.toString();

    // we only add it to the history if the buffer is not empty
    // and if mask is null, since having a mask typically means
    // the string was a password. We clear the mask after this call
    if (str.length() > 0) {
      if (mask == null && useHistory) {
        history.addToHistory(str);
      } else {
        mask = null;
      }
    }

    history.moveToEnd();

    buf.buffer.setLength(0);
    buf.cursor = 0;

    return str;
  }