@Override
  public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {

    int offs = -1;

    if (!isAllocationValid()) {
      Rectangle alloc = a.getBounds();
      setSize(alloc.width, alloc.height);
    }

    // Get the child view for the line at (x,y), and ask it for the
    // specific offset.
    Rectangle alloc = getInsideAllocation(a);
    View v = getViewAtPoint((int) x, (int) y, alloc);
    if (v != null) {
      offs = v.viewToModel(x, y, alloc, bias);
    }

    // Code folding may have hidden the last line.  If so, return the last
    // visible offset instead of the last offset.
    if (host.isCodeFoldingEnabled()
        && v == getView(getViewCount() - 1)
        && offs == v.getEndOffset() - 1) {
      offs = host.getLastVisibleOffset();
    }

    return offs;
  }
  /**
   * Provides a mapping from the view coordinate space to the logical coordinate space of the model.
   *
   * @param x x coordinate of the view location to convert >= 0
   * @param y y coordinate of the view location to convert >= 0
   * @param a the allocated region to render into
   * @param bias either <code>Position.Bias.Forward</code> or <code>Position.Bias.Backward</code>
   * @return the location within the model that best represents the given point in the view &gt;= 0
   * @see View#viewToModel
   */
  public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
    Rectangle alloc = getInsideAllocation(a);
    if (isBefore((int) x, (int) y, alloc)) {
      // point is before the range represented
      int retValue = -1;

      try {
        retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, a, EAST, bias);
      } catch (BadLocationException ble) {
      } catch (IllegalArgumentException iae) {
      }
      if (retValue == -1) {
        retValue = getStartOffset();
        bias[0] = Position.Bias.Forward;
      }
      return retValue;
    } else if (isAfter((int) x, (int) y, alloc)) {
      // point is after the range represented.
      int retValue = -1;
      try {
        retValue = getNextVisualPositionFrom(-1, Position.Bias.Forward, a, WEST, bias);
      } catch (BadLocationException ble) {
      } catch (IllegalArgumentException iae) {
      }

      if (retValue == -1) {
        // NOTE: this could actually use end offset with backward.
        retValue = getEndOffset() - 1;
        bias[0] = Position.Bias.Forward;
      }
      return retValue;
    } else {
      // locate the child and pass along the request
      View v = getViewAtPoint((int) x, (int) y, alloc);
      if (v != null) {
        return v.viewToModel(x, y, alloc, bias);
      }
    }
    return -1;
  }