/**
   * Like {@link ComponentTester#keyString}, but correcting some characters.
   *
   * <p>While Abbot has features to deal with different locales, I have experienced problems where
   * at {@code @} appeared to be typed as {@code "}. This can result, for example, in an invalid
   * email address. This method tries to work around the blocking issues I've encountered here (very
   * crude method though).
   *
   * @throws InterruptedException
   */
  protected static void keyString(String s) throws AWTException, InterruptedException {
    char[] c = s.toCharArray();
    // initialize when needed
    if (replacemap == null) {
      logger.fine("Detecting robot keymapping");
      replacemap = new HashMap<Character, Character>();
      // create textbox, type in each character, store result
      final String chars = "1234567890";
      JFrame frame = new JFrame("Detecting key mapping (don't type yourself!)");
      JTextField field = new JTextField("", 10);
      frame.add(field);
      frame.setSize(200, 100);
      frame.setVisible(true);
      for (int i = 0; i < chars.length(); i++) {
        try {
          field.setText("");
          tester.setModifiers(InputEvent.SHIFT_MASK, true);
          tester.keyStroke(chars.charAt(i));
          tester.setModifiers(InputEvent.SHIFT_MASK, false);
          guiSleep();
          replacemap.put(field.getText().charAt(0), chars.charAt(i));
        } catch (Exception e) {
        }
      }
      frame.setVisible(false);
      frame.dispose();
    }

    for (int i = 0; i < c.length; i++) {
      if (replacemap.containsKey(c[i])) {
        guiSleep();
        tester.setModifiers(InputEvent.SHIFT_MASK, true);
        tester.keyStroke(replacemap.get(c[i]));
        tester.setModifiers(InputEvent.SHIFT_MASK, false);
        guiSleep();
      } else {
        tester.keyStroke(c[i]);
      }
    }
  }
 /** Gives focus to a {@linkplain Component} by its name */
 protected static boolean focusByName(final String name)
     throws ComponentNotFoundException, MultipleComponentsFoundException {
   Component c = findByName(name);
   if (c.hasFocus()) return true;
   // try ordinary method
   if (c.requestFocusInWindow()) {
     while (!c.hasFocus()) guiSleep();
     return true;
   }
   // press tab until we have the correct focus
   for (int i = 0; i < 25 /* TODO proper number */; i++) {
     tester.keyStroke('\t');
     guiSleep();
     if (name.equals(AWT.getActiveWindow().getFocusOwner().getName())) return true;
   }
   // failed ...
   logger.warning("Could not give focus to component: " + name);
   return true;
 }