@Override
  public void processContents(MElementContainer<MUIElement> element) {
    if (!(((MUIElement) element) instanceof MWindow)) {
      return;
    }
    MWindow mWindow = (MWindow) ((MUIElement) element);
    Shell shell = (Shell) element.getWidget();

    // Populate the main menu
    IPresentationEngine2 renderer =
        (IPresentationEngine2) context.get(IPresentationEngine.class.getName());
    if (mWindow.getMainMenu() != null) {
      renderer.createGui(mWindow.getMainMenu(), element);
      shell.setMenuBar((Menu) mWindow.getMainMenu().getWidget());
    }

    // create Detached Windows
    for (MWindow dw : mWindow.getWindows()) {
      renderer.createGui(dw, element);
    }

    // Populate the trim (if any)
    if (mWindow instanceof MTrimmedWindow) {
      MTrimmedWindow tWindow = (MTrimmedWindow) mWindow;
      for (MTrimBar trimBar : tWindow.getTrimBars()) {
        renderer.createGui(trimBar, element);
      }
    }

    shell.pack();
    shell.open();
  }
  public void testCreateMenu() {
    final MWindow window = createWindowWithOneViewAndMenu();
    wb = new E4Workbench(window, appContext);

    Widget topWidget = (Widget) window.getWidget();
    assertTrue(topWidget instanceof Shell);
    Shell shell = (Shell) topWidget;
    final Menu menuBar = shell.getMenuBar();
    assertNotNull(menuBar);
    assertEquals(1, menuBar.getItemCount());
    final MenuItem fileItem = menuBar.getItem(0);
    assertEquals("File", fileItem.getText());
    final Menu fileMenu = fileItem.getMenu();
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(2, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);

    MMenu mainMenu = window.getMainMenu();
    MMenu modelFileMenu = (MMenu) mainMenu.getChildren().get(0);
    final MMenuItem item2Model = (MMenuItem) modelFileMenu.getChildren().get(0);
    item2Model.setToBeRendered(false);
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(1, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);

    item2Model.setToBeRendered(true);
    fileMenu.notifyListeners(SWT.Show, null);
    assertEquals(2, fileMenu.getItemCount());
    fileMenu.notifyListeners(SWT.Hide, null);
  }
 /** Process defined windows and menu contributions */
 protected void processModelMenus() {
   for (MWindow window : app.getChildren()) {
     redirectHandledMenuItems(window.getMainMenu());
   }
   for (MMenuContribution contribution : app.getMenuContributions()) {
     processMenuContribution(contribution);
   }
 }
  /**
   * Locate an action (a menu item, actually) with the given id in the current menu bar and run it.
   *
   * @param actionId the action to find
   * @return true if an action was found, false otherwise
   */
  private boolean runAction(String actionId) {
    MWindow window = app.getSelectedElement();
    if (window == null) {
      return false;
    }
    MMenu topMenu = window.getMainMenu();
    MMenuItem item = findAction(actionId, topMenu);
    if (item == null || !item.isEnabled()) {
      return false;
    }
    try {
      // disable the about and prefs items -- they shouldn't be
      // able to be run when another item is being triggered
      final Display display = Display.getDefault();
      MenuItem aboutItem = null;
      boolean aboutEnabled = true;
      MenuItem prefsItem = null;
      boolean prefsEnabled = true;

      Menu appMenuBar = display.getMenuBar();
      if (appMenuBar != null) {
        aboutItem = findMenuItemById(appMenuBar, SWT.ID_ABOUT);
        if (aboutItem != null) {
          aboutEnabled = aboutItem.getEnabled();
          aboutItem.setEnabled(false);
        }
        prefsItem = findMenuItemById(appMenuBar, SWT.ID_PREFERENCES);
        if (prefsItem != null) {
          prefsEnabled = prefsItem.getEnabled();
          prefsItem.setEnabled(false);
        }
      }
      try {
        simulateMenuSelection(item);
      } finally {
        if (prefsItem != null) {
          prefsItem.setEnabled(prefsEnabled);
        }
        if (aboutItem != null) {
          aboutItem.setEnabled(aboutEnabled);
        }
      }
    } catch (Exception e) {
      // theoretically, one of
      // SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception
      // not expected to happen at all.
      log(e);
      // return false?
    }
    return true;
  }
  private <T> void findElementsRecursive(
      MApplicationElement searchRoot,
      Class<T> clazz,
      Selector matcher,
      List<T> elements,
      int searchFlags) {
    Assert.isLegal(searchRoot != null);
    if (searchFlags == 0) {
      return;
    }

    // are *we* a match ?
    boolean classMatch = clazz == null ? true : clazz.isInstance(searchRoot);
    if (classMatch && matcher.select(searchRoot)) {
      if (!elements.contains(searchRoot)) {
        @SuppressWarnings("unchecked")
        T element = (T) searchRoot;
        elements.add(element);
      }
    }
    if (searchRoot instanceof MApplication && (searchFlags == ANYWHERE)) {
      MApplication app = (MApplication) searchRoot;

      List<MApplicationElement> children = new ArrayList<>();
      if (clazz != null) {
        if (clazz.equals(MHandler.class)) {
          children.addAll(app.getHandlers());
        } else if (clazz.equals(MCommand.class)) {
          children.addAll(app.getCommands());
        } else if (clazz.equals(MBindingContext.class)) {
          children.addAll(app.getBindingContexts());
        } else if (clazz.equals(MBindingTable.class) || clazz.equals(MKeyBinding.class)) {
          children.addAll(app.getBindingTables());
        }
        // } else { only look for these if specifically asked.
        // children.addAll(app.getHandlers());
        // children.addAll(app.getCommands());
        // children.addAll(app.getBindingContexts());
        // children.addAll(app.getBindingTables());
      }

      for (MApplicationElement child : children) {
        findElementsRecursive(child, clazz, matcher, elements, searchFlags);
      }
    }

    if (searchRoot instanceof MBindingContext && (searchFlags == ANYWHERE)) {
      MBindingContext bindingContext = (MBindingContext) searchRoot;
      for (MBindingContext child : bindingContext.getChildren()) {
        findElementsRecursive(child, clazz, matcher, elements, searchFlags);
      }
    }

    if (searchRoot instanceof MBindingTable) {
      MBindingTable bindingTable = (MBindingTable) searchRoot;
      for (MKeyBinding child : bindingTable.getBindings()) {
        findElementsRecursive(child, clazz, matcher, elements, searchFlags);
      }
    }

    // Check regular containers
    if (searchRoot instanceof MElementContainer<?>) {
      /*
       * Bug 455281: If given a window with a primary perspective stack,
       * and we're not told to look outside of the perspectives (i.e.,
       * searchFlags is missing OUTSIDE_PERSPECTIVE), then just search the
       * primary perspective stack instead. This ignores special areas
       * like the compat layer's stack holding the Help, CheatSheets, and
       * Intro.
       */
      MElementContainer<?> searchContainer = (MElementContainer<?>) searchRoot;
      MPerspectiveStack primaryStack = null;
      if (searchRoot instanceof MWindow
          && (searchFlags & OUTSIDE_PERSPECTIVE) == 0
          && (primaryStack = getPrimaryPerspectiveStack((MWindow) searchRoot)) != null) {
        searchContainer = primaryStack;
      }
      if (searchContainer instanceof MPerspectiveStack) {
        if ((searchFlags & IN_ANY_PERSPECTIVE) != 0) {
          // Search *all* the perspectives
          MElementContainer<? extends MUIElement> container = searchContainer;
          List<? extends MUIElement> children = container.getChildren();
          for (MUIElement child : children) {
            findElementsRecursive(child, clazz, matcher, elements, searchFlags);
          }
        } else if ((searchFlags & IN_ACTIVE_PERSPECTIVE) != 0) {
          // Only search the currently active perspective, if any
          MPerspective active = ((MPerspectiveStack) searchContainer).getSelectedElement();
          if (active != null) {
            findElementsRecursive(active, clazz, matcher, elements, searchFlags);
          }
        } else if ((searchFlags & IN_SHARED_AREA) != 0) {
          // Only recurse through the shared areas
          List<MArea> areas = findElements(searchContainer, null, MArea.class, null);
          for (MArea area : areas) {
            findElementsRecursive(area, clazz, matcher, elements, searchFlags);
          }
        }
      } else {
        @SuppressWarnings("unchecked")
        MElementContainer<MUIElement> container = (MElementContainer<MUIElement>) searchRoot;
        List<MUIElement> children = container.getChildren();
        for (MUIElement child : children) {
          findElementsRecursive(child, clazz, matcher, elements, searchFlags);
        }
      }
    }

    // Search Trim
    if (searchRoot instanceof MTrimmedWindow && (searchFlags & IN_TRIM) != 0) {
      MTrimmedWindow tw = (MTrimmedWindow) searchRoot;
      List<MTrimBar> bars = tw.getTrimBars();
      for (MTrimBar bar : bars) {
        findElementsRecursive(bar, clazz, matcher, elements, searchFlags);
      }
    }

    // Search Detached Windows
    if (searchRoot instanceof MWindow) {
      MWindow window = (MWindow) searchRoot;
      for (MWindow dw : window.getWindows()) {
        findElementsRecursive(dw, clazz, matcher, elements, searchFlags);
      }

      MMenu menu = window.getMainMenu();
      if (menu != null && (searchFlags & IN_MAIN_MENU) != 0) {
        findElementsRecursive(menu, clazz, matcher, elements, searchFlags);
      }
      // Check for Handlers
      if (searchFlags == ANYWHERE && MHandler.class.equals(clazz)) {
        for (MHandler child : window.getHandlers()) {
          findElementsRecursive(child, clazz, matcher, elements, searchFlags);
        }
      }
    }

    if (searchRoot instanceof MPerspective) {
      MPerspective persp = (MPerspective) searchRoot;
      for (MWindow dw : persp.getWindows()) {
        findElementsRecursive(dw, clazz, matcher, elements, searchFlags);
      }
    }
    // Search shared elements
    if (searchRoot instanceof MPlaceholder) {
      MPlaceholder ph = (MPlaceholder) searchRoot;

      // Don't search in shared areas unless the flag is set
      if (ph.getRef() != null
          && (!(ph.getRef() instanceof MArea) || (searchFlags & IN_SHARED_AREA) != 0)) {
        findElementsRecursive(ph.getRef(), clazz, matcher, elements, searchFlags);
      }
    }

    if (searchRoot instanceof MPart && (searchFlags & IN_PART) != 0) {
      MPart part = (MPart) searchRoot;

      for (MMenu menu : part.getMenus()) {
        findElementsRecursive(menu, clazz, matcher, elements, searchFlags);
      }

      MToolBar toolBar = part.getToolbar();
      if (toolBar != null) {
        findElementsRecursive(toolBar, clazz, matcher, elements, searchFlags);
      }
      if (MHandler.class.equals(clazz)) {
        for (MHandler child : part.getHandlers()) {
          findElementsRecursive(child, clazz, matcher, elements, searchFlags);
        }
      }
    }
  }
  /**
   * Modify the given workbench window shell bits to show the tool bar toggle button.
   *
   * @param window the window to modify
   * @since 3.2
   */
  @SuppressWarnings("restriction")
  protected void modifyWindowShell(MWindow window) {
    if (window.getWidget() == null) {
      return;
    }
    if (window.getMainMenu() == null) {
      return;
    }
    redirectHandledMenuItems(window.getMainMenu());

    // the toolbar button is not available since MacOS X 10.7
    if (OS.VERSION >= 0x1070) {
      return;
    }
    // only add the button when either the cool bar or perspective bar
    // is initially visible. This is so that RCP applications can choose to
    // use this fragment without fear that their explicitly invisible bars
    // can't be shown.
    boolean trimInitiallyVisible = false;
    if (window instanceof MTrimmedWindow && !((MTrimmedWindow) window).getTrimBars().isEmpty()) {
      for (MTrimBar tb : ((MTrimmedWindow) window).getTrimBars()) {
        if (tb.isVisible()) {
          trimInitiallyVisible = true;
        }
      }
    }

    // It would also be worth checking if there's a command defined
    // for COMMAND_ID_TOGGLE_COOLBAR
    if (trimInitiallyVisible) {
      Shell shell = ((Control) window.getWidget()).getShell();
      NSWindow nsWindow = shell.view.window();
      // Add an empty, hidden tool bar to the window. Without this the
      // tool bar button at the top right of the window will not
      // appear even when setShowsToolbarButton(true) is called.
      // Unfortunately cannot just call shell.getToolBar() as it
      // allocates a properly-sized toolbar
      NSToolbar dummyBar = new NSToolbar();
      dummyBar.alloc();
      dummyBar.initWithIdentifier(NSString.stringWith("SWTToolbar")); // $NON-NLS-1$
      dummyBar.setVisible(false);
      nsWindow.setToolbar(dummyBar);
      dummyBar.release();
      nsWindow.setShowsToolbarButton(true);

      // Override the target and action of the toolbar button so we can
      // control it.
      try {
        Object fieldValue = wrapPointer(NSWindowToolbarButton);
        NSButton toolbarButton =
            (NSButton)
                invokeMethod(
                    NSWindow.class,
                    nsWindow,
                    "standardWindowButton",
                    new Object[] {fieldValue}); // $NON-NLS-1$
        if (toolbarButton != null) {
          toolbarButton.setTarget(delegate);
          invokeMethod(
              NSControl.class,
              toolbarButton,
              "setAction", //$NON-NLS-1$
              new Object[] {wrapPointer(sel_toolbarButtonClicked_)});
        }
      } catch (Exception e) {
        // theoretically, one of
        // SecurityException,Illegal*Exception,InvocationTargetException,NoSuch*Exception
        // not expected to happen at all.
        log(e);
      }
    }
  }