/**
   * Clicks a button asynchronously and waits till the given condition is fulfilled.
   *
   * @param bot the SWT bot
   * @param button the button to click
   * @param waitCondition the condition to wait for, may be null
   * @throws TimeoutException
   */
  public static void asyncClick(
      final SWTWorkbenchBot bot, final SWTBotButton button, final ICondition waitCondition)
      throws TimeoutException {
    bot.waitUntil(
        new DefaultCondition() {
          public boolean test() throws Exception {
            return button.isEnabled();
          }

          public String getFailureMessage() {
            return "Button isn't enabled.";
          }
        });

    UIThreadRunnable.asyncExec(
        bot.getDisplay(),
        new VoidResult() {
          public void run() {
            button.click();
          }
        });

    if (waitCondition != null) {
      bot.waitUntil(waitCondition);
    }
  }
  /**
   * Expands the entry. Takes care that all attributes and child entries are initialized so that
   * there are no pending background actions and event notifications. This is necessary to avoid
   * race conditions.
   *
   * @param bot the bot
   * @param entry the entry to expand
   * @param nextName the name of the entry that must become visible, may be null
   * @throws Exception the exception
   */
  public static void expandEntry(
      final SWTWorkbenchBot bot, final SWTBotTreeItem entry, final String nextName) {
    UIThreadRunnable.asyncExec(
        bot.getDisplay(),
        new VoidResult() {
          public void run() {
            entry.expand();
          }
        });

    bot.waitUntil(
        new DefaultCondition() {
          public boolean test() throws Exception {
            if (nextName != null) {
              String adjustedNodeName = nextName != null ? adjustNodeName(entry, nextName) : null;
              SWTBotTreeItem node = entry.getNode(adjustedNodeName);
              if (node == null) {
                return false;
              }
            }
            return !entry.getNodes().contains("Fetching Entries...");
          }

          public String getFailureMessage() {
            return "Could not find entry " + entry.getText() + " -> " + nextName;
          }
        });
  }
  private void expand(final SWTBotTreeItem entry, boolean wait, final String nextNode) {
    UIThreadRunnable.asyncExec(
        bot.getDisplay(),
        new VoidResult() {
          public void run() {
            entry.expand();
          }
        });

    if (wait) {
      bot.waitUntil(
          new DefaultCondition() {
            public boolean test() throws Exception {
              //                    if ( nextNode != null )
              //                    {
              //                        String adjustedNodeName = nextNode != null ? adjustNodeName(
              // entry, nextNode ) : null;
              //                        SWTBotTreeItem node = entry.getNode( adjustedNodeName );
              //                        if ( node == null )
              //                        {
              //                            return false;
              //                        }
              //                    }
              return !entry.getNodes().contains("Fetching Entries...")
                  && !entry.getNodes().contains("Opening Connection...");
            }

            public String getFailureMessage() {
              return "Could not find entry " + entry.getText() + " -> " + nextNode;
            }
          });
    }
  }
  /**
   * Clicks a tree item asynchronously and waits till the given condition is fulfilled.
   *
   * @param bot the SWT bot
   * @param item the tree item to click
   * @param waitCondition the condition to wait for, may be null
   * @throws TimeoutException the timeout exception
   */
  public static void asyncClick(
      final SWTWorkbenchBot bot, final SWTBotTreeItem item, final ICondition waitCondition)
      throws TimeoutException {
    UIThreadRunnable.asyncExec(
        bot.getDisplay(),
        new VoidResult() {
          public void run() {
            item.click();
          }
        });

    if (waitCondition != null) {
      bot.waitUntil(waitCondition);
    }
  }