private static void putSpecialKey(
     Map<CompactKeyEvent, ProtoCommands.KeyEvent> table,
     int scanCode,
     ProtoCommands.KeyEvent.SpecialKey specialKey) {
   for (boolean shift : new boolean[] {true, false}) {
     for (boolean alt : new boolean[] {true, false}) {
       for (boolean ctrl : new boolean[] {true, false}) {
         int metaState = 0;
         ProtoCommands.KeyEvent.Builder builder =
             ProtoCommands.KeyEvent.newBuilder().setSpecialKey(specialKey);
         if (shift) {
           metaState |= android.view.KeyEvent.META_SHIFT_ON;
           builder.addModifierKeys(ModifierKey.SHIFT);
         }
         if (alt) {
           metaState |= android.view.KeyEvent.META_ALT_ON;
           builder.addModifierKeys(ModifierKey.ALT);
         }
         if (ctrl) {
           metaState |= android.view.KeyEvent.META_CTRL_ON;
           builder.addModifierKeys(ModifierKey.CTRL);
         }
         putUnique(
             table,
             new CompactKeyEvent(scanCode, getCompactMetaState(metaState)),
             builder.build());
       }
     }
   }
 }
    @Override
    public ProtoCommands.KeyEvent getMozcKeyEvent(android.view.KeyEvent keyEvent) {
      int metaState = keyEvent.getMetaState();
      int unicodeChar = keyEvent.getUnicodeChar();
      int keyCode = keyEvent.getKeyCode();
      ProtoCommands.KeyEvent.Builder builder = ProtoCommands.KeyEvent.newBuilder();
      switch (keyCode) {
        case android.view.KeyEvent.KEYCODE_SPACE:
          builder.setSpecialKey(SpecialKey.SPACE);
          break;
        case android.view.KeyEvent.KEYCODE_DEL:
          builder.setSpecialKey(SpecialKey.BACKSPACE);
          break;
        case android.view.KeyEvent.KEYCODE_TAB:
          builder.setSpecialKey(SpecialKey.TAB);
          break;
        case android.view.KeyEvent.KEYCODE_ENTER:
          builder.setSpecialKey(SpecialKey.ENTER);
          break;
        case android.view.KeyEvent.KEYCODE_HOME:
          builder.setSpecialKey(SpecialKey.HOME);
          break;
        case android.view.KeyEvent.KEYCODE_PAGE_UP:
          builder.setSpecialKey(SpecialKey.PAGE_UP);
          break;
        case android.view.KeyEvent.KEYCODE_PAGE_DOWN:
          builder.setSpecialKey(SpecialKey.PAGE_DOWN);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_DIVIDE:
          builder.setSpecialKey(SpecialKey.DIVIDE);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_MULTIPLY:
          builder.setSpecialKey(SpecialKey.MULTIPLY);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_SUBTRACT:
          builder.setSpecialKey(SpecialKey.SUBTRACT);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_ADD:
          builder.setSpecialKey(SpecialKey.ADD);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_ENTER:
          builder.setSpecialKey(SpecialKey.SEPARATOR);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_DOT:
          builder.setSpecialKey(SpecialKey.DECIMAL);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_0:
          builder.setSpecialKey(SpecialKey.NUMPAD0);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_1:
          builder.setSpecialKey(SpecialKey.NUMPAD1);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_2:
          builder.setSpecialKey(SpecialKey.NUMPAD2);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_3:
          builder.setSpecialKey(SpecialKey.NUMPAD3);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_4:
          builder.setSpecialKey(SpecialKey.NUMPAD4);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_5:
          builder.setSpecialKey(SpecialKey.NUMPAD5);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_6:
          builder.setSpecialKey(SpecialKey.NUMPAD6);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_7:
          builder.setSpecialKey(SpecialKey.NUMPAD7);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_8:
          builder.setSpecialKey(SpecialKey.NUMPAD8);
          break;
        case android.view.KeyEvent.KEYCODE_NUMPAD_9:
          builder.setSpecialKey(SpecialKey.NUMPAD9);
          break;
        default:
          if (unicodeChar != 0) {
            builder.setKeyCode(unicodeChar);
          }
          break;
      }

      if (!isPrintable(unicodeChar)) {
        // Mozc server accepts modifiers only if non-printable key event is sent.
        if ((metaState & android.view.KeyEvent.META_SHIFT_MASK) != 0) {
          builder.addModifierKeys(ModifierKey.SHIFT);
        }
        if ((metaState & android.view.KeyEvent.META_ALT_MASK) != 0) {
          builder.addModifierKeys(ModifierKey.ALT);
        }
        if ((metaState & android.view.KeyEvent.META_CTRL_MASK) != 0) {
          builder.addModifierKeys(ModifierKey.CTRL);
        }
      }
      return builder.build();
    }