private Object safeCreateGui(MUIElement element) {
    // Obtain the necessary parent widget
    Object parent = null;
    MUIElement parentME = element.getParent();
    if (parentME == null) parentME = (MUIElement) ((EObject) element).eContainer();
    if (parentME != null) {
      AbstractPartRenderer renderer = getRendererFor(parentME);
      if (renderer != null) {
        if (!element.isVisible()) {
          parent = getLimboShell();
        } else {
          parent = renderer.getUIContainer(element);
        }
      }
    }

    // Obtain the necessary parent context
    IEclipseContext parentContext = null;
    if (element.getCurSharedRef() != null) {
      MPlaceholder ph = element.getCurSharedRef();
      parentContext = getContext(ph.getParent());
    } else if (parentContext == null && element.getParent() != null) {
      parentContext = getContext(element.getParent());
    } else if (parentContext == null && element.getParent() == null) {
      parentContext = getContext((MUIElement) ((EObject) element).eContainer());
    }

    return safeCreateGui(element, parent, parentContext);
  }
  protected Object createWidget(MUIElement element, Object parent) {
    AbstractPartRenderer renderer = getRenderer(element, parent);
    if (renderer != null) {
      // Remember which renderer is responsible for this widget
      element.setRenderer(renderer);
      Object newWidget = renderer.createWidget(element, parent);
      if (newWidget != null) {
        renderer.bindWidget(element, newWidget);
        return newWidget;
      }
    }

    return null;
  }
        public void handleEvent(Event event) {
          MUIElement changedElement = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
          MUIElement parent = changedElement.getParent();
          if (parent == null) {
            parent = (MUIElement) ((EObject) changedElement).eContainer();
            if (parent == null) {
              return;
            }
          }

          AbstractPartRenderer renderer = (AbstractPartRenderer) parent.getRenderer();
          if (renderer == null || parent instanceof MToolBar) return;

          // Re-parent the control based on the visible state
          if (changedElement.isVisible()) {
            if (changedElement.isToBeRendered()) {
              if (changedElement.getWidget() instanceof Control) {
                // Ensure that the control is under its 'real' parent if
                // it's visible
                Composite realComp = (Composite) renderer.getUIContainer(changedElement);
                Control ctrl = (Control) changedElement.getWidget();
                ctrl.setParent(realComp);
                fixZOrder(changedElement);
              }

              if (parent instanceof MElementContainer<?>) {
                renderer.childRendered((MElementContainer<MUIElement>) parent, changedElement);
              }
            }
          } else {
            // Put the control under the 'limbo' shell
            if (changedElement.getWidget() instanceof Control) {
              Control ctrl = (Control) changedElement.getWidget();

              if (!(ctrl instanceof Shell)) {
                ctrl.getShell().layout(new Control[] {ctrl}, SWT.DEFER);
              }

              ctrl.setParent(getLimboShell());
            }

            if (parent instanceof MElementContainer<?>) {
              renderer.hideChild((MElementContainer<MUIElement>) parent, changedElement);
            }
          }
        }
  private void safeRemoveGui(MUIElement element) {
    if (removeRoot == null) removeRoot = element;
    renderedElements.remove(element);

    // We call 'hideChild' *before* checking if the actual element
    // has been rendered in order to pick up cases of 'lazy loading'
    MUIElement parent = element.getParent();
    AbstractPartRenderer parentRenderer = parent != null ? getRendererFor(parent) : null;
    if (parentRenderer != null) {
      parentRenderer.hideChild(element.getParent(), element);
    }

    AbstractPartRenderer renderer = getRendererFor(element);

    // If the element hasn't been rendered then this is a NO-OP
    if (renderer != null) {

      if (element instanceof MElementContainer<?>) {
        MElementContainer<MUIElement> container = (MElementContainer<MUIElement>) element;
        MUIElement selectedElement = container.getSelectedElement();
        List<MUIElement> children = container.getChildren();
        for (MUIElement child : children) {
          // remove stuff in the "back" first
          if (child != selectedElement) {
            removeGui(child);
          }
        }

        if (selectedElement != null && children.contains(selectedElement)) {
          // now remove the selected element
          removeGui(selectedElement);
        }
      }

      if (element instanceof MPerspective) {
        MPerspective perspective = (MPerspective) element;
        for (MWindow subWindow : perspective.getWindows()) {
          removeGui(subWindow);
        }
      } else if (element instanceof MWindow) {
        MWindow window = (MWindow) element;
        for (MWindow subWindow : window.getWindows()) {
          removeGui(subWindow);
        }

        if (window instanceof MTrimmedWindow) {
          MTrimmedWindow trimmedWindow = (MTrimmedWindow) window;
          for (MUIElement trimBar : trimmedWindow.getTrimBars()) {
            removeGui(trimBar);
          }
        }
      }

      if (element instanceof MContribution) {
        MContribution contribution = (MContribution) element;
        Object client = contribution.getObject();
        IEclipseContext parentContext = renderer.getContext(element);
        if (parentContext != null && client != null) {
          try {
            ContextInjectionFactory.invoke(client, PersistState.class, parentContext, null);
          } catch (Exception e) {
            if (logger != null) {
              logger.error(e);
            }
          }
        }
      }

      renderer.disposeWidget(element);

      // unset the client object
      if (element instanceof MContribution) {
        MContribution contribution = (MContribution) element;
        Object client = contribution.getObject();
        IEclipseContext parentContext = renderer.getContext(element);
        if (parentContext != null && client != null) {
          try {
            ContextInjectionFactory.uninject(client, parentContext);
          } catch (Exception e) {
            if (logger != null) {
              logger.error(e);
            }
          }
        }
        contribution.setObject(null);
      }

      // dispose the context
      if (element instanceof MContext) {
        clearContext((MContext) element);
      }
    }

    if (removeRoot == element) removeRoot = null;
  }
  public Object safeCreateGui(
      MUIElement element, Object parentWidget, IEclipseContext parentContext) {
    if (!element.isToBeRendered()) return null;

    if (!renderedElements.contains(element)) renderedElements.add(element);

    // no creates while processing a remove
    if (removeRoot != null) {
      return null;
    }

    Object currentWidget = element.getWidget();
    if (currentWidget != null) {
      if (currentWidget instanceof Control) {
        Control control = (Control) currentWidget;
        // make sure the control is visible
        control.setVisible(true);

        if (parentWidget instanceof Composite) {
          Composite currentParent = control.getParent();
          if (currentParent != parentWidget) {
            // check if the original parent was a tab folder
            if (currentParent instanceof CTabFolder) {
              CTabFolder folder = (CTabFolder) currentParent;
              // if we used to be the tab folder's top right
              // control, unset it
              if (folder.getTopRight() == control) {
                folder.setTopRight(null);
              }
            }

            // the parents are different so we should reparent it
            control.setParent((Composite) parentWidget);
          }
        }
      }

      // Reparent the context (or the kid's context)
      if (element instanceof MContext) {
        IEclipseContext ctxt = ((MContext) element).getContext();
        if (ctxt != null) ctxt.setParent(parentContext);
      } else {
        List<MContext> childContexts =
            modelService.findElements(element, null, MContext.class, null);
        for (MContext c : childContexts) {
          // Ensure that we only reset the context of our direct
          // children
          MUIElement kid = (MUIElement) c;
          MUIElement parent = kid.getParent();
          if (parent == null && kid.getCurSharedRef() != null)
            parent = kid.getCurSharedRef().getParent();
          if (!(element instanceof MPlaceholder) && parent != element) continue;

          if (c.getContext() != null && c.getContext().getParent() != parentContext) {
            c.getContext().setParent(parentContext);
          }
        }
      }

      // Now that we have a widget let the parent (if any) know
      if (element.getParent() instanceof MUIElement) {
        MElementContainer<MUIElement> parentElement = element.getParent();
        AbstractPartRenderer parentRenderer = getRendererFor(parentElement);
        if (parentRenderer != null) parentRenderer.childRendered(parentElement, element);
      }
      return element.getWidget();
    }

    if (element instanceof MContext) {
      MContext ctxt = (MContext) element;
      // Assert.isTrue(ctxt.getContext() == null,
      // "Before rendering Context should be null");
      if (ctxt.getContext() == null) {
        IEclipseContext lclContext = parentContext.createChild(getContextName(element));
        populateModelInterfaces(ctxt, lclContext, element.getClass().getInterfaces());
        ctxt.setContext(lclContext);

        // System.out.println("New Context: " + lclContext.toString()
        // + " parent: " + parentContext.toString());

        // make sure the context knows about these variables that have
        // been defined in the model
        for (String variable : ctxt.getVariables()) {
          lclContext.declareModifiable(variable);
        }

        Map<String, String> props = ctxt.getProperties();
        for (String key : props.keySet()) {
          lclContext.set(key, props.get(key));
        }

        E4Workbench.processHierarchy(element);
      }
    }

    // Create a control appropriate to the part
    Object newWidget = createWidget(element, parentWidget);

    // Remember that we've created the control
    if (newWidget != null) {
      AbstractPartRenderer renderer = getRendererFor(element);

      // Have the renderer hook up any widget specific listeners
      renderer.hookControllerLogic(element);

      // Process its internal structure through the renderer that created
      // it
      if (element instanceof MElementContainer) {
        renderer.processContents((MElementContainer<MUIElement>) element);
      }

      // Allow a final chance to set up
      renderer.postProcess(element);

      // Now that we have a widget let the parent (if any) know
      if (element.getParent() instanceof MUIElement) {
        MElementContainer<MUIElement> parentElement = element.getParent();
        AbstractPartRenderer parentRenderer = getRendererFor(parentElement);
        if (parentRenderer != null) parentRenderer.childRendered(parentElement, element);
      }
    } else {
      // failed to create the widget, dispose its context if necessary
      if (element instanceof MContext) {
        MContext ctxt = (MContext) element;
        IEclipseContext lclContext = ctxt.getContext();
        if (lclContext != null) {
          lclContext.dispose();
          ctxt.setContext(null);
        }
      }
    }

    return newWidget;
  }
        public void handleEvent(Event event) {

          Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
          if (!(changedObj instanceof MElementContainer<?>)) return;

          MElementContainer<MUIElement> changedElement = (MElementContainer<MUIElement>) changedObj;
          boolean isApplication = changedObj instanceof MApplication;

          boolean menuChild = changedObj instanceof MMenu;
          // If the parent isn't in the UI then who cares?
          AbstractPartRenderer renderer = getRendererFor(changedElement);
          if ((!isApplication && renderer == null) || menuChild) return;

          String eventType = (String) event.getProperty(UIEvents.EventTags.TYPE);
          if (UIEvents.EventTypes.ADD.equals(eventType)) {
            Activator.trace(Policy.DEBUG_RENDERER, "Child Added", null); // $NON-NLS-1$
            MUIElement added = (MUIElement) event.getProperty(UIEvents.EventTags.NEW_VALUE);

            // OK, we have a new -visible- part we either have to create
            // it or host it under the correct parent. Note that we
            // explicitly do *not* render non-selected elements in
            // stacks (to support lazy loading).
            boolean isStack = changedObj instanceof MGenericStack<?>;
            boolean hasWidget = added.getWidget() != null;
            boolean isSelected = added == changedElement.getSelectedElement();
            boolean renderIt = !isStack || hasWidget || isSelected;
            if (renderIt) {
              // NOTE: createGui will call 'childAdded' if successful
              Object w = createGui(added);
              if (w instanceof Control && !(w instanceof Shell)) {
                final Control ctrl = (Control) w;
                fixZOrder(added);
                if (!ctrl.isDisposed()) {
                  ctrl.getShell().layout(new Control[] {ctrl}, SWT.DEFER);
                }
              }
            } else {
              if (renderer != null && added.isToBeRendered())
                renderer.childRendered(changedElement, added);
            }

            // If the element being added is a placeholder, check to see if
            // it's 'globally visible' and, if so, remove all other
            // 'local' placeholders referencing the same element.
            int newLocation = modelService.getElementLocation(added);
            if (newLocation == EModelService.IN_SHARED_AREA
                || newLocation == EModelService.OUTSIDE_PERSPECTIVE) {
              MWindow topWin = modelService.getTopLevelWindowFor(added);
              modelService.hideLocalPlaceholders(topWin, null);
            }
          } else if (UIEvents.EventTypes.REMOVE.equals(eventType)) {
            Activator.trace(Policy.DEBUG_RENDERER, "Child Removed", null); // $NON-NLS-1$
            MUIElement removed = (MUIElement) event.getProperty(UIEvents.EventTags.OLD_VALUE);
            // Removing invisible elements is a NO-OP as far as the
            // renderer is concerned
            if (!removed.isToBeRendered()) return;

            if (removed.getWidget() instanceof Control) {
              Control ctrl = (Control) removed.getWidget();
              ctrl.setLayoutData(null);
              ctrl.getParent().layout(new Control[] {ctrl}, SWT.CHANGED | SWT.DEFER);
            }

            // Ensure that the element about to be removed is not the
            // selected element
            if (changedElement.getSelectedElement() == removed)
              changedElement.setSelectedElement(null);

            if (renderer != null) renderer.hideChild(changedElement, removed);
          }
        }