public void inquireCandidatePosition() {
    Component source = getClientComponent();
    if (source == null) {
      return;
    }
    // This call should return immediately just to cause
    // InputMethodRequests.getTextLocation be called within
    // AWT Event thread.  Otherwise, a potential deadlock
    // could happen.
    Runnable r =
        new Runnable() {
          public void run() {
            int x = 0;
            int y = 0;
            Component client = getClientComponent();

            if (client != null) {
              if (haveActiveClient()) {
                Rectangle rc = inputContext.getTextLocation(TextHitInfo.leading(0));
                x = rc.x;
                y = rc.y + rc.height;
              } else {
                Point pt = client.getLocationOnScreen();
                Dimension size = client.getSize();
                x = pt.x;
                y = pt.y + size.height;
              }
            }

            openCandidateWindow(awtFocussedComponentPeer, x, y);
          }
        };
    WToolkit.postEvent(WToolkit.targetToAppContext(source), new InvocationEvent(source, r));
  }
  public void sendInputMethodEvent(
      int id,
      long when,
      String text,
      int[] clauseBoundary,
      String[] clauseReading,
      int[] attributeBoundary,
      byte[] attributeValue,
      int commitedTextLength,
      int caretPos,
      int visiblePos) {

    AttributedCharacterIterator iterator = null;

    if (text != null) {

      // construct AttributedString
      AttributedString attrStr = new AttributedString(text);

      // set Language Information
      attrStr.addAttribute(Attribute.LANGUAGE, Locale.getDefault(), 0, text.length());

      // set Clause and Reading Information
      if (clauseBoundary != null
          && clauseReading != null
          && clauseReading.length != 0
          && clauseBoundary.length == clauseReading.length + 1
          && clauseBoundary[0] == 0
          && clauseBoundary[clauseReading.length] == text.length()) {
        for (int i = 0; i < clauseBoundary.length - 1; i++) {
          attrStr.addAttribute(
              Attribute.INPUT_METHOD_SEGMENT,
              new Annotation(null),
              clauseBoundary[i],
              clauseBoundary[i + 1]);
          attrStr.addAttribute(
              Attribute.READING,
              new Annotation(clauseReading[i]),
              clauseBoundary[i],
              clauseBoundary[i + 1]);
        }
      } else {
        // if (clauseBoundary != null)
        //    System.out.println("Invalid clause information!");

        attrStr.addAttribute(
            Attribute.INPUT_METHOD_SEGMENT, new Annotation(null), 0, text.length());
        attrStr.addAttribute(Attribute.READING, new Annotation(""), 0, text.length());
      }

      // set Hilight Information
      if (attributeBoundary != null
          && attributeValue != null
          && attributeValue.length != 0
          && attributeBoundary.length == attributeValue.length + 1
          && attributeBoundary[0] == 0
          && attributeBoundary[attributeValue.length] == text.length()) {
        for (int i = 0; i < attributeBoundary.length - 1; i++) {
          InputMethodHighlight highlight;
          switch (attributeValue[i]) {
            case ATTR_TARGET_CONVERTED:
              highlight = InputMethodHighlight.SELECTED_CONVERTED_TEXT_HIGHLIGHT;
              break;
            case ATTR_CONVERTED:
              highlight = InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT;
              break;
            case ATTR_TARGET_NOTCONVERTED:
              highlight = InputMethodHighlight.SELECTED_RAW_TEXT_HIGHLIGHT;
              break;
            case ATTR_INPUT:
            case ATTR_INPUT_ERROR:
            default:
              highlight = InputMethodHighlight.UNSELECTED_RAW_TEXT_HIGHLIGHT;
              break;
          }
          attrStr.addAttribute(
              TextAttribute.INPUT_METHOD_HIGHLIGHT,
              highlight,
              attributeBoundary[i],
              attributeBoundary[i + 1]);
        }
      } else {
        // if (attributeBoundary != null)
        //    System.out.println("Invalid attribute information!");

        attrStr.addAttribute(
            TextAttribute.INPUT_METHOD_HIGHLIGHT,
            InputMethodHighlight.UNSELECTED_CONVERTED_TEXT_HIGHLIGHT,
            0,
            text.length());
      }

      // get iterator
      iterator = attrStr.getIterator();
    }

    Component source = getClientComponent();
    if (source == null) return;

    InputMethodEvent event =
        new InputMethodEvent(
            source,
            id,
            when,
            iterator,
            commitedTextLength,
            TextHitInfo.leading(caretPos),
            TextHitInfo.leading(visiblePos));
    WToolkit.postEvent(WToolkit.targetToAppContext(source), event);
  }