@Override
  public boolean isPartVisible(MPart part) {
    if (isInContainer(part)) {
      MUIElement element = part;
      MElementContainer<?> parent = part.getParent();
      if (parent == null) {
        // might be a shared part
        element = part.getCurSharedRef();
        if (element == null) {
          return false;
        }

        parent = element.getParent();
        if (parent == null) {
          return false;
        }
      }

      if (parent instanceof MPartStack) {
        return parent.getSelectedElement() == element;
      }

      return element.isVisible();
    }
    return false;
  }
  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);
  }
 /** @param parent */
 private void setStackVisibility(MElementContainer<MUIElement> parent) {
   for (MUIElement child : parent.getChildren()) {
     if (child.isToBeRendered() && child.isVisible()) {
       parent.setToBeRendered(true);
       return;
     }
   }
   parent.setToBeRendered(false);
   // continue modifying the visibility as the parent's parent may also
   // need to be hidden from the user
   setStackVisibility(parent.getParent());
 }
  @Override
  public Image getImage(Object element, Display display) {
    if (element instanceof MUIElement) {
      MUIElement uiElement = (MUIElement) element;
      if (uiElement.isToBeRendered() && uiElement.isVisible()) {
        return createImage(ResourceProvider.IMG_WizardDialog);
      } else {
        return createImage(ResourceProvider.IMG_Tbr_WizardDialog);
      }
    }

    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);
            }
          }
        }
  @Override
  public void childRendered(MPerspectiveStack parentElement, MUIElement element) {
    if (inLazyInit || inContentProcessing(parentElement) || !element.isVisible()) {
      return;
    }

    WPerspectiveStack<N, I, IC> stack = getWidget(parentElement);
    for (WStackItem<I, IC> i : stack.getItems()) {
      if (i.getDomElement() == element) {
        return;
      }
    }

    int idx = getRenderedIndex(parentElement, element);
    AbstractRenderer<MPerspective, ?> renderer = factory.getRenderer(element);
    stack.addItems(
        idx, Collections.singletonList(createStackItem(stack, (MPerspective) element, renderer)));
  }
  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);
        }
      }
    }
  }