//-------------------------------------------------------------------------------------------------
// Module    : $RCSfile: KeyboardMap.java,v $
// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 11.07.2012 $
// Project   : KeyboardMaps
// Creation  : 2012 by patrick
// Copyright : Patrick Harms, 2012
//-------------------------------------------------------------------------------------------------
package de.ugoe.cs.tasktree.keyboardmaps;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

//-------------------------------------------------------------------------------------------------
/**
 * TODO comment
 * 
 * @version $Revision: $ $Date: 11.07.2012$
 * @author 2012, last modified by $Author: patrick$
 */
//-------------------------------------------------------------------------------------------------
public class KeyboardMap
{
  /** */
  private static Logger LOG = Logger.getLogger(KeyboardMap.class.getName());

  /** */
  private Locale mLocale;

  /** */
  private String mFileName;

  /** */
  private Map<VirtualKey, List<KeyStroke>> mKeyStrokes = new HashMap<VirtualKey, List<KeyStroke>>();
  
  /** TODO: remove this stuff */
  private List<Object[]> mKeyIds = new ArrayList<Object[]>();

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param locale
   */
  //-----------------------------------------------------------------------------------------------
  KeyboardMap(Locale locale)
  {
    mLocale = locale;
    
    if ((mLocale == Locale.ENGLISH) || (mLocale == Locale.US) || (mLocale == Locale.CANADA))
    {
      mFileName = "en-us";
    }
    else if (mLocale == Locale.UK)
    {
      mFileName = "en-gb";
    }
    else
    {
      mFileName = locale.getLanguage();
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param digit1
   * @param b
   * @param c
   * @param d
   * @param e
   * @param f
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  public char getCharacterFor(VirtualKey key,
                              boolean    numlock,
                              boolean    shift,
                              boolean    altgr,
                              boolean    inhibit)
    throws IllegalArgumentException
  {
    List<KeyStroke> candidates = mKeyStrokes.get(key);
    
    if (candidates == null)
    {
      return Character.UNASSIGNED;
    }
    
    // try to find the key stroke 
    for (KeyStroke keyStroke : candidates)
    {
      if ((numlock == keyStroke.getNumlock()) &&
          (!keyStroke.getLocalstate()) &&
          (shift == keyStroke.getShift()) &&
          (altgr == keyStroke.getAltgr()) &&
          (inhibit == keyStroke.getInhibit()))
      {
        return keyStroke.getCharacter();
      }
    }
    
    // try to find the key stroke with a local state ignoring the other keys
    for (KeyStroke keyStroke : candidates)
    {
      if ((numlock == keyStroke.getNumlock()) &&
          (keyStroke.getLocalstate()) &&
          (inhibit == keyStroke.getInhibit()))
      {
        return keyStroke.getCharacter();
      }
    }
    
    return Character.UNASSIGNED;
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   */
  //-----------------------------------------------------------------------------------------------
  void init() throws IllegalArgumentException
  {
    LOG.info("initializing keymap for locale " + mLocale);

    List<String[]> deadKeySequences = new ArrayList<String[]>();
    List<String[]> keyStrokes = new ArrayList<String[]>();
    readStream(getStream(mFileName), deadKeySequences, keyStrokes);
    
    LOG.info("read " + keyStrokes.size() + " key strokes and " + deadKeySequences.size() +
             " dead key sequences");

    VirtualKeySynonyms virtualKeySynonyms = determineVirtualKeySynonyms(keyStrokes);
    processKeyStrokes(keyStrokes, virtualKeySynonyms);
    processDeadKeySequences(deadKeySequences);
    
    for (Object[] keyId : mKeyIds)
    {
      System.out.println(Integer.toHexString((Integer) keyId[0]) + "  " + keyId[1]);
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param fileName
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private InputStream getStream(String name)
  {
    LOG.info("reading keymap for locale " + mLocale + " from resource keymaps/" + name);

    InputStream stream =
      this.getClass().getClassLoader().getResourceAsStream("keymaps/" + name);
      
    if (stream == null)
    {
      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
    }
    
    return stream;
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param stream
   * @param virtualKeySynonyms 
   * @param deadKeySequences 
   */
  //-----------------------------------------------------------------------------------------------
  private void readStream(InputStream    stream,
                          List<String[]> deadKeySequences,
                          List<String[]> keyStrokes)
    throws IllegalArgumentException
  {
    BufferedReader in = new BufferedReader(new InputStreamReader(stream));
    
    try
    {
      String line;
      while ((line = in.readLine()) != null)
      {
        if (!"".equals(line))
        {
          processLine(line, deadKeySequences, keyStrokes);
        }
      }
    }
    catch (IOException e)
    {
      LOG.log(Level.WARNING, "no keyboard map available for locale " + mLocale, e);
      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale, e);
    }
    finally
    {
      try
      {
        in.close();
      }
      catch (IOException e)
      {
        LOG.warning("could not close input stream for reading keyboard map");
      }
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param line
   * @param deadKeySequences 
   */
  //-----------------------------------------------------------------------------------------------
  private void processLine(String         line,
                           List<String[]> deadKeySequences,
                           List<String[]> keyStrokes)
  {
    String[] values = line.split(" ");
    
    if (values.length <= 0)
    {
      return;
    }
    
    // ignore comments
    if (values[0].startsWith("#"))
    {
      return;
    }
    
    if ("map".equals(values[0]))
    {
      // this is the map id. Ignore it.
    }
    else if ("include".equals(values[0]))
    {
      // process all includes
      for (int i = 1; i < values.length; i++)
      {
        if (!values[i].startsWith("#"))
        {
          readStream(getStream(values[i]), deadKeySequences, keyStrokes);
        }
        else
        {
          break;
        }
      }
    }
    else if ("sequence".equals(values[0]))
    {
      deadKeySequences.add(values);
    }
    else
    {
      boolean alreadyAdded = false;
      
      // check, if there is a replacement
      for (int i = 0; i < keyStrokes.size(); i++)
      {
        if (keyStrokes.get(i)[0].equals(values[0]))
        {
          LOG.finest("replacing key stroke " + values[0] + " with former keyid " +
                     keyStrokes.get(i)[1] + " with new key id " + values[1]);
          keyStrokes.set(i, values);
          alreadyAdded = true;
          break;
        }
      }
      
      if (!alreadyAdded)
      {
        keyStrokes.add(values);
      }
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStrokes
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private VirtualKeySynonyms determineVirtualKeySynonyms(List<String[]> keyStrokes)
  {
    LOG.info("determining virtual keys and synonyms for the keymap");

    VirtualKeySynonyms virtualKeySynonyms = new VirtualKeySynonyms();
    
    // for debugging purposes, determine which key strokes are not matched to virtual keys.
    List<String[]> unmatchedKeyStrokes = new ArrayList<String[]>();
    
    for (String[] keyStroke : keyStrokes)
    {
      String keyStrokeName = keyStroke[0];
      int keyId = getKeyId(keyStroke[1]);
      //System.err.println(keyStrokeName + "  0x" + Integer.toHexString(keyId));

      VirtualKey virtualKey = determineVirtualKey(keyStrokeName);
      
      if (virtualKey != null)
      {
        virtualKeySynonyms.add(keyId, virtualKey);
      }
      else
      {
        unmatchedKeyStrokes.add(keyStroke);
      }
    }
    
    for (String[] unmatchedKeyStroke : unmatchedKeyStrokes)
    {
      if (!virtualKeySynonyms.containsKey(getKeyId(unmatchedKeyStroke[1])))
      {
        LOG.finest("no virtual key mapped to key stroke " + unmatchedKeyStroke[0] + "(" +
                   unmatchedKeyStroke[1] + ") of keyboard map for locale " + mLocale);
      }
    }
    
    return virtualKeySynonyms;
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param string
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private int getKeyId(String keyIdString)
  {
    if (keyIdString.startsWith("0x"))
    {
      keyIdString = keyIdString.substring(2);
    }
  
    return Integer.parseInt(keyIdString, 16);
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStrokes
   * @param virtualKeySynonyms
   */
  //-----------------------------------------------------------------------------------------------
  private void processKeyStrokes(List<String[]> keyStrokes, VirtualKeySynonyms virtualKeySynonyms)
  {
    for (String[] keyStroke : keyStrokes)
    {
      handleKeyStroke(keyStroke, virtualKeySynonyms);
    }
    
    addKeyStrokesIndependentOfNumLock();
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param values
   */
  //-----------------------------------------------------------------------------------------------
  private void handleKeyStroke(String[]           values,
                               VirtualKeySynonyms virtualKeySynonyms)
  {
    String keyStrokeName = values[0];
    String keyIdString = values[1];
    if (keyIdString.startsWith("0x"))
    {
      keyIdString = keyIdString.substring(2);
    }
    
    int keyId = Integer.parseInt(keyIdString, 16);
    
    // parse the conditions
    boolean numlock = false;
    boolean localstate = false;
    boolean shift = false;
    boolean altgr = false;
    boolean addupper = false;
    boolean inhibit = false;
    
    for (int i = 2; i < values.length; i++)
    {
      if (!values[i].startsWith("#"))
      {
        if ("numlock".equals(values[i]))
        {
          numlock = true;
        }
        else if ("localstate".equals(values[i]))
        {
          localstate = true;
        }
        else if ("shift".equals(values[i]))
        {
          shift = true;
        }
        else if ("altgr".equals(values[i]))
        {
          altgr = true;
        }
        else if ("addupper".equals(values[i]))
        {
          addupper = true;
        }
        else if ("inhibit".equals(values[i]))
        {
          inhibit = true;
        }
        else
        {
          LOG.severe("unknown condition " + values[i] + " specified for key stroke " +
                     keyStrokeName + " through keyboard map for locale " + mLocale);
          throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
        }
      }
      else
      {
        break;
      }
    }
    
    addAllRepresentedKeyStrokes(keyStrokeName, keyId, numlock, localstate, shift, altgr, addupper,
                                inhibit, virtualKeySynonyms);
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStrokeName
   * @param keyId
   * @param numlock
   * @param localstate
   * @param shift
   * @param altgr
   * @param addupper
   * @param inhibit
   */
  //-----------------------------------------------------------------------------------------------
  private void addAllRepresentedKeyStrokes(String             keyStrokeName,
                                           int                keyId,
                                           boolean            numlock,
                                           boolean            localstate,
                                           boolean            shift,
                                           boolean            altgr,
                                           boolean            addupper,
                                           boolean            inhibit,
                                           VirtualKeySynonyms virtualKeySynonyms)
  {
    VirtualKey[] virtualKeys = virtualKeySynonyms.getVirtualKeySynonyms(keyId);
    
    if (virtualKeys == null)
    {
      LOG.severe("no virtual key mapped to key stroke " + keyStrokeName +
                 " of keyboard map for locale " + mLocale);
      //throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
      return;
    }
    
    for (VirtualKey virtualKey : virtualKeys)
    {
      if (addupper)
      {
        char c = determineCharacter(keyStrokeName, true);
        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, true, altgr, inhibit, c);
      
        c = determineCharacter(keyStrokeName, false);
        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, false, altgr, inhibit, c);
      }
      else
      {
        char c = determineCharacter(keyStrokeName, false);
        addKeyStroke(keyStrokeName, virtualKey, numlock, localstate, shift, altgr, inhibit, c);
      }
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStroke
   */
  //-----------------------------------------------------------------------------------------------
  private void addKeyStroke(String     keyStrokeName,
                            VirtualKey virtualKey,
                            boolean    numlock,
                            boolean    localstate,
                            boolean    shift,
                            boolean    altgr,
                            boolean    inhibit,
                            char       character)
  {
    KeyStroke keyStroke = new KeyStroke
      (keyStrokeName, virtualKey, numlock, localstate, shift, altgr, inhibit, character);
    
    List<KeyStroke> keyStrokes = mKeyStrokes.get(keyStroke.getVirtualKey());
    
    if (keyStrokes == null)
    {
      keyStrokes = new ArrayList<KeyStroke>();
      mKeyStrokes.put(keyStroke.getVirtualKey(), keyStrokes);
    }
    
    keyStrokes.add(keyStroke);
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   */
  //-----------------------------------------------------------------------------------------------
  private void addKeyStrokesIndependentOfNumLock()
  {
    for (Map.Entry<VirtualKey, List<KeyStroke>> entry : mKeyStrokes.entrySet())
    {
      List<KeyStroke> keyStrokesToAdd = new ArrayList<KeyStroke>();
      for (KeyStroke keyStroke : entry.getValue())
      {
        if (!keyStroke.getNumlock())
        {
          boolean foundPositiveNumlockVariant = false;
          for (KeyStroke candidate : entry.getValue())
          {
            if ((candidate.getShift() == keyStroke.getShift()) &&
                (candidate.getAltgr() == keyStroke.getAltgr()) &&
                (candidate.getLocalstate() == keyStroke.getLocalstate()) &&
                (candidate.getInhibit() == keyStroke.getInhibit()) &&
                (candidate.getNumlock()))
            {
              foundPositiveNumlockVariant = true;
              break;
            }
          }
          
          if (!foundPositiveNumlockVariant)
          {
            keyStrokesToAdd.add(keyStroke);
          }
        }
      }
      
      for (KeyStroke keyStroke : keyStrokesToAdd)
      {
        addKeyStroke(keyStroke.getKeyStrokeName(), keyStroke.getVirtualKey(), true,
                     keyStroke.getLocalstate(), keyStroke.getShift(), keyStroke.getAltgr(),
                     keyStroke.getInhibit(), keyStroke.getCharacter());
      }
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param deadKeySequences
   */
  //-----------------------------------------------------------------------------------------------
  private void processDeadKeySequences(List<String[]> deadKeySequences)
  {
    // TODO Auto-generated method stub
    //System.out.println("PATRICK: KeyboardMap.processDeadKeySequences ");
    
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStrokeName
   * @param shift
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private VirtualKey determineVirtualKey(String keyStrokeName)
  {
    if ("Shift_R".equals(keyStrokeName))
    {
      return VirtualKey.SHIFT;
    }
    else if ("Shift_L".equals(keyStrokeName))
    {
      return VirtualKey.SHIFT;
    }
    else if ("Alt_R".equals(keyStrokeName))
    {
      return VirtualKey.ALT_GRAPH;
    }
    else if ("Mode_switch".equals(keyStrokeName))
    {
      return VirtualKey.MODECHANGE;
    }
    else if ("ISO_Level3_Shift".equals(keyStrokeName))
    {
      return VirtualKey.SHIFT;
    }
    else if ("Alt_L".equals(keyStrokeName))
    {
      return VirtualKey.ALT;
    }
    else if ("Control_R".equals(keyStrokeName))
    {
      return VirtualKey.CONTROL;
    }
    else if ("Control_L".equals(keyStrokeName))
    {
      return VirtualKey.CONTROL;
    }
    else if ("Menu".equals(keyStrokeName))
    {
      return VirtualKey.WINDOWS;
    }
    else if ("1".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_1;
    }
    else if ("2".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_2;
    }
    else if ("3".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_3;
    }
    else if ("4".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_4;
    }
    else if ("5".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_5;
    }
    else if ("6".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_6;
    }
    else if ("7".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_7;
    }
    else if ("8".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_8;
    }
    else if ("9".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_9;
    }
    else if ("0".equals(keyStrokeName))
    {
      return VirtualKey.DIGIT_0;
    }
    else if ("BackSpace".equals(keyStrokeName))
    {
      return VirtualKey.BACK_SPACE;
    }
    else if ("Tab".equals(keyStrokeName))
    {
      return VirtualKey.TAB;
    }
    else if ("q".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_Q;
    }
    else if ("w".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_W;
    }
    else if ("e".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_E;
    }
    else if ("r".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_R;
    }
    else if ("t".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_T;
    }
    else if ("y".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_Y;
    }
    else if ("u".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_U;
    }
    else if ("i".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_I;
    }
    else if ("o".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_O;
    }
    else if ("p".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_P;
    }
    else if ("a".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_A;
    }
    else if ("s".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_S;
    }
    else if ("d".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_D;
    }
    else if ("f".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_F;
    }
    else if ("g".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_G;
    }
    else if ("h".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_H;
    }
    else if ("j".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_J;
    }
    else if ("k".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_K;
    }
    else if ("l".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_L;
    }
    else if ("Return".equals(keyStrokeName))
    {
      return VirtualKey.ENTER;
    }
    else if ("z".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_Z;
    }
    else if ("x".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_X;
    }
    else if ("c".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_C;
    }
    else if ("v".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_V;
    }
    else if ("b".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_B;
    }
    else if ("n".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_N;
    }
    else if ("m".equals(keyStrokeName))
    {
      return VirtualKey.LETTER_M;
    }
    else if ("space".equals(keyStrokeName))
    {
      return VirtualKey.SPACE;
    }
    else if ("less".equals(keyStrokeName))
    {
      return VirtualKey.LESS;
    }
    else if ("greater".equals(keyStrokeName))
    {
      return VirtualKey.GREATER;
    }
    else if ("Escape".equals(keyStrokeName))
    {
      return VirtualKey.ESCAPE;
    }
    else if ("F1".equals(keyStrokeName))
    {
      return VirtualKey.F1;
    }
    else if ("F2".equals(keyStrokeName))
    {
      return VirtualKey.F2;
    }
    else if ("F3".equals(keyStrokeName))
    {
      return VirtualKey.F3;
    }
    else if ("F4".equals(keyStrokeName))
    {
      return VirtualKey.F4;
    }
    else if ("F5".equals(keyStrokeName))
    {
      return VirtualKey.F5;
    }
    else if ("F6".equals(keyStrokeName))
    {
      return VirtualKey.F6;
    }
    else if ("F7".equals(keyStrokeName))
    {
      return VirtualKey.F7;
    }
    else if ("F8".equals(keyStrokeName))
    {
      return VirtualKey.F8;
    }
    else if ("F9".equals(keyStrokeName))
    {
      return VirtualKey.F9;
    }
    else if ("F10".equals(keyStrokeName))
    {
      return VirtualKey.F10;
    }
    else if ("F11".equals(keyStrokeName))
    {
      return VirtualKey.F11;
    }
    else if ("F12".equals(keyStrokeName))
    {
      return VirtualKey.F12;
    }
    else if ("F13".equals(keyStrokeName))
    {
      return VirtualKey.F13;
    }
    else if ("F14".equals(keyStrokeName))
    {
      return VirtualKey.F14;
    }
    else if ("F15".equals(keyStrokeName))
    {
      return VirtualKey.F15;
    }
    else if ("F16".equals(keyStrokeName))
    {
      return VirtualKey.F16;
    }
    else if ("F17".equals(keyStrokeName))
    {
      return VirtualKey.F17;
    }
    else if ("F18".equals(keyStrokeName))
    {
      return VirtualKey.F18;
    }
    else if ("F19".equals(keyStrokeName))
    {
      return VirtualKey.F19;
    }
    else if ("F20".equals(keyStrokeName))
    {
      return VirtualKey.F20;
    }
    else if ("F21".equals(keyStrokeName))
    {
      return VirtualKey.F21;
    }
    else if ("F22".equals(keyStrokeName))
    {
      return VirtualKey.F22;
    }
    else if ("F23".equals(keyStrokeName))
    {
      return VirtualKey.F23;
    }
    else if ("F24".equals(keyStrokeName))
    {
      return VirtualKey.F24;
    }
    else if ("Print".equals(keyStrokeName))
    {
      return VirtualKey.PRINTSCREEN;
    }
    else if ("Scroll_Lock".equals(keyStrokeName))
    {
      return VirtualKey.SCROLL_LOCK;
    }
    else if ("Insert".equals(keyStrokeName))
    {
      return VirtualKey.INSERT;
    }
    else if ("Delete".equals(keyStrokeName))
    {
      return VirtualKey.DELETE;
    }
    else if ("Home".equals(keyStrokeName))
    {
      return VirtualKey.HOME;
    }
    else if ("End".equals(keyStrokeName))
    {
      return VirtualKey.END;
    }
    else if ("Page_Up".equals(keyStrokeName))
    {
      return VirtualKey.PAGE_UP;
    }
    else if ("Page_Down".equals(keyStrokeName))
    {
      return VirtualKey.PAGE_DOWN;
    }
    else if ("Left".equals(keyStrokeName))
    {
      return VirtualKey.LEFT;
    }
    else if ("Up".equals(keyStrokeName))
    {
      return VirtualKey.UP;
    }
    else if ("Down".equals(keyStrokeName))
    {
      return VirtualKey.DOWN;
    }
    else if ("Right".equals(keyStrokeName))
    {
      return VirtualKey.RIGHT;
    }
    else if ("Num_Lock".equals(keyStrokeName))
    {
      return VirtualKey.NUM_LOCK;
    }
    else if ("KP_Divide".equals(keyStrokeName))
    {
      return VirtualKey.SLASH;
    }
    else if ("KP_Multiply".equals(keyStrokeName))
    {
      return VirtualKey.ASTERISK;
    }
    else if ("KP_Subtract".equals(keyStrokeName))
    {
      return VirtualKey.MINUS;
    }
    else if ("KP_Add".equals(keyStrokeName))
    {
      return VirtualKey.PLUS;
    }
    else if ("KP_Enter".equals(keyStrokeName))
    {
      return VirtualKey.ENTER;
    }
    else if ("KP_Decimal".equals(keyStrokeName))
    {
      return VirtualKey.DECIMAL;
    }
    else if ("KP_Separator".equals(keyStrokeName))
    {
      return VirtualKey.SEPARATOR;
    }
    else if ("KP_Delete".equals(keyStrokeName))
    {
      return VirtualKey.DELETE;
    }
    else if ("KP_0".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_0;
    }
    else if ("KP_Insert".equals(keyStrokeName))
    {
      return VirtualKey.INSERT;
    }
    else if ("KP_1".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_1;
    }
    else if ("KP_End".equals(keyStrokeName))
    {
      return VirtualKey.END;
    }
    else if ("KP_2".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_2;
    }
    else if ("KP_Down".equals(keyStrokeName))
    {
      return VirtualKey.KP_DOWN;
    }
    else if ("KP_3".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_3;
    }
    else if ("KP_Next".equals(keyStrokeName))
    {
      return VirtualKey.PAGE_DOWN;
    }
    else if ("KP_4".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_4;
    }
    else if ("KP_Left".equals(keyStrokeName))
    {
      return VirtualKey.KP_LEFT;
    }
    else if ("KP_5".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_5;
    }
    else if ("KP_Begin".equals(keyStrokeName))
    {
      return VirtualKey.BEGIN;
    }
    else if ("KP_6".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_6;
    }
    else if ("KP_Right".equals(keyStrokeName))
    {
      return VirtualKey.KP_RIGHT;
    }
    else if ("KP_7".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_7;
    }
    else if ("KP_Home".equals(keyStrokeName))
    {
      return VirtualKey.HOME;
    }
    else if ("KP_8".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_8;
    }
    else if ("KP_Up".equals(keyStrokeName))
    {
      return VirtualKey.KP_UP;
    }
    else if ("KP_9".equals(keyStrokeName))
    {
      return VirtualKey.NUMPAD_9;
    }
    else if ("KP_Prior".equals(keyStrokeName))
    {
      return VirtualKey.PAGE_UP;
    }
    else if ("Caps_Lock".equals(keyStrokeName))
    {
      return VirtualKey.CAPS_LOCK;
    }
    else if ("exclam".equals(keyStrokeName))
    {
      return VirtualKey.EXCLAMATION_MARK;
    }
    else if ("exclamdown".equals(keyStrokeName))
    {
      return VirtualKey.INVERTED_EXCLAMATION_MARK;
    }
    else if ("quotedbl".equals(keyStrokeName))
    {
      return VirtualKey.QUOTEDBL;
    }
    else if ("slash".equals(keyStrokeName))
    {
      return VirtualKey.SLASH;
    }
    else if ("backslash".equals(keyStrokeName))
    {
      return VirtualKey.BACK_SLASH;
    }
    else if ("dead_acute".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_ACUTE;
    }
    else if ("dead_diaresis".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_DIAERESIS;
    }
    else if ("dead_abovering".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_ABOVERING;
    }
    else if ("plus".equals(keyStrokeName))
    {
      return VirtualKey.PLUS;
    }
    else if ("asterisk".equals(keyStrokeName))
    {
      return VirtualKey.ASTERISK;
    }
    else if ("dead_tilde".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_TILDE;
    }
    else if ("dead_doubleacute".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_DOUBLEACUTE;
    }
    else if ("dead_caron".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_CARON;
    }
    else if ("dead_circumflex".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_CIRCUMFLEX;
    }
    else if ("comma".equals(keyStrokeName))
    {
      return VirtualKey.COMMA;
    }
    else if ("semicolon".equals(keyStrokeName))
    {
      return VirtualKey.SEMICOLON;
    }
    else if ("multiply".equals(keyStrokeName))
    {
      return VirtualKey.MULTIPLY;
    }
    else if ("period".equals(keyStrokeName))
    {
      return VirtualKey.PERIOD;
    }
    else if ("colon".equals(keyStrokeName))
    {
      return VirtualKey.COLON;
    }
    else if ("dead_breve".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_BREVE;
    }
    else if ("division".equals(keyStrokeName))
    {
      return VirtualKey.DIVIDE;
    }
    else if ("minus".equals(keyStrokeName))
    {
      return VirtualKey.MINUS;
    }
    else if ("underscore".equals(keyStrokeName))
    {
      return VirtualKey.UNDERSCORE;
    }
    else if ("dead_abovedot".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_ABOVEDOT;
    }
    else if ("bracketleft".equals(keyStrokeName))
    {
      return VirtualKey.OPEN_BRACKET;
    }
    else if ("bracketright".equals(keyStrokeName))
    {
      return VirtualKey.CLOSE_BRACKET;
    }
    else if ("grave".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_GRAVE;
    }
    else if ("equal".equals(keyStrokeName))
    {
      return VirtualKey.EQUALS;
    }
    else if ("dead_macron".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_MACRON;
    }
    else if ("dead_ogonek".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_OGONEK;
    }
    else if ("dead_cedilla".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_CEDILLA;
    }
    else if ("ampersand".equals(keyStrokeName))
    {
      return VirtualKey.AMPERSAND;
    }
    else if ("parenleft".equals(keyStrokeName))
    {
      return VirtualKey.LEFT_PARENTHESIS;
    }
    else if ("parenright".equals(keyStrokeName))
    {
      return VirtualKey.RIGHT_PARENTHESIS;
    }
    else if ("braceleft".equals(keyStrokeName))
    {
      return VirtualKey.BRACELEFT;
    }
    else if ("braceright".equals(keyStrokeName))
    {
      return VirtualKey.BRACERIGHT;
    }
    else if ("at".equals(keyStrokeName))
    {
      return VirtualKey.AT;
    }
    else if ("dollar".equals(keyStrokeName))
    {
      return VirtualKey.DOLLAR;
    }
    else if ("EuroSign".equals(keyStrokeName))
    {
      return VirtualKey.EURO_SIGN;
    }
    else if ("Begin".equals(keyStrokeName))
    {
      return VirtualKey.BEGIN;
    }
    else if ("numbersign".equals(keyStrokeName))
    {
      return VirtualKey.NUMBER_SIGN;
    }
    else if ("asciicircum".equals(keyStrokeName))
    {
      return VirtualKey.CIRCUMFLEX;
    }
    else if ("Kanji".equals(keyStrokeName))
    {
      return VirtualKey.KANJI;
    }
    else if ("Katakana".equals(keyStrokeName))
    {
      return VirtualKey.KATAKANA;
    }
    else if ("Hiragana_Katakana".equals(keyStrokeName))
    {
      return VirtualKey.HIRAGANA;
    }
    else if ("Muhenkan".equals(keyStrokeName))
    {
      // I found this in the KeyEvent description
      return VirtualKey.NONCONVERT;
    }
    else if ("kan".equals(keyStrokeName))
    {
      // I found this in the KeyEvent description
      return VirtualKey.NONCONVERT;
    }
    else if ("Henkan_Mode".equals(keyStrokeName))
    {
      // I found this in the key event description
      return VirtualKey.CONVERT;
    }
    else if ("voicedsound".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_VOICED_SOUND;
    }
    else if ("semivoicedsound".equals(keyStrokeName))
    {
      return VirtualKey.DEAD_SEMIVOICED_SOUND;
    }
    else if ("Menu".equals(keyStrokeName))
    {
      return VirtualKey.CONTEXT_MENU;
    }
    else
    {
      LOG.finest("unknown virtual key for key stroke " + keyStrokeName + " specified through " +
                 "keyboard map for locale " + mLocale);
      
      return null;
    }
    
    // for the following virtual keys no key stroke names are provided in the key maps
    /*CANCEL(KeyEvent.VK_CANCEL),
    CLEAR(KeyEvent.VK_CLEAR),
    PAUSE(KeyEvent.VK_PAUSE),
    HELP(KeyEvent.VK_HELP),
    META(KeyEvent.VK_META),

    BACK_QUOTE(KeyEvent.VK_BACK_QUOTE),
    QUOTE(KeyEvent.VK_QUOTE),

    DEAD_IOTA(KeyEvent.VK_DEAD_IOTA),

    FINAL(KeyEvent.VK_FINAL),
    CONVERT(KeyEvent.VK_CONVERT),
    NONCONVERT(KeyEvent.VK_NONCONVERT),
    ACCEPT(KeyEvent.VK_ACCEPT),
    KANA(KeyEvent.VK_KANA),
    ALPHANUMERIC(KeyEvent.VK_ALPHANUMERIC),
    FULL_WIDTH(KeyEvent.VK_FULL_WIDTH),
    HALF_WIDTH(KeyEvent.VK_HALF_WIDTH),
    ROMAN_CHARACTERS(KeyEvent.VK_ROMAN_CHARACTERS),
    ALL_CANDIDATES(KeyEvent.VK_ALL_CANDIDATES),
    PREVIOUS_CANDIDATE(KeyEvent.VK_PREVIOUS_CANDIDATE),
    CODE_INPUT(KeyEvent.VK_CODE_INPUT),
    JAPANESE_KATAKANA(KeyEvent.VK_JAPANESE_KATAKANA),
    JAPANESE_HIRAGANA(KeyEvent.VK_JAPANESE_HIRAGANA),
    JAPANESE_ROMAN(KeyEvent.VK_JAPANESE_ROMAN),
    KANA_LOCK(KeyEvent.VK_KANA_LOCK),
    INPUT_METHOD_ON_OFF(KeyEvent.VK_INPUT_METHOD_ON_OFF),

    CUT(KeyEvent.VK_CUT),
    COPY(KeyEvent.VK_COPY),
    PASTE(KeyEvent.VK_PASTE),
    UNDO(KeyEvent.VK_UNDO),
    AGAIN(KeyEvent.VK_AGAIN),
    FIND(KeyEvent.VK_FIND),
    PROPS(KeyEvent.VK_PROPS),
    STOP(KeyEvent.VK_STOP),
    COMPOSE(KeyEvent.VK_COMPOSE),*/
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   * @param keyStrokeName
   * @param shift
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private char determineCharacter(String keyStrokeName, boolean getUpper)
  {
    if ("Shift_R".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Shift_L".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Alt_R".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Mode_switch".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("ISO_Level3_Shift".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Alt_L".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Control_R".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Control_L".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Menu".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("1".equals(keyStrokeName))
    {
      return '1';
    }
    else if ("2".equals(keyStrokeName))
    {
      return '2';
    }
    else if ("3".equals(keyStrokeName))
    {
      return '3';
    }
    else if ("4".equals(keyStrokeName))
    {
      return '4';
    }
    else if ("5".equals(keyStrokeName))
    {
      return '5';
    }
    else if ("6".equals(keyStrokeName))
    {
      return '6';
    }
    else if ("7".equals(keyStrokeName))
    {
      return '7';
    }
    else if ("8".equals(keyStrokeName))
    {
      return '8';
    }
    else if ("9".equals(keyStrokeName))
    {
      return '9';
    }
    else if ("0".equals(keyStrokeName))
    {
      return '0';
    }
    else if ("BackSpace".equals(keyStrokeName))
    {
      return '\b';
    }
    else if ("Tab".equals(keyStrokeName))
    {
      return '\t';
    }
    else if ("ISO_Left_Tab".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("q".equals(keyStrokeName))
    {
      return getUpper ? 'Q' : 'q';
    }
    else if ("w".equals(keyStrokeName))
    {
      return getUpper ? 'W' : 'w';
    }
    else if ("e".equals(keyStrokeName))
    {
      return getUpper ? 'E' : 'e';
    }
    else if ("r".equals(keyStrokeName))
    {
      return getUpper ? 'R' : 'r';
    }
    else if ("t".equals(keyStrokeName))
    {
      return getUpper ? 'T' : 't';
    }
    else if ("y".equals(keyStrokeName))
    {
      return getUpper ? 'Y' : 'y';
    }
    else if ("u".equals(keyStrokeName))
    {
      return getUpper ? 'U' : 'u';
    }
    else if ("i".equals(keyStrokeName))
    {
      return getUpper ? 'I' : 'i';
    }
    else if ("o".equals(keyStrokeName))
    {
      return getUpper ? 'O' : 'o';
    }
    else if ("p".equals(keyStrokeName))
    {
      return getUpper ? 'P' : 'p';
    }
    else if ("a".equals(keyStrokeName))
    {
      return getUpper ? 'A' : 'a';
    }
    else if ("s".equals(keyStrokeName))
    {
      return getUpper ? 'S' : 's';
    }
    else if ("d".equals(keyStrokeName))
    {
      return getUpper ? 'D' : 'd';
    }
    else if ("f".equals(keyStrokeName))
    {
      return getUpper ? 'F' : 'f';
    }
    else if ("g".equals(keyStrokeName))
    {
      return getUpper ? 'G' : 'g';
    }
    else if ("h".equals(keyStrokeName))
    {
      return getUpper ? 'H' : 'h';
    }
    else if ("j".equals(keyStrokeName))
    {
      return getUpper ? 'J' : 'j';
    }
    else if ("k".equals(keyStrokeName))
    {
      return getUpper ? 'K' : 'k';
    }
    else if ("l".equals(keyStrokeName))
    {
      return getUpper ? 'L' : 'l';
    }
    else if ("Return".equals(keyStrokeName))
    {
      return '\n';
    }
    else if ("z".equals(keyStrokeName))
    {
      return getUpper ? 'Z' : 'z';
    }
    else if ("x".equals(keyStrokeName))
    {
      return getUpper ? 'X' : 'x';
    }
    else if ("c".equals(keyStrokeName))
    {
      return getUpper ? 'C' : 'c';
    }
    else if ("v".equals(keyStrokeName))
    {
      return getUpper ? 'V' : 'v';
    }
    else if ("b".equals(keyStrokeName))
    {
      return getUpper ? 'B' : 'b';
    }
    else if ("n".equals(keyStrokeName))
    {
      return getUpper ? 'N' : 'n';
    }
    else if ("m".equals(keyStrokeName))
    {
      return getUpper ? 'M' : 'm';
    }
    else if ("space".equals(keyStrokeName))
    {
      return ' ';
    }
    else if ("less".equals(keyStrokeName))
    {
      return '<';
    }
    else if ("greater".equals(keyStrokeName))
    {
      return '>';
    }
    else if ("bar".equals(keyStrokeName))
    {
      return '|';
    }
    else if ("brokenbar".equals(keyStrokeName))
    {
      return '¦';
    }
    else if ("Escape".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F1".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F2".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F3".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F4".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F5".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F6".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F7".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F8".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F9".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F10".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F11".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("SunF36".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F12".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("SunF37".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Print".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Sys_Req".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Execute".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F22".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Scroll_Lock".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F23".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Insert".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Delete".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Home".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("End".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Page_Up".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Page_Down".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Left".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Up".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Down".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Right".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Num_Lock".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_Divide".equals(keyStrokeName))
    {
      return '/';
    }
    else if ("KP_Multiply".equals(keyStrokeName))
    {
      return '*';
    }
    else if ("KP_Subtract".equals(keyStrokeName))
    {
      return '-';
    }
    else if ("KP_Add".equals(keyStrokeName))
    {
      return '+';
    }
    else if ("KP_Enter".equals(keyStrokeName))
    {
      return '\n';
    }
    else if ("KP_Decimal".equals(keyStrokeName))
    {
      return ',';
    }
    else if ("KP_Separator".equals(keyStrokeName))
    {
      return ',';
    }
    else if ("KP_Delete".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_0".equals(keyStrokeName))
    {
      return '0';
    }
    else if ("KP_Insert".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_1".equals(keyStrokeName))
    {
      return '1';
    }
    else if ("KP_End".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_2".equals(keyStrokeName))
    {
      return '2';
    }
    else if ("KP_Down".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_3".equals(keyStrokeName))
    {
      return '3';
    }
    else if ("KP_Next".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_4".equals(keyStrokeName))
    {
      return '4';
    }
    else if ("KP_Left".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_5".equals(keyStrokeName))
    {
      return '5';
    }
    else if ("KP_Begin".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_6".equals(keyStrokeName))
    {
      return '6';
    }
    else if ("KP_Right".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_7".equals(keyStrokeName))
    {
      return '7';
    }
    else if ("KP_Home".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_8".equals(keyStrokeName))
    {
      return '8';
    }
    else if ("KP_Up".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("KP_9".equals(keyStrokeName))
    {
      return '9';
    }
    else if ("KP_Prior".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Caps_Lock".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Multi_key".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("exclam".equals(keyStrokeName))
    {
      return '!';
    }
    else if ("onesuperior".equals(keyStrokeName))
    {
      return '¹';
    }
    else if ("exclamdown".equals(keyStrokeName))
    {
      return '¡';
    }
    else if ("quotedbl".equals(keyStrokeName))
    {
      return '"';
    }
    else if ("twosuperior".equals(keyStrokeName))
    {
      return '²';
    }
    else if ("oneeighth".equals(keyStrokeName))
    {
      return '⅛';
    }
    else if ("section".equals(keyStrokeName))
    {
      return '§';
    }
    else if ("threesuperior".equals(keyStrokeName))
    {
      return '³';
    }
    else if ("sterling".equals(keyStrokeName))
    {
      return '£';
    }
    else if ("dollar".equals(keyStrokeName))
    {
      return '$';
    }
    else if ("onequarter".equals(keyStrokeName))
    {
      return '¼';
    }
    else if ("currency".equals(keyStrokeName))
    {
      return '¤';
    }
    else if ("percent".equals(keyStrokeName))
    {
      return '%';
    }
    else if ("onehalf".equals(keyStrokeName))
    {
      return '½';
    }
    else if ("threeeighths".equals(keyStrokeName))
    {
      return '⅜';
    }
    else if ("ampersand".equals(keyStrokeName))
    {
      return '&';
    }
    else if ("threequarters".equals(keyStrokeName))
    {
      return '¾';
    }
    else if ("fiveeighths".equals(keyStrokeName))
    {
      return '⅝';
    }
    else if ("slash".equals(keyStrokeName))
    {
      return '/';
    }
    else if ("braceleft".equals(keyStrokeName))
    {
      return '{';
    }
    else if ("seveneighths".equals(keyStrokeName))
    {
      return '⅞';
    }
    else if ("parenleft".equals(keyStrokeName))
    {
      return '(';
    }
    else if ("bracketleft".equals(keyStrokeName))
    {
      return '[';
    }
    else if ("trademark".equals(keyStrokeName))
    {
      return '™';
    }
    else if ("parenright".equals(keyStrokeName))
    {
      return ')';
    }
    else if ("bracketright".equals(keyStrokeName))
    {
      return ']';
    }
    else if ("plusminus".equals(keyStrokeName))
    {
      return '±';
    }
    else if ("equal".equals(keyStrokeName))
    {
      return '=';
    }
    else if ("braceright".equals(keyStrokeName))
    {
      return '}';
    }
    else if ("ssharp".equals(keyStrokeName))
    {
      return 'ß';
    }
    else if ("question".equals(keyStrokeName))
    {
      return '?';
    }
    else if ("backslash".equals(keyStrokeName))
    {
      return '\\';
    }
    else if ("questiondown".equals(keyStrokeName))
    {
      return '¿';
    }
    else if ("acute".equals(keyStrokeName))
    {
      return '´';
    }
    else if ("dead_acute".equals(keyStrokeName))
    {
      return 0x0301;
    }
    else if ("grave".equals(keyStrokeName))
    {
      return '`';
    }
    else if ("dead_grave".equals(keyStrokeName))
    {
      return 0x0300;
    }
    else if ("dead_cedilla".equals(keyStrokeName))
    {
      return 0x0327;
    }
    else if ("dead_ogonek".equals(keyStrokeName))
    {
      return 0x0328;
    }
    else if ("at".equals(keyStrokeName))
    {
      return '@';
    }
    else if ("Greek_OMEGA".equals(keyStrokeName))
    {
      return 'Ω';
    }
    else if ("EuroSign".equals(keyStrokeName))
    {
      return '€';
    }
    else if ("paragraph".equals(keyStrokeName))
    {
      return 0x2029;
    }
    else if ("registered".equals(keyStrokeName))
    {
      return '®';
    }
    else if ("tslash".equals(keyStrokeName))
    {
      return 'ŧ';
    }
    else if ("Tslash".equals(keyStrokeName))
    {
      return 'Ŧ';
    }
    else if ("z".equals(keyStrokeName))
    {
      return getUpper ? 'Z' : 'z';
    }
    else if ("leftarrow".equals(keyStrokeName))
    {
      return '←';
    }
    else if ("yen".equals(keyStrokeName))
    {
      return '¥';
    }
    else if ("downarrow".equals(keyStrokeName))
    {
      return '↓';
    }
    else if ("uparrow".equals(keyStrokeName))
    {
      return '↑';
    }
    else if ("rightarrow".equals(keyStrokeName))
    {
      return '→';
    }
    else if ("idotless".equals(keyStrokeName))
    {
      return 'ı';
    }
    else if ("oslash".equals(keyStrokeName))
    {
      return 'ø';
    }
    else if ("Ooblique".equals(keyStrokeName))
    {
      return 'Ø';
    }
    else if ("thorn".equals(keyStrokeName))
    {
      return 'þ';
    }
    else if ("THORN".equals(keyStrokeName))
    {
      return 'Þ';
    }
    else if ("udiaeresis".equals(keyStrokeName))
    {
      return getUpper ? 'Ü' : 'ü';
    }
    else if ("Udiaeresis".equals(keyStrokeName))
    {
      return getUpper ? 'Ü' : 'ü';
    }
    else if ("dead_diaeresis".equals(keyStrokeName))
    {
      return 0x0308;
    }
    else if ("dead_abovering".equals(keyStrokeName))
    {
      return 0x030A;
    }
    else if ("plus".equals(keyStrokeName))
    {
      return '+';
    }
    else if ("asterisk".equals(keyStrokeName))
    {
      return '*';
    }
    else if ("asciitilde".equals(keyStrokeName))
    {
      return '~';
    }
    else if ("dead_tilde".equals(keyStrokeName))
    {
      return 0x0303;
    }
    else if ("dead_macron".equals(keyStrokeName))
    {
      return 0x0304;
    }
    else if ("ae".equals(keyStrokeName))
    {
      return 'æ';
    }
    else if ("AE".equals(keyStrokeName))
    {
      return 'Æ';
    }
    else if ("eth".equals(keyStrokeName))
    {
      return 'ð';
    }
    else if ("ETH".equals(keyStrokeName))
    {
      return 'Ð';
    }
    else if ("dstroke".equals(keyStrokeName))
    {
      return getUpper ? 'Đ' : 'đ';
    }
    else if ("ordfeminine".equals(keyStrokeName))
    {
      return 'ª';
    }
    else if ("eng".equals(keyStrokeName))
    {
      return 'ŋ';
    }
    else if ("ENG".equals(keyStrokeName))
    {
      return 'Ŋ';
    }
    else if ("hstroke".equals(keyStrokeName))
    {
      return 'ħ';
    }
    else if ("Hstroke".equals(keyStrokeName))
    {
      return 'Ħ';
    }
    else if ("kra".equals(keyStrokeName))
    {
      return 'ĸ';
    }
    else if ("odiaeresis".equals(keyStrokeName))
    {
      return 'ö';
    }
    else if ("Odiaeresis".equals(keyStrokeName))
    {
      return 'Ö';
    }
    else if ("dead_doubleacute".equals(keyStrokeName))
    {
      return 0x030B;
    }
    else if ("adiaeresis".equals(keyStrokeName))
    {
      return 'ä';
    }
    else if ("Adiaeresis".equals(keyStrokeName))
    {
      return 'Ä';
    }
    else if ("dead_caron".equals(keyStrokeName))
    {
      return 0x030C;
    }
    else if ("asciicircum".equals(keyStrokeName))
    {
      return '^';
    }
    else if ("dead_circumflex".equals(keyStrokeName))
    {
      return 0x0302;
    }
    else if ("degree".equals(keyStrokeName))
    {
      return '°';
    }
    else if ("notsign".equals(keyStrokeName))
    {
      return '¬';
    }
    else if ("numbersign".equals(keyStrokeName))
    {
      return '#';
    }
    else if ("apostrophe".equals(keyStrokeName))
    {
      return '\'';
    }
    else if ("dead_breve".equals(keyStrokeName))
    {
      return 0x0306;
    }
    else if ("y".equals(keyStrokeName))
    {
      return getUpper ? 'Y' : 'y';
    }
    else if ("guillemotleft".equals(keyStrokeName))
    {
      return '»';
    }
    else if ("guillemotright".equals(keyStrokeName))
    {
      return '«';
    }
    else if ("cent".equals(keyStrokeName))
    {
      return '¢';
    }
    else if ("copyright".equals(keyStrokeName))
    {
      return '©';
    }
    else if ("leftdoublequotemark".equals(keyStrokeName))
    {
      return '„';
    }
    else if ("rightdoublequotemark".equals(keyStrokeName))
    {
      return '“';
    }
    else if ("mu".equals(keyStrokeName))
    {
      return 'µ';
    }
    else if ("masculine".equals(keyStrokeName))
    {
      return 'º';
    }
    else if ("comma".equals(keyStrokeName))
    {
      return ',';
    }
    else if ("semicolon".equals(keyStrokeName))
    {
      return ';';
    }
    else if ("horizconnector".equals(keyStrokeName))
    {
      return '·';
    }
    else if ("multiply".equals(keyStrokeName))
    {
      return '×';
    }
    else if ("period".equals(keyStrokeName))
    {
      return '.';
    }
    else if ("colon".equals(keyStrokeName))
    {
      return ':';
    }
    else if ("periodcentered".equals(keyStrokeName))
    {
      return '…';
    }
    else if ("division".equals(keyStrokeName))
    {
      return '÷';
    }
    else if ("minus".equals(keyStrokeName))
    {
      return '-';
    }
    else if ("underscore".equals(keyStrokeName))
    {
      return '_';
    }
    else if ("dead_belowdot".equals(keyStrokeName))
    {
      return 0x0323;
    }
    else if ("dead_abovedot".equals(keyStrokeName))
    {
      return 0x0307;
    }
    else if ("eacute".equals(keyStrokeName))
    {
      return getUpper ? 'É' : 'é';
    }
    else if ("Eacute".equals(keyStrokeName))
    {
      return getUpper ? 'É' : 'é';
    }
    else if ("egrave".equals(keyStrokeName))
    {
      return getUpper ? 'È' : 'è';
    }
    else if ("Egrave".equals(keyStrokeName))
    {
      return getUpper ? 'È' : 'è';
    }
    else if ("ccedilla".equals(keyStrokeName))
    {
      return getUpper ? 'Ç' : 'ç';
    }
    else if ("Ccedilla".equals(keyStrokeName))
    {
      return getUpper ? 'Ç' : 'ç';
    }
    else if ("agrave".equals(keyStrokeName))
    {
      return getUpper ? 'À' : 'à';
    }
    else if ("Agrave".equals(keyStrokeName))
    {
      return getUpper ? 'À' : 'à';
    }
    else if ("lstroke".equals(keyStrokeName))
    {
      return getUpper ? 'Ł' : 'ł';
    }
    else if ("Lstroke".equals(keyStrokeName))
    {
      return getUpper ? 'Ł' : 'ł';
    }
    else if ("ugrave".equals(keyStrokeName))
    {
      return getUpper ? 'Ù' : 'ù';
    }
    else if ("Ugrave".equals(keyStrokeName))
    {
      return getUpper ? 'Ù' : 'ù';
    }
    else if ("igrave".equals(keyStrokeName))
    {
      return getUpper ? 'Ì' : 'ì';
    }
    else if ("Igrave".equals(keyStrokeName))
    {
      return getUpper ? 'Ì' : 'ì';
    }
    else if ("ograve".equals(keyStrokeName))
    {
      return getUpper ? 'Ò' : 'ò';
    }
    else if ("ograve".equals(keyStrokeName))
    {
      return getUpper ? 'Ò' : 'ò';
    }
    else if ("keyboard_type".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("keyboard_subtype".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("keyboard_functionkeys".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("kana_NU".equals(keyStrokeName))
    {
      return 'ヌ';
    }
    else if ("kana_FU".equals(keyStrokeName))
    {
      return 'フ';
    }
    else if ("kana_A".equals(keyStrokeName))
    {
      return 'ア';
    }
    else if ("kana_a".equals(keyStrokeName))
    {
      return 'ァ';
    }
    else if ("kana_U".equals(keyStrokeName))
    {
      return 'ウ';
    }
    else if ("kana_u".equals(keyStrokeName))
    {
      return 'ゥ';
    }
    else if ("kana_E".equals(keyStrokeName))
    {
      return 'エ';
    }
    else if ("kana_e".equals(keyStrokeName))
    {
      return 'ェ';
    }
    else if ("kana_O".equals(keyStrokeName))
    {
      return 'オ';
    }
    else if ("kana_o".equals(keyStrokeName))
    {
      return 'ォ';
    }
    else if ("kana_YA".equals(keyStrokeName))
    {
      return 'ヤ';
    }
    else if ("kana_ya".equals(keyStrokeName))
    {
      return 'ャ';
    }
    else if ("kana_YU".equals(keyStrokeName))
    {
      return 'ユ';
    }
    else if ("kana_yu".equals(keyStrokeName))
    {
      return 'ュ';
    }
    else if ("kana_YO".equals(keyStrokeName))
    {
      return 'ヨ';
    }
    else if ("kana_yo".equals(keyStrokeName))
    {
      return 'ョ';
    }
    else if ("kana_WA".equals(keyStrokeName))
    {
      return 'ワ';
    }
    else if ("kana_WO".equals(keyStrokeName))
    {
      return 'ヲ';
    }
    else if ("kana_HO".equals(keyStrokeName))
    {
      return 'ホ';
    }
    else if ("kana_HE".equals(keyStrokeName))
    {
      return 'ヘ';
    }
    else if ("kana_TA".equals(keyStrokeName))
    {
      return 'タ';
    }
    else if ("kana_TE".equals(keyStrokeName))
    {
      return 'テ';
    }
    else if ("kana_I".equals(keyStrokeName))
    {
      return 'イ';
    }
    else if ("kana_i".equals(keyStrokeName))
    {
      return 'ィ';
    }
    else if ("kana_SU".equals(keyStrokeName))
    {
      return 'ス';
    }
    else if ("kana_KA".equals(keyStrokeName))
    {
      return 'カ';
    }
    else if ("kana_N".equals(keyStrokeName))
    {
      return 'ン';
    }
    else if ("kana_NA".equals(keyStrokeName))
    {
      return 'ナ';
    }
    else if ("kana_NI".equals(keyStrokeName))
    {
      return 'ニ';
    }
    else if ("kana_RA".equals(keyStrokeName))
    {
      return 'ラ';
    }
    else if ("kana_SE".equals(keyStrokeName))
    {
      return 'セ';
    }
    else if ("voicedsound".equals(keyStrokeName))
    {
      return 0x3099;
    }
    else if ("semivoicedsound".equals(keyStrokeName))
    {
      return 0x309A;
    }
    else if ("kana_openingbracket".equals(keyStrokeName))
    {
      return 0x04A2;
    }
    else if ("kana_closingbracket".equals(keyStrokeName))
    {
      return 0x04A3;
    }
    else if ("kana_CHI".equals(keyStrokeName))
    {
      return 'チ';
    }
    else if ("kana_TO".equals(keyStrokeName))
    {
      return 'ト';
    }
    else if ("kana_SHI".equals(keyStrokeName))
    {
      return 'シ';
    }
    else if ("kana_HA".equals(keyStrokeName))
    {
      return 'ハ';
    }
    else if ("kana_KI".equals(keyStrokeName))
    {
      return 'キ';
    }
    else if ("kana_KU".equals(keyStrokeName))
    {
      return 'ク';
    }
    else if ("kana_MA".equals(keyStrokeName))
    {
      return 'マ';
    }
    else if ("kana_NO".equals(keyStrokeName))
    {
      return 'ノ';
    }
    else if ("kana_RI".equals(keyStrokeName))
    {
      return 'リ';
    }
    else if ("kana_RE".equals(keyStrokeName))
    {
      return 'レ';
    }
    else if ("kana_KE".equals(keyStrokeName))
    {
      return 'ケ';
    }
    else if ("Zenkaku_Hankaku".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Kanji".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("kana_MU".equals(keyStrokeName))
    {
      return 'ム';
    }
    else if ("kana_TSU".equals(keyStrokeName))
    {
      return 'ツ';
    }
    else if ("kana_tsu".equals(keyStrokeName))
    {
      return 'ッ';
    }
    else if ("kana_SA".equals(keyStrokeName))
    {
      return 'サ';
    }
    else if ("kana_SO".equals(keyStrokeName))
    {
      return 'ソ';
    }
    else if ("kana_HI".equals(keyStrokeName))
    {
      return 'ヒ';
    }
    else if ("kana_KO".equals(keyStrokeName))
    {
      return 'コ';
    }
    else if ("kana_MI".equals(keyStrokeName))
    {
      return 'ミ';
    }
    else if ("kana_MO".equals(keyStrokeName))
    {
      return 'モ';
    }
    else if ("kana_NE".equals(keyStrokeName))
    {
      return 'ネ';
    }
    else if ("kana_comma".equals(keyStrokeName))
    {
      return '､';
    }
    else if ("kana_RU".equals(keyStrokeName))
    {
      return 'ル';
    }
    else if ("kana_fullstop".equals(keyStrokeName))
    {
      return '｡';
    }
    else if ("kana_ME".equals(keyStrokeName))
    {
      return 'メ';
    }
    else if ("kana_conjunctive".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Henkan_Mode".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Hiragana_Katakana".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Katakana".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Romaji".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Muhenkan".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Eisu_toggle".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Eisu_toggle".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("F13".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Hangul".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else if ("Hangul_Hanja".equals(keyStrokeName))
    {
      return Character.UNASSIGNED;
    }
    else
    {
      LOG.severe("unknown key stroke name " + keyStrokeName + " specified through keyboard map " +
                 "for locale " + mLocale);
      
//      if (shift)
//      {
//        System.err.println("    else if (\"" + keyStrokeName + "\".equals(keyStrokeName))");
//        System.err.println("    {");
//        System.err.println("      return shift ? '" + Character.toUpperCase(keyStrokeName.charAt(0)) +
//                           "' : '" + Character.toLowerCase(keyStrokeName.charAt(0)) + "';");
//        System.err.println("    }");
//      }
//      else
//      {
//        System.err.println("    else if (\"" + keyStrokeName + "\".equals(keyStrokeName))");
//        System.err.println("    {");
//        System.err.println("      return '" + keyStrokeName + "';");
//        System.err.println("    }");
//      }
//      
//      return 0x0;
      throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
    }
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * this is a former implementation
   *
   * @param keyId
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  /*private VirtualKey[] mapKeyIdToVirtualKeys(int     keyId,
                                             String  keyStrokeName)
  {
    
    Set<String> names = null;
    
    for (int i = 0; i < mKeyIds.size(); i++)
    {
      if (((Integer) mKeyIds.get(i)[0]) == keyId)
      {
        names = (Set<String>) mKeyIds.get(i)[1];
        break;
      }
    }
    
    if (names == null)
    {
      names = new HashSet<String>();
      boolean added = false;
      
      for (int i = 0; i < mKeyIds.size(); i++)
      {
        if (((Integer) mKeyIds.get(i)[0]) > keyId)
        {
          mKeyIds.add(i, new Object[] { keyId, names });
          added = true;
          break;
        }
      }
      
      if (!added)
      {
        mKeyIds.add(new Object[] { keyId, names });
      }
    }
    
    names.add(keyStrokeName);
    
    
    switch(keyId)
    {
      case 0x36:
      case 0x2a:
        return new VirtualKey[] { VirtualKey.SHIFT };
      case 0xb8:
        return new VirtualKey[] { VirtualKey.ALT_GRAPH };
      case 0x38:
        return new VirtualKey[] { VirtualKey.ALT };
      case 0x9d:
      case 0x1d:
        return new VirtualKey[] { VirtualKey.CONTROL };
      case 0xdd:
        return new VirtualKey[] { VirtualKey.WINDOWS };
      case 0x2:
        return new VirtualKey[] { VirtualKey.DIGIT_1 };
      case 0x3:
        return new VirtualKey[] { VirtualKey.DIGIT_2 };
      case 0x4:
        return new VirtualKey[] { VirtualKey.DIGIT_3 };
      case 0x5:
        return new VirtualKey[] { VirtualKey.DIGIT_4 };
      case 0x6:
        return new VirtualKey[] { VirtualKey.DIGIT_5 };
      case 0x7:
        return new VirtualKey[] { VirtualKey.DIGIT_6 };
      case 0x8:
        return new VirtualKey[] { VirtualKey.DIGIT_7 };
      case 0x9:
        return new VirtualKey[] { VirtualKey.DIGIT_8 };
      case 0xa:
        return new VirtualKey[] { VirtualKey.DIGIT_9 };
      case 0xb:
        return new VirtualKey[] { VirtualKey.DIGIT_0 };
      case 0xe:
        return new VirtualKey[] { VirtualKey.BACK_SPACE };
      case 0xf:
        return new VirtualKey[] { VirtualKey.TAB };
      case 0x10:
        return new VirtualKey[] { VirtualKey.LETTER_Q };
      case 0x11:
        return new VirtualKey[] { VirtualKey.LETTER_W };
      case 0x12:
        return new VirtualKey[] { VirtualKey.LETTER_E };
      case 0x13:
        return new VirtualKey[] { VirtualKey.LETTER_R };
      case 0x14:
        return new VirtualKey[] { VirtualKey.LETTER_T };
      case 0x15:
        return new VirtualKey[] { VirtualKey.LETTER_Y };
      case 0x16:
        return new VirtualKey[] { VirtualKey.LETTER_U };
      case 0x17:
        return new VirtualKey[] { VirtualKey.LETTER_I };
      case 0x18:
        return new VirtualKey[] { VirtualKey.LETTER_O };
      case 0x19:
        return new VirtualKey[] { VirtualKey.LETTER_P };
      case 0x1e:
        return new VirtualKey[] { VirtualKey.LETTER_A };
      case 0x1f:
        return new VirtualKey[] { VirtualKey.LETTER_S };
      case 0x20:
        return new VirtualKey[] { VirtualKey.LETTER_D };
      case 0x21:
        return new VirtualKey[] { VirtualKey.LETTER_F };
      case 0x22:
        return new VirtualKey[] { VirtualKey.LETTER_G };
      case 0x23:
        return new VirtualKey[] { VirtualKey.LETTER_H };
      case 0x24:
        return new VirtualKey[] { VirtualKey.LETTER_J };
      case 0x25:
        return new VirtualKey[] { VirtualKey.LETTER_K };
      case 0x26:
        return new VirtualKey[] { VirtualKey.LETTER_L };
      case 0x1c:
        return new VirtualKey[] { VirtualKey.ENTER };
      case 0x2c:
        return new VirtualKey[] { VirtualKey.LETTER_Z };
      case 0x2d:
        return new VirtualKey[] { VirtualKey.LETTER_X };
      case 0x2e:
        return new VirtualKey[] { VirtualKey.LETTER_C };
      case 0x2f:
        return new VirtualKey[] { VirtualKey.LETTER_V };
      case 0x30:
        return new VirtualKey[] { VirtualKey.LETTER_B };
      case 0x31:
        return new VirtualKey[] { VirtualKey.LETTER_N };
      case 0x32:
        return new VirtualKey[] { VirtualKey.LETTER_M };
      case 0x39:
        return new VirtualKey[] { VirtualKey.SPACE };
      case 0x56:
        return new VirtualKey[] { VirtualKey.LESS };
      case 0x1:
        return new VirtualKey[] { VirtualKey.ESCAPE };
      case 0x3b:
        return new VirtualKey[] { VirtualKey.F1 };
      case 0x3c:
        return new VirtualKey[] { VirtualKey.F2 };
      case 0x3d:
        return new VirtualKey[] { VirtualKey.F3 };
      case 0x3e:
        return new VirtualKey[] { VirtualKey.F4 };
      case 0x3f:
        return new VirtualKey[] { VirtualKey.F5 };
      case 0x40:
        return new VirtualKey[] { VirtualKey.F6 };
      case 0x41:
        return new VirtualKey[] { VirtualKey.F7 };
      case 0x42:
        return new VirtualKey[] { VirtualKey.F8 };
      case 0x43:
        return new VirtualKey[] { VirtualKey.F9 };
      case 0x44:
        return new VirtualKey[] { VirtualKey.F10 };
      case 0x57:
        return new VirtualKey[] { VirtualKey.F11 };
      case 0x58:
        return new VirtualKey[] { VirtualKey.F12 };
      case 0xb7:
        return new VirtualKey[] { VirtualKey.PRINTSCREEN };
      case 0x46:
        return new VirtualKey[] { VirtualKey.SCROLL_LOCK };
      case 0xd2:
        return new VirtualKey[] { VirtualKey.INSERT };
      case 0xd3:
        return new VirtualKey[] { VirtualKey.DELETE };
      case 0xc7:
        return new VirtualKey[] { VirtualKey.HOME };
      case 0xcf:
        return new VirtualKey[] { VirtualKey.END };
      case 0xc9:
        return new VirtualKey[] { VirtualKey.PAGE_UP };
      case 0xd1:
        return new VirtualKey[] { VirtualKey.PAGE_DOWN };
      case 0xcb:
        return new VirtualKey[] { VirtualKey.LEFT };
      case 0xc8:
        return new VirtualKey[] { VirtualKey.UP };
      case 0xd0:
        return new VirtualKey[] { VirtualKey.DOWN };
      case 0xcd:
        return new VirtualKey[] { VirtualKey.RIGHT };
      case 0x45:
        return new VirtualKey[] { VirtualKey.NUM_LOCK };
      case 0xb5:
        return new VirtualKey[] { VirtualKey.DIVIDE };
      case 0x37:
        return new VirtualKey[] { VirtualKey.MULTIPLY };
      case 0x4a:
        return new VirtualKey[] { VirtualKey.SUBTRACT };
      case 0x4e:
        return new VirtualKey[] { VirtualKey.ADD };
      case 0x9c:
        return new VirtualKey[] { VirtualKey.ENTER };
      case 0x53:
        return new VirtualKey[] { VirtualKey.DECIMAL, VirtualKey.DELETE };
      case 0x52:
        return new VirtualKey[] { VirtualKey.NUMPAD_0, VirtualKey.INSERT };
      case 0x4f:
        return new VirtualKey[] { VirtualKey.NUMPAD_1, VirtualKey.END };
      case 0x50:
        return new VirtualKey[] { VirtualKey.NUMPAD_2, VirtualKey.KP_DOWN };
      case 0x51:
        return new VirtualKey[] { VirtualKey.NUMPAD_3, VirtualKey.PAGE_UP };
      case 0x4b:
        return new VirtualKey[] { VirtualKey.NUMPAD_4, VirtualKey.KP_LEFT };
      case 0x4c:
        return new VirtualKey[] { VirtualKey.NUMPAD_5, VirtualKey.BEGIN };
      case 0x4d:
        return new VirtualKey[] { VirtualKey.NUMPAD_6, VirtualKey.KP_RIGHT };
      case 0x47:
        return new VirtualKey[] { VirtualKey.NUMPAD_7, VirtualKey.HOME };
      case 0x48:
        return new VirtualKey[] { VirtualKey.NUMPAD_8, VirtualKey.KP_UP };
      case 0x49:
        return new VirtualKey[] { VirtualKey.NUMPAD_9, VirtualKey.PAGE_DOWN };
      case 0x0:
        return new VirtualKey[] { VirtualKey.CAPS_LOCK };
      case 0xc:
        return new VirtualKey[] { VirtualKey.MINUS, VirtualKey.UNDERSCORE };
      case 0xd:
        return new VirtualKey[] { VirtualKey.EQUALS, VirtualKey.PLUS };
      case 0x1a:
        return new VirtualKey[] { VirtualKey.OPEN_BRACKET, VirtualKey.BRACELEFT };
      case 0x1b:
        return new VirtualKey[] { VirtualKey.CLOSE_BRACKET, VirtualKey.BRACERIGHT };
      case 0x27:
        return new VirtualKey[] { VirtualKey.SEMICOLON, VirtualKey.COLON };
/*      case 0x28:
        return new VirtualKey[] { VirtualKey.APOSTROPHE, VirtualKey.QUOTEDBL };
      case 0x29:
        return new VirtualKey[] { VirtualKey.DEAD_GRAVE, VirtualKey.DEAD_TILDE };
      case 0x2b:
        return new VirtualKey[] { VirtualKey.BACK_SLASH, VirtualKey.BAR };
      case 0x33:
        return new VirtualKey[] { VirtualKey.COMMA, VirtualKey.LESS };
      case 0x34:
        return new VirtualKey[] { VirtualKey.PERIOD, VirtualKey.GREATER };
      case 0x35:
        return new VirtualKey[] { VirtualKey.SLASH, VirtualKey.QUESTIONMARK };
      case 0x73:
        return new VirtualKey[] { VirtualKey.BACK_SLASH, VirtualKey.DEGREE,
                                  VirtualKey.QUESTIONMARK, VirtualKey.UNDERSCORE };
      case 0x7d:
        return new VirtualKey[] { VirtualKey.BAR };
      case 0x79:
        return new VirtualKey[] { VirtualKey.HENKAN_MODE };
      case 0x70:
        return new VirtualKey[] { VirtualKey.KATAKANA };
      case 0x7b:
        return new VirtualKey[] { VirtualKey.MUHENKAN };
      case 0x3a:
        return new VirtualKey[] { VirtualKey.EISU_TOGGLE, VirtualKey.CAPS_LOCK };
      case 0xdc:
        return new VirtualKey[] { VirtualKey.F13 };
      case 0xf2:
        return new VirtualKey[] { VirtualKey.HANGUL };
      case 0xf1:
        return new VirtualKey[] { VirtualKey.HANGUL_HANJA };
      case 0x54:
        return new VirtualKey[] { VirtualKey.EXECUTE };
      default:
        LOG.severe("unknown key id 0x" + Integer.toHexString(keyId) + " specified for key stroke " +
                   keyStrokeName + " through keyboard map for locale " + mLocale);
        throw new IllegalArgumentException("no keyboard map available for locale " + mLocale);
    }
  }*/

}
