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;
  }