@Override
  public Object compute(IEclipseContext context, String contextKey) {
    // look for the top-most MWindow in the context chain:

    // 1st: go up the tree to find topmost MWindow
    MWindow window = null;
    IEclipseContext current = context;
    do {
      MContext model = current.get(MContext.class);
      if (model instanceof MWindow) window = (MWindow) model;
      current = current.getParent();
    } while (current != null);

    if (window == null) {
      if (context.get(MApplication.class) != null) {
        // called from Application scope
        return ContextInjectionFactory.make(ApplicationPartServiceImpl.class, context);
      }
      return IInjector.NOT_A_VALUE;
    }

    IEclipseContext windowContext = window.getContext();
    PartServiceImpl service = windowContext.getLocal(PartServiceImpl.class);
    if (service == null) {
      service = ContextInjectionFactory.make(PartServiceImpl.class, windowContext);
      windowContext.set(PartServiceImpl.class, service);
    }
    return service;
  }
  private void clearContext(MContext contextME) {
    MContext ctxt = (MContext) contextME;
    IEclipseContext lclContext = ctxt.getContext();
    if (lclContext != null) {
      IEclipseContext parentContext = lclContext.getParent();
      IEclipseContext child = parentContext.getActiveChild();
      if (child == lclContext) {
        child.deactivate();
      }

      ctxt.setContext(null);
      lclContext.dispose();
    }
  }
    @Override
    public boolean update(IEclipseContext eventsContext, int eventType, Object[] extraArguments) {
      if (eventType == ContextChangeEvent.INITIAL) {
        // needs to be done inside runnable to establish dependencies
        for (int i = 0; i < keys.length; i++) {
          if (keys[i] == null) continue;
          IEclipseContext targetContext = (active[i]) ? context.getActiveLeaf() : context;
          if (ECLIPSE_CONTEXT_NAME.equals(keys[i])) {
            result[i] = targetContext;
            IEclipseContext parent = targetContext.getParent(); // creates pseudo-link
            if (parent == null)
              targetContext.get(ECLIPSE_CONTEXT_NAME); // pseudo-link in case there is no parent
          } else if (targetContext.containsKey(keys[i])) result[i] = targetContext.get(keys[i]);
        }
        return true;
      }

      if (eventType == ContextChangeEvent.DISPOSE) {
        if (eventsContext == context) {
          ContextObjectSupplier originatingSupplier =
              eventsContext.getLocal(ContextObjectSupplier.class);
          requestor.disposed(originatingSupplier);
          return false;
        }
      } else if (eventType == ContextChangeEvent.UNINJECTED) {
        if (eventsContext == context) {
          ContextObjectSupplier originatingSupplier =
              eventsContext.getLocal(ContextObjectSupplier.class);
          return requestor.uninject(extraArguments[0], originatingSupplier);
        }
      } else {
        if (!requestor.isValid()) return false; // remove this listener
        requestor.resolveArguments(false);
        requestor.execute();
      }
      return true;
    }
  public Object createWidget(final MUIElement element, Object parent) {
    MPlaceholder ph = (MPlaceholder) element;
    final MUIElement ref = ph.getRef();
    ref.setCurSharedRef(ph);

    List<MPlaceholder> renderedRefs = renderedMap.get(ref);
    if (renderedRefs == null) {
      renderedRefs = new ArrayList<MPlaceholder>();
      renderedMap.put(ref, renderedRefs);
    }

    if (!renderedRefs.contains(ph)) renderedRefs.add(ph);

    Composite newComp = new Composite((Composite) parent, SWT.NONE);
    newComp.setLayout(new FillLayout());

    Control refWidget = (Control) ref.getWidget();
    if (refWidget == null) {
      ref.setToBeRendered(true);
      refWidget = (Control) renderingEngine.createGui(ref, newComp, getContextForParent(ref));
    } else {
      if (refWidget.getParent() != newComp) {
        refWidget.setParent(newComp);
      }
    }

    if (ref instanceof MContext) {
      IEclipseContext context = ((MContext) ref).getContext();
      IEclipseContext newParentContext = getContext(ph);
      if (context.getParent() != newParentContext) {
        context.setParent(newParentContext);
      }
    }

    return newComp;
  }
 public void activateBranch() {
   for (IEclipseContext i = this; i != null; i = i.getParent()) {
     i.activate();
   }
 }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer#disposeWidget
   * (org.eclipse.e4.ui.model.application.ui.MUIElement)
   */
  @Override
  public void disposeWidget(MUIElement element) {
    MPlaceholder ph = (MPlaceholder) element;
    MUIElement refElement = ph.getRef();
    Control refCtrl = (Control) refElement.getWidget();

    // Remove the element ref from the rendered list
    List<MPlaceholder> refs = renderedMap.get(refElement);
    refs.remove(ph);

    IEclipseContext curContext = modelService.getContainingContext(ph);

    if (refs.size() == 0) {
      // Ensure that the image is the 'original' image for this
      // part. See bug 347471 for details
      if (refElement instanceof MPart) {
        MPart thePart = (MPart) refElement;
        String imageURI = thePart.getIconURI();
        thePart.setIconURI(null);
        thePart.setIconURI(imageURI);
      }

      renderingEngine.removeGui(refElement);
    } else {
      // Ensure that the dispose of the element reference doesn't cascade
      // to dispose the 'real' part
      if (refCtrl != null && !refCtrl.isDisposed()) {
        MPlaceholder currentRef = refElement.getCurSharedRef();
        if (currentRef == ph) {
          // Find another *rendered* ref to pass the part on to
          for (MPlaceholder aPH : refs) {
            Composite phComp = (Composite) aPH.getWidget();
            if (phComp == null || phComp.isDisposed()) continue;

            // Reparent the context(s) (if any)
            IEclipseContext newParentContext = modelService.getContainingContext(aPH);
            List<MContext> allContexts =
                modelService.findElements(refElement, null, MContext.class, null);
            for (MContext ctxtElement : allContexts) {
              IEclipseContext theContext = ctxtElement.getContext();
              // this may be null if it hasn't been rendered yet
              if (theContext != null) {
                if (theContext.getParent() == curContext) {
                  // about to reparent the context, if we're
                  // the active child of the current parent,
                  // deactivate ourselves first
                  if (curContext.getActiveChild() == theContext) {
                    theContext.deactivate();
                  }
                  theContext.setParent(newParentContext);
                }
              }
            }

            // reset the 'cur' ref
            refElement.setCurSharedRef(aPH);

            // Reparent the widget
            refCtrl.setParent(phComp);
            break;
          }
        } else if (currentRef != null) {
          Composite phComp = (Composite) currentRef.getWidget();
          if (phComp == null || phComp.isDisposed()) {
            super.disposeWidget(element);
            return;
          }

          // Reparent the context(s) (if any)
          IEclipseContext newParentContext = modelService.getContainingContext(currentRef);
          List<MContext> allContexts =
              modelService.findElements(refElement, null, MContext.class, null);
          for (MContext ctxtElement : allContexts) {
            IEclipseContext theContext = ctxtElement.getContext();
            // this may be null if it hasn't been rendered yet
            if (theContext != null && theContext.getParent() == curContext) {
              // about to reparent the context, if we're the
              // active child of the current parent, deactivate
              // ourselves first
              if (curContext.getActiveChild() == theContext) {
                theContext.deactivate();
              }
              theContext.setParent(newParentContext);
            }
          }
        }
      }
    }

    super.disposeWidget(element);
  }
  private void activate(MPart part, boolean requiresFocus, boolean activateBranch) {
    if (part == null) {
      if (constructed && activePart != null) {
        firePartDeactivated(activePart);
      }
      activePart = part;
      return;
    }

    // Delegate activations to a CompositePart's inner part (if any)
    if (part instanceof MCompositePart) {
      if (part.getContext() != null) {
        IEclipseContext pContext = part.getContext();
        if (pContext.getActiveLeaf() != null) {
          MPart inner = pContext.getActiveLeaf().get(MPart.class);
          if (inner != null) {
            part = inner;
          }
        }
      }
    }

    // only activate parts that is under our control
    if (!isInContainer(part)) {
      return;
    }

    MWindow window = getWindow();
    IEclipseContext windowContext = window.getContext();
    // check if the active part has changed or if we are no longer the active window
    if (windowContext.getParent().getActiveChild() == windowContext && part == activePart) {
      // insert it in the beginning of the activation history, it may not have been inserted
      // pending when this service was instantiated
      partActivationHistory.prepend(part);
      UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
      return;
    }
    if (contextService != null) {
      contextService.deferUpdates(true);
    }
    if (contextManager != null) {
      contextManager.deferUpdates(true);
    }

    MPart lastActivePart = activePart;
    activePart = part;

    if (constructed && lastActivePart != null && lastActivePart != activePart) {
      firePartDeactivated(lastActivePart);
    }

    try {
      // record any sibling into the activation history if necessary, this will allow it to be
      // reselected again in the future as it will be an activation candidate in the future,
      // this
      // prevents other unrendered elements from being selected arbitrarily which would cause
      // unwanted bundle activation
      recordStackActivation(part);

      delegateBringToTop(part);
      window.getParent().setSelectedElement(window);

      partActivationHistory.activate(part, activateBranch);

      if (requiresFocus) {
        IPresentationEngine pe = part.getContext().get(IPresentationEngine.class);
        pe.focusGui(part);
      }

      firePartActivated(part);
      UIEvents.publishEvent(UIEvents.UILifeCycle.ACTIVATE, part);
    } finally {
      if (contextService != null) {
        contextService.deferUpdates(false);
      }
      if (contextManager != null) {
        contextManager.deferUpdates(false);
      }
    }
  }
 private boolean isActiveChild(MPart part) {
   IEclipseContext context = part.getContext();
   return context != null && context.getParent().getActiveChild() == context;
 }
  private void showElementRecursive(MUIElement element) {
    if (!element.isToBeRendered()) {
      return;
    }

    if (element instanceof MPlaceholder && element.getWidget() != null) {
      MPlaceholder ph = (MPlaceholder) element;
      MUIElement ref = ph.getRef();

      if (ref.getCurSharedRef() != ph) {
        ref.setCurSharedRef(ph);
        WPlaceholderWidget placeholder = (WPlaceholderWidget) ph.getWidget();
        @SuppressWarnings("unchecked")
        WLayoutedWidget<MUIElement> content = (WLayoutedWidget<MUIElement>) ref.getWidget();
        placeholder.setContent(content);
      }

      element = ref;
    }

    if (element instanceof MContext) {
      IEclipseContext context = ((MContext) element).getContext();
      if (context != null) {
        IEclipseContext newParentContext = modelService.getContainingContext(element);
        if (context.getParent() != newParentContext) {
          context.setParent(newParentContext);
        }
      }
    }

    if (element instanceof MWindow && element.getWidget() != null) {
      int visCount = 0;
      for (MUIElement kid : ((MWindow) element).getChildren()) {
        if (kid.isToBeRendered() && kid.isVisible()) visCount++;
      }
      if (visCount > 0) element.setVisible(true);
    }

    if (element instanceof MGenericStack) {
      MGenericStack<?> container = (MGenericStack<?>) element;
      MUIElement curSel = container.getSelectedElement();
      if (curSel == null && container.getChildren().size() > 0) {
        curSel = container.getChildren().get(0);
      }
      if (curSel != null) {
        showElementRecursive(curSel);
      }
    } else if (element instanceof MElementContainer<?>) {
      MElementContainer<?> container = (MElementContainer<?>) element;
      for (MUIElement childElement : container.getChildren().toArray(new MUIElement[0])) {
        showElementRecursive(childElement);
      }

      // OK, now process detached windows
      if (element instanceof MWindow) {
        for (MWindow w : ((MWindow) element).getWindows()) {
          showElementRecursive(w);
        }
      } else if (element instanceof MPerspective) {
        for (MWindow w : ((MPerspective) element).getWindows()) {
          showElementRecursive(w);
        }
      }
    }
  }
  private void showElementRecursive(MUIElement element) {
    if (!element.isToBeRendered()) return;

    if (element instanceof MPlaceholder && element.getWidget() != null) {
      MPlaceholder ph = (MPlaceholder) element;
      MUIElement ref = ph.getRef();
      ref.setCurSharedRef(ph);

      ComponentContainer phComponent = (ComponentContainer) ph.getWidget();
      Component refComponent = (Component) ph.getRef().getWidget();
      phComponent.addComponent(refComponent);

      element = ref;

      // top right folder
      MPartStack topLeftStack = HierarchyUtils.findTopLeftFolder(ph.getRef());
      if (topLeftStack != null) {
        if (ph.getTags().contains(IPresentationEngine.MAXIMIZED))
          ((StackWidget) topLeftStack.getWidget()).setState(1);
        else if (ph.getTags().contains(IPresentationEngine.MINIMIZED))
          ((StackWidget) topLeftStack.getWidget()).setState(-1);
        else ((StackWidget) topLeftStack.getWidget()).setState(0);
      }
    }

    if (element instanceof MContext) {
      IEclipseContext context = ((MContext) element).getContext();
      if (context != null) {
        IEclipseContext newParentContext = modelService.getContainingContext(element);
        if (context.getParent() != newParentContext) {
          context.setParent(newParentContext);
        }
      }
    }

    // Show any floating windows
    if (element instanceof MWindow && element.getWidget() != null) {
      int visCount = 0;
      for (MUIElement kid : ((MWindow) element).getChildren()) {
        if (kid.isToBeRendered() && kid.isVisible()) visCount++;
      }
      if (visCount > 0) element.setVisible(true);
    }

    if (element instanceof MElementContainer<?>) {
      MElementContainer<?> container = (MElementContainer<?>) element;
      List<MUIElement> kids = new ArrayList<MUIElement>(container.getChildren());
      for (MUIElement childElement : kids) {
        showElementRecursive(childElement);
      }

      // OK, now process detached windows
      if (element instanceof MWindow) {
        for (MWindow w : ((MWindow) element).getWindows()) {
          showElementRecursive(w);
        }
      } else if (element instanceof MPerspective) {
        for (MWindow w : ((MPerspective) element).getWindows()) {
          showElementRecursive(w);
        }
      }
    }
  }