Fix potential class cast exception during selection handling
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / model / AbstractUtility.java
index e335480a8e2e36e7c27b8e75f65ad902ced113ca..3d394830b538ceec6c9dab2dce9a9b7d6dd58595 100644 (file)
@@ -1,4 +1,3 @@
-// $Id$
 /**
  * Copyright (C) 2007 EDIT
  * European Distributed Institute of Taxonomy
 
 package eu.etaxonomy.taxeditor.model;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.TreeSet;
+import java.util.UUID;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.commands.operations.AbstractOperation;
 import org.eclipse.core.commands.operations.IOperationHistory;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.ILog;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
@@ -29,12 +34,14 @@ import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.resource.ColorRegistry;
 import org.eclipse.jface.resource.FontRegistry;
-import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.widgets.Display;
@@ -45,27 +52,36 @@ import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.internal.E4PartWrapper;
 import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.progress.IProgressConstants;
 import org.eclipse.ui.progress.IProgressService;
 import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
 import org.eclipse.ui.themes.ITheme;
 import org.eclipse.ui.themes.IThemeManager;
 
+import eu.etaxonomy.cdm.api.application.CdmApplicationState;
+import eu.etaxonomy.cdm.api.service.IProgressMonitorService;
+import eu.etaxonomy.cdm.common.monitor.IRemotingProgressMonitor;
 import eu.etaxonomy.cdm.model.common.IEnumTerm;
 import eu.etaxonomy.taxeditor.operation.AbstractPostOperation;
+import eu.etaxonomy.taxeditor.operation.IFeedbackGenerator;
+import eu.etaxonomy.taxeditor.operation.IPostMoniteredOperationEnabled;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
+import eu.etaxonomy.taxeditor.operation.RemotingCdmHandler;
+import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;
+import eu.etaxonomy.taxeditor.ui.dialog.ReportTextDialog;
 import eu.etaxonomy.taxeditor.view.AbstractCdmDataViewer;
 import eu.etaxonomy.taxeditor.view.detail.DetailsViewPart;
 import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
 
 /**
- * <p>
- * Abstract AbstractUtility class.
- * </p>
  *
  * @author n.hoffmann
  * @created 11.05.2009
@@ -73,853 +89,523 @@ import eu.etaxonomy.taxeditor.view.supplementaldata.SupplementalDataViewPart;
  */
 public abstract class AbstractUtility {
 
-       /** Constant <code>statusLineManager</code> */
-       protected static IStatusLineManager statusLineManager;
-
-       /**
-        * <p>
-        * closeAll
-        * </p>
-        *
-        * @return a boolean.
-        */
-       public static boolean closeAll() {
-               return getActivePage().closeAllEditors(true);
-       }
-
-       /**
-        * Close the given editor.
-        *
-        * @param editor
-        *            The <tt>MultipageTaxonEditor</tt> to close.
-        * @return <tt>true</tt> on success
-        */
-       public static boolean close(EditorPart editor) {
-               return getActivePage().closeEditor(editor, true);
-       }
-
-       /**
-        * <p>
-        * getShell
-        * </p>
-        *
-        * @return a {@link org.eclipse.swt.widgets.Shell} object.
-        */
-       public static Shell getShell() {
-
-               return TaxeditorStorePlugin.getDefault().getWorkbench()
-                               .getActiveWorkbenchWindow().getShell();
-       }
-
-       /**
-        * <p>
-        * getActivePage
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IWorkbenchPage} object.
-        */
-       public static IWorkbenchPage getActivePage() {
-
-               return TaxeditorStorePlugin.getDefault().getWorkbench()
-                               .getActiveWorkbenchWindow().getActivePage();
-       }
-
-       /**
-        * <p>
-        * getActivePart
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IWorkbenchPart} object.
-        */
-       public static IWorkbenchPart getActivePart() {
-               return getActivePage() != null ? getActivePage().getActivePart() : null;
-       }
-
-       public static IWorkbench getWorkbench() {
-               return TaxeditorStorePlugin.getDefault().getWorkbench();
-       }
-
-       /**
-        * <p>
-        * getWorkbenchWindow
-        * </p>
-        *
-        * @return a {@link org.eclipse.jface.window.ApplicationWindow} object.
-        */
-       public static ApplicationWindow getWorkbenchWindow() {
-               if (getWorkbench().getWorkbenchWindowCount() > 1) {
-                       throw new IllegalStateException("More than one workbench window");
-               }
-               return (ApplicationWindow) getWorkbench().getWorkbenchWindows()[0];
-       }
-
-       /**
-        * <p>
-        * showView
-        * </p>
-        *
-        * @param id
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static IViewPart showView(String id) {
-               try {
-                       return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-                                       .getActivePage()
-                                       .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
-               } catch (PartInitException e) {
-                       errorDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
-                       return null;
-               }
-       }
-
-       /**
-        * <p>
-        * hideView
-        * </p>
-        *
-        * @param view
-        *            a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static void hideView(IViewPart view) {
-               PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
-                               .hideView(view);
-       }
-
-       /**
-        * <p>
-        * getView
-        * </p>
-        *
-        * @param id
-        *            a {@link java.lang.String} object.
-        * @param restore
-        *            a boolean.
-        * @return a {@link org.eclipse.ui.IViewPart} object.
-        */
-       public static IViewPart getView(String id, boolean restore) {
-               IViewReference[] references = PlatformUI.getWorkbench()
-                               .getActiveWorkbenchWindow().getActivePage().getViewReferences();
-               for (IViewReference reference : references) {
-                       if (reference.getId().equals(id)) {
-                               return reference.getView(restore);
-                       }
-               }
-               return null;
-       }
-
-       /**
-        * <p>
-        * getService
-        * </p>
-        *
-        * @param api
-        *            a {@link java.lang.Class} object.
-        * @return a {@link java.lang.Object} object.
-        */
-       public static Object getService(Class api) {
-               return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
-       }
-
-       /**
-        * <p>
-        * getCurrentTheme
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.themes.ITheme} object.
-        */
-       public static ITheme getCurrentTheme() {
-               IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
-                               .getWorkbench().getThemeManager();
-               return themeManager.getCurrentTheme();
-       }
-
-       /**
-        * Fonts registered to the plugin may be obtained with the Eclipse themeing
-        * functionality. Thus fonts are chooseable by the user via
-        * Preferences->General->Appearance->Colors and Fonts
-        *
-        * @return the FontRegistry for the current theme
-        */
-       public static FontRegistry getFontRegistry() {
-               return getCurrentTheme().getFontRegistry();
-       }
-
-       /**
-        * <p>
-        * getFont
-        * </p>
-        *
-        * @param symbolicName
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.swt.graphics.Font} object.
-        */
-       public static Font getFont(String symbolicName) {
-               return getFontRegistry().get(symbolicName);
-       }
-
-       /**
-        * Color registered to the plugin may be obtained with the Eclipse themeing
-        * functionality. Thus colors are editable by the user via
-        * Preferences->General->Appearance->Colors and Fonts
-        *
-        * @return the ColorRegistry for the current theme
-        */
-       public static ColorRegistry getColorRegistry() {
-               return getCurrentTheme().getColorRegistry();
-       }
-
-       /**
-        * <p>
-        * getColor
-        * </p>
-        *
-        * @param symbolicName
-        *            a {@link java.lang.String} object.
-        * @return a {@link org.eclipse.swt.graphics.Color} object.
-        */
-       public static Color getColor(String symbolicName) {
-               return getColorRegistry().get(symbolicName);
-       }
-
-       /**
-        * Open a message box that informs the user about unimplemented
-        * functionality. This method is for developer convenience.
-        *
-        * @param source
-        *            a {@link java.lang.Object} object.
-        */
-       public static void notImplementedMessage(Object source) {
-               warningDialog("Not yet implemented", source,
-                               "This functionality is not yet implemented.");
-       }
-
-       /**
-        * <p>
-        * informationDialog
-        * </p>
-        *
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void informationDialog(final String title,
-                       final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
-            public void run() {
-                               MessageDialog.openInformation(getShell(), title, message);
-                       }
-               });
-       }
-
-       public static void informationDialog(final String title,
-                       final IStatus status) {
-               informationDialog(title, status.getMessage());
-       }
-
-       /**
-        * <p>
-        * warningDialog
-        * </p>
-        *
-        * @param title
-        *            The dialogs title
-        * @param source
-        *            The object where the warning was generated (used by log4j)
-        * @param message
-        *            An informative String to be presented to the user
-        */
-       public static void warningDialog(final String title, final Object source,
-                       final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
-            public void run() {
-                               MessageDialog.openWarning(getShell(), title, message);
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : AbstractUtility.class;
-                               warn(clazz, message);
-                       }
-               });
-       }
-
-       /**
-        * @param title
-        * @param termBase
-        * @param status
-        */
-       public static void warningDialog(String title, Object source,
-                       IStatus status) {
-               warningDialog(title, source, status.getMessage());
-       }
-
-       /**
-        * <p>
-        * errorDialog
-        * </p>
-        *
-        * @param title
-        *            The dialogs title
-        * @param source
-        *            The object where the warning was generated (used by log4j)
-        * @param message
-        *            An informative String to be presented to the user
-        * @param title
-        *            The dialogs title
-        * @param t
-        *            a Throwable if one exists or null
-        */
-       public static void errorDialog(final String title, final Object source,
-                       final String message, final Throwable t) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
-            public void run() {
-                               MessageDialog.openError(getShell(), title, message + getCauseRecursively(t));
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : this.getClass();
-                               error(clazz, message, t);
-                       }
-
-                       private String getCauseRecursively(Throwable t) {
-                               if(t == null){
-                                       return "";
-                               }
-
-                               if(t.getCause() != null){
-                                       return getCauseRecursively(t.getCause());
-                               }else{
-                                       return String.format("\n\nException: %s\nMessage: %s", t.getClass().getSimpleName(), t.getMessage());
-                               }
-
-                       }
-               });
-       }
-
-       public static void errorDialog(final String title, final Object source,
-                       final String message){
-               errorDialog(title, source, message, null);
-       }
-
-       /**
-        * <p>
-        * errorDialog
-        * </p>
-        *
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param source
-        *            a {@link java.lang.Object} object.
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void errorDialog(final String title, final Object source,
-                       final IStatus status) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
-            public void run() {
-                               MessageDialog.openError(getShell(), title, status.getMessage());
-                               Class<? extends Object> clazz = source != null ? source
-                                               .getClass() : this.getClass();
-                               error(clazz, status.getMessage(), status.getException());
-                       }
-               });
-       }
-
-       /**
-        * <p>
-        * confirmDialog
-        * </p>
-        *
-        * @param title
-        *            a {@link java.lang.String} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        * @return a boolean.
-        */
-       public static boolean confirmDialog(String title, String message) {
-               return MessageDialog.openQuestion(getShell(), title, message);
-       }
-
-       /**
-        * <p>
-        * executeOperation
-        * </p>
-        *
-        * @param operation
-        *            a
-        *            {@link eu.etaxonomy.taxeditor.operation.AbstractPostTaxonOperation}
-        *            object.
-        * @return a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static IStatus executeOperation(final AbstractPostOperation operation) {
-               if (getOperationHistory() == null) {
-                       throw new IllegalArgumentException(
-                                       "There is no operation history for this context");
-               }
-
-               final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
-                               .getUIInfoAdapter(getShell());
-
-               IRunnableWithProgress runnable = new IRunnableWithProgress() {
-
-                       @Override
+    private static final Logger logger = Logger.getLogger(AbstractUtility.class);
+
+    /** Constant <code>statusLineManager</code> */
+    protected static IStatusLineManager statusLineManager;
+
+
+    public static boolean closeAll() {
+        if(getActivePage()!=null){
+            return getActivePage().closeAllEditors(true);
+        }
+        return false;
+    }
+
+    /**
+     * Close the given editor.
+     *
+     * @param editor
+     *            The <tt>MultipageTaxonEditor</tt> to close.
+     * @return <tt>true</tt> on success
+     */
+    public static boolean close(EditorPart editor) {
+        return getActivePage() != null ? getActivePage().closeEditor(editor, true):false;
+    }
+
+    public static Shell getShell() {
+
+        return TaxeditorStorePlugin.getDefault().getWorkbench()
+                .getActiveWorkbenchWindow().getShell();
+    }
+
+    public static IWorkbenchPage getActivePage() {
+        try{
+            return TaxeditorStorePlugin.getDefault().getWorkbench()
+                    .getActiveWorkbenchWindow().getActivePage();
+        } catch(NullPointerException npe){
+            return null;
+        }
+    }
+
+    public static IWorkbenchPart getActiveWorkbenchPart() {
+        IWorkbenchPage activePage = getActivePage();
+        if(activePage!=null){
+            IWorkbenchPart activePart = activePage.getActivePart();
+            if(activePart!=null){
+                return activePart;
+            }
+        }
+        return null;
+    }
+
+    public static Object getActiveE4Part() {
+        IWorkbenchPage activePage = getActivePage();
+        if(activePage!=null){
+            IWorkbenchPart activePart = activePage.getActivePart();
+            Object e4WrappedPart = getE4WrappedPart(activePart);
+            return e4WrappedPart!=null?e4WrappedPart:activePart;
+        }
+        return null;
+    }
+
+    public static Object getE4WrappedPart(Object activePart){
+        if(activePart instanceof E4PartWrapper){
+            //FIXME can be removed when E4 migration is complete
+            try {
+                Field field = activePart.getClass().getDeclaredField("wrappedPart");
+                field.setAccessible(true);
+                Object object = field.get(activePart);
+                if(object instanceof MPart){
+                    return ((MPart) object).getObject();
+                }
+            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    public static IWorkbench getWorkbench() {
+        return TaxeditorStorePlugin.getDefault().getWorkbench();
+    }
+
+    public static IWorkbenchWindow getWorkbenchWindow() {
+        if (getWorkbench().getWorkbenchWindowCount() > 1) {
+            throw new IllegalStateException("More than one workbench window");
+        }
+        return getWorkbench().getWorkbenchWindows()[0];
+    }
+
+    public static IViewPart showView(String id) {
+        try {
+            return PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                    .getActivePage()
+                    .showView(id, null, IWorkbenchPage.VIEW_VISIBLE);
+        } catch (PartInitException e) {
+            MessagingUtils.messageDialog("Error opening view", AbstractUtility.class, "Could not open view: " + id, e);
+            return null;
+        }
+    }
+
+    public static void hideView(IViewPart view) {
+        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+        .hideView(view);
+    }
+
+    public static IViewPart getView(String id, boolean restore) {
+       IWorkbench workbench = PlatformUI.getWorkbench();
+        IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
+       IViewReference[] references = null;
+       if(activeWorkbenchWindow!=null && activeWorkbenchWindow.getActivePage()!=null){
+           references = activeWorkbenchWindow.getActivePage().getViewReferences();
+       }
+       else if(workbench.getWorkbenchWindows().length>0 && workbench.getWorkbenchWindows()[0].getActivePage()!=null){
+               references = workbench.getWorkbenchWindows()[0].getActivePage().getViewReferences();
+       }
+       if(references!=null){
+               for (IViewReference reference : references) {
+                       if (reference.getId().equals(id)) {
+                               return reference.getView(restore);
+                       }
+               }
+       }
+        return null;
+    }
+
+    public static Object getService(Class api) {
+        return TaxeditorStorePlugin.getDefault().getWorkbench().getService(api);
+    }
+
+    public static ITheme getCurrentTheme() {
+        IThemeManager themeManager = TaxeditorStorePlugin.getDefault()
+                .getWorkbench().getThemeManager();
+        return themeManager.getCurrentTheme();
+    }
+
+    /**
+     * Fonts registered to the plugin may be obtained with the Eclipse themeing
+     * functionality. Thus fonts are chooseable by the user via
+     * Preferences->General->Appearance->Colors and Fonts
+     *
+     * @return the FontRegistry for the current theme
+     */
+    public static FontRegistry getFontRegistry() {
+        return getCurrentTheme().getFontRegistry();
+    }
+
+    public static Font getFont(String symbolicName) {
+        return getFontRegistry().get(symbolicName);
+    }
+
+    /**
+     * Color registered to the plugin may be obtained with the Eclipse themeing
+     * functionality. Thus colors are editable by the user via
+     * Preferences->General->Appearance->Colors and Fonts
+     *
+     * @return the ColorRegistry for the current theme
+     */
+    public static ColorRegistry getColorRegistry() {
+        return getCurrentTheme().getColorRegistry();
+    }
+
+    public static Color getColor(String symbolicName) {
+        return getColorRegistry().get(symbolicName);
+    }
+
+    public static IStatus executeOperation(final AbstractPostOperation operation) {
+        if (getOperationHistory() == null) {
+            throw new IllegalArgumentException(
+                    "There is no operation history for this context");
+        }
+
+        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
+                .getUIInfoAdapter(getShell());
+
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+
+            @Override
             public void run(IProgressMonitor monitor)
-                                       throws InvocationTargetException, InterruptedException {
-                               monitor.beginTask(operation.getLabel(), 100);
-                               IStatus status = Status.CANCEL_STATUS;
-                               try {
-                                       operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
-                                       status = getOperationHistory().execute(operation, monitor,
-                                                       uiInfoAdapter);
-                               } catch (ExecutionException e) {
-                                       errorDialog("Error executing operation", getClass(), String.format("An error occured while executing %s.", operation.getLabel()), e);
-                               } finally {
-                                       monitor.done();
-                               }
-
-                               String statusString = status.equals(Status.OK_STATUS) ? "completed"
-                                               : "cancelled";
-                               setStatusLine(operation.getLabel() + " " + statusString + ".");
-
-                       }
-               };
-
-               try {
-                       runInUI(runnable, null);
-               } catch (Exception e) {
-                       errorDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
-               }
-
-               // // Start the main progress monitor.
-               // IProgressMonitor newMonitor =
-               // startMainMonitor(getMonitor(),operation.getLabel(), 100);
-               //
-               // // Check whether operation was canceled and do some steps.
-               // workedChecked(newMonitor, 10);
-               //
-               // try {
-               // IStatus status = getOperationHistory().execute(operation, newMonitor,
-               // WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
-               //
-               // // Check whether operation was canceled and do some steps.
-               // workedChecked(newMonitor, 30);
-               //
-               // String statusString = status.equals(Status.OK_STATUS) ? "completed" :
-               // "cancelled";
-               // setStatusLine(operation.getLabel() + " " + statusString + ".");
-               //
-               // return status;
-               // } catch (ExecutionException e) {
-               // logger.error("Error executing operation: " + operation.getLabel(),
-               // e);
-               // errorDialog("Error executing operation: " + operation.getLabel(),
-               // "Please refer to the error log.");
-               // }
-               // finally {
-               //
-               // // Stop the progress monitor.
-               // newMonitor.done();
-               // }
-
-               IPostOperationEnabled postOperationEnabled = operation
-                               .getPostOperationEnabled();
-               if (postOperationEnabled != null) {
-                       postOperationEnabled.onComplete();
-               }
-               return Status.OK_STATUS;
-       }
-
-       /**
-        * <p>
-        * getOperationHistory
-        * </p>
-        *
-        * @return a {@link org.eclipse.core.commands.operations.IOperationHistory}
-        *         object.
-        */
-       public static IOperationHistory getOperationHistory() {
-               return getWorkbench().getOperationSupport().getOperationHistory();
-       }
-
-       /**
-        * <p>
-        * setStatusLine
-        * </p>
-        *
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void setStatusLine(final String message) {
-               Display.getDefault().asyncExec(new Runnable() {
-
-                       @Override
+                    throws InvocationTargetException, InterruptedException {
+                String operationlabel = operation.getLabel();
+                monitor.beginTask(operationlabel, 100);
+                IStatus status = Status.CANCEL_STATUS;
+                try {
+                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
+                    status = getOperationHistory().execute(operation, monitor,
+                            uiInfoAdapter);
+                } catch (ExecutionException e) {
+
+                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+
+                } finally {
+                    monitor.done();
+                }
+
+                String statusString = status.equals(Status.OK_STATUS) ? "completed"
+                        : "cancelled";
+                setStatusLine(operationlabel + " " + statusString + ".");
+
+            }
+        };
+
+        try {
+            runInUI(runnable, null);
+        } catch (Exception e) {
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+        }
+
+        IPostOperationEnabled postOperationEnabled = operation
+                .getPostOperationEnabled();
+        if (postOperationEnabled != null) {
+            postOperationEnabled.onComplete();
+        }
+        return Status.OK_STATUS;
+    }
+
+    public static IStatus executeOperation(final AbstractOperation operation, final RemotingCdmHandler handler) {
+        if (getOperationHistory() == null) {
+            throw new IllegalArgumentException(
+                    "There is no operation history for this context");
+        }
+
+        final IAdaptable uiInfoAdapter = WorkspaceUndoUtil
+                .getUIInfoAdapter(getShell());
+
+        IRunnableWithProgress runnable = new IRunnableWithProgress() {
+
+            @Override
+            public void run(IProgressMonitor monitor)
+                    throws InvocationTargetException, InterruptedException {
+                String operationlabel = operation.getLabel();
+                monitor.beginTask(operationlabel, 100);
+                IStatus status = Status.CANCEL_STATUS;
+                try {
+                    operation.addContext(IOperationHistory.GLOBAL_UNDO_CONTEXT);
+                    status = getOperationHistory().execute(operation, monitor,
+                            uiInfoAdapter);
+                    if(handler != null) {
+                        handler.postOperation(status);
+                    }
+                } catch (ExecutionException e) {
+                    MessagingUtils.operationDialog(this, e, TaxeditorStorePlugin.PLUGIN_ID, operationlabel, null);
+                } finally {
+                    monitor.done();
+                }
+
+                String statusString = status.equals(Status.OK_STATUS) ? "completed"
+                        : "cancelled";
+                setStatusLine(operationlabel + " " + statusString + ".");
+
+            }
+        };
+
+        try {
+            runInUI(runnable, null);
+        } catch (Exception e) {
+            MessagingUtils.messageDialog("Error executing operation", AbstractUtility.class, "An error occured while executing " + operation.getLabel(), e);
+        }
+
+        return Status.OK_STATUS;
+    }
+
+    /**
+     * Executes a remoting monitored operation
+     *
+     * @param label for the operation
+     * @param uuid of the remoting monitor already started on the server
+     * @param pollInterval in milliseconds
+     * @param cancelable flag which determines whether the operation can be cancelled
+     * @param postOp callback for running post operation logic
+     * @return
+     */
+    public static IStatus executeMoniteredOperation(final String label,
+            final UUID uuid,
+            final int pollInterval,
+            final boolean cancelable,
+            final IPostMoniteredOperationEnabled postOp,
+            final IFeedbackGenerator feedbackGenerator) {
+
+        try {
+            // get the remoting monitor the first time to make sure that the
+            // operation is valid
+            final IProgressMonitorService progressMonitorService = CdmApplicationState.getCurrentAppConfig().getProgressMonitorService();
+            final IRemotingProgressMonitor firstRemotingMonitor = progressMonitorService.getRemotingMonitor(uuid);
+            if(firstRemotingMonitor == null) {
+                throw new IllegalStateException("Remoting progress monitor is null");
+            }
+
+            Job job = new Job(label) {
+
+
+                @Override
+                public IStatus run(IProgressMonitor monitor) {
+                    // run the monitor until the operation is finished
+                    IRemotingProgressMonitor remotingMonitor;
+                    try {
+                        remotingMonitor = CdmStore.getProgressMonitorClientManager().pollMonitor(label,
+                                uuid,
+                                pollInterval,
+                                postOp,
+                                feedbackGenerator,
+                                monitor);
+                    } catch (Exception ex) {
+                        return new Status(Status.ERROR, TaxeditorStorePlugin.PLUGIN_ID, "Operation Interrupted", ex);
+                    }
+                    final StringBuilder reportSb = new StringBuilder();
+                    // collect reports
+                    for(String report : remotingMonitor.getReports()) {
+                        reportSb.append(report);
+                    }
+                    if(!StringUtils.isBlank(reportSb.toString())) {
+                        Display.getDefault().asyncExec(new Runnable() {
+                            @Override
+                            public void run() {
+                                // display reports with possibility to save
+                                ReportTextDialog dialog = new ReportTextDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
+                                dialog.setTitle(label + " Report");
+                                dialog.setReportText(reportSb.toString());
+                                dialog.open();
+                            }
+                        });
+                    }
+                    return Status.OK_STATUS;
+                }
+
+                @Override
+                protected void canceling() {
+                    CdmStore.getCurrentApplicationConfiguration().getProgressMonitorService().cancel(uuid);
+                }
+            };
+
+            // configure the job
+            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
+            job.setUser(true);
+            // schedule job
+            job.schedule();
+
+        } catch (Exception e) {
+            MessagingUtils.errorDialog("Error executing operation",
+                    AbstractUtility.class,
+                    "An error occured while executing " + label,
+                    TaxeditorStorePlugin.PLUGIN_ID,
+                    e,
+                    true);
+        }
+
+        return Status.OK_STATUS;
+    }
+
+    public static IOperationHistory getOperationHistory() {
+        return getWorkbench().getOperationSupport().getOperationHistory();
+    }
+
+    public static void setStatusLine(final String message) {
+        Display.getDefault().asyncExec(new Runnable() {
+
+            @Override
             public void run() {
-                               statusLineManager.setMessage(message);
-                       }
-
-               });
-
-       }
-
-       /**
-        * <p>
-        * getMonitor
-        * </p>
-        *
-        * @return a {@link org.eclipse.core.runtime.IProgressMonitor} object.
-        */
-       public static IProgressMonitor getMonitor() {
-               statusLineManager.setCancelEnabled(false);
-               return statusLineManager.getProgressMonitor();
-       }
-
-       /**
-        * Starts either the given {@link IProgressMonitor} if it's not
-        * <code>null</code> or a new {@link NullProgressMonitor}.
-        *
-        * @param progressMonitor
-        *            The {@link IProgressMonitor} or <code>null</code> if no
-        *            progress should be reported.
-        * @param taskName
-        *            The name of the main task.
-        * @param steps
-        *            The number of steps this task is subdivided into.
-        * @return The {@link IProgressMonitor}.
-        */
-       public static IProgressMonitor startMainMonitor(
-                       IProgressMonitor progressMonitor, String taskName, int steps) {
-               IProgressMonitor newMonitor = progressMonitor;
-               if (newMonitor == null) {
-                       newMonitor = new NullProgressMonitor();
-               }
-               newMonitor.beginTask(taskName == null ? "" : taskName, steps);
-               newMonitor.subTask(" ");
-               return newMonitor;
-       }
-
-       /**
-        * Creates a {@link SubProgressMonitor} if the given
-        * {@link IProgressMonitor} is not <code>null</code> and not a
-        * {@link NullProgressMonitor}.
-        *
-        * @param progressMonitor
-        *            The parent {@link IProgressMonitor} of the
-        *            {@link SubProgressMonitor} to be created.
-        * @param ticks
-        *            The number of steps this subtask is subdivided into. Must be a
-        *            positive number and must not be
-        *            {@link IProgressMonitor#UNKNOWN}.
-        * @return The {@link IProgressMonitor}.
-        */
-       public static IProgressMonitor getSubProgressMonitor(
-                       IProgressMonitor progressMonitor, int ticks) {
-               if (progressMonitor == null) {
-                       return new NullProgressMonitor();
-               }
-               if (progressMonitor instanceof NullProgressMonitor) {
-                       return progressMonitor;
-               }
-
-               return new SubProgressMonitor(progressMonitor, ticks);
-       }
-
-       /**
-        * Checks whether the user canceled this operation. If not canceled, the
-        * given number of steps are declared as done.
-        *
-        * @param newMonitor
-        *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
-        * @param steps
-        *            a int.
-        */
-       public static void workedChecked(IProgressMonitor newMonitor, int steps) {
-               // In case the progress monitor was canceled throw an exception.
-               if (newMonitor.isCanceled()) {
-                       throw new OperationCanceledException();
-               }
-               // Otherwise declare this step as done.
-               newMonitor.worked(steps);
-       }
-
-       /**
-        * Present a progress dialog to the user. This dialog will block the UI
-        *
-        * @param runnable
-        *            an implementation of {@link IRunnableWithProgress}
-        * @throws java.lang.InterruptedException
-        *             if any.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        */
-       public static void busyCursorWhile(IRunnableWithProgress runnable)
-                       throws InvocationTargetException, InterruptedException {
-               getProgressService().busyCursorWhile(runnable);
-       }
-
-       /**
-        * <p>
-        * runInUI
-        * </p>
-        *
-        * @see {@link IProgressService#runInUI(org.eclipse.jface.operation.IRunnableContext, IRunnableWithProgress, ISchedulingRule)}
-        * @param runnable
-        *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
-        *            object.
-        * @param rule
-        *            a {@link org.eclipse.core.runtime.jobs.ISchedulingRule}
-        *            object.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        * @throws java.lang.InterruptedException
-        *             if any.
-        */
-       public static void runInUI(IRunnableWithProgress runnable,
-                       ISchedulingRule rule) throws InvocationTargetException,
-                       InterruptedException {
-               getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
-       }
-
-       /**
-        * <p>
-        * run
-        * </p>
-        *
-        * @param fork
-        *            a boolean.
-        * @param cancelable
-        *            a boolean.
-        * @param runnable
-        *            a {@link org.eclipse.jface.operation.IRunnableWithProgress}
-        *            object.
-        * @throws java.lang.reflect.InvocationTargetException
-        *             if any.
-        * @throws java.lang.InterruptedException
-        *             if any.
-        */
-       public static void run(boolean fork, boolean cancelable,
-                       IRunnableWithProgress runnable) throws InvocationTargetException,
-                       InterruptedException {
-               getProgressService().run(fork, cancelable, runnable);
-       }
-
-       /**
-        * <p>
-        * getProgressService
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.progress.IProgressService} object.
-        */
-       public static IProgressService getProgressService() {
-               IWorkbench workbench = PlatformUI.getWorkbench();
-               return workbench.getProgressService();
-       }
-
-       /**
-        * <p>
-        * getProgressService2
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.progress.IWorkbenchSiteProgressService}
-        *         object.
-        */
-       public static IWorkbenchSiteProgressService getProgressService2() {
-               return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
-       }
-
-       /**
-        * <p>
-        * info
-        * </p>
-        *
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void info(String message) {
-               IStatus status = new Status(IStatus.INFO, getPluginId(), message);
-               info(status);
-       }
-
-       /**
-        * <p>
-        * info
-        * </p>
-        *
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void info(IStatus status) {
-               log(status);
-       }
-
-       /**
-        * <p>
-        * warn
-        * </p>
-        *
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        */
-       public static void warn(Class source, String message) {
-               IStatus status = new Status(IStatus.WARNING, getPluginId(), message);
-               getLog4JLogger(source).warn(message);
-               log(status);
-       }
-
-       public static void warn(Class source, IStatus status) {
-               getLog4JLogger(source).warn(status.getMessage(), status.getException());
-               log(status);
-       }
-
-       public static void warn(Class source, Throwable t) {
-               IStatus status = new Status(IStatus.WARNING, getPluginId(), t.getMessage(), t);
-               getLog4JLogger(source).warn(t);
-               log(status);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        *
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param t
-        *            a {@link java.lang.Throwable} object.
-        */
-       public static void error(Class source, Throwable t) {
-               error(source.getClass(), t.getMessage(), t);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        *
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param message
-        *            a {@link java.lang.String} object.
-        * @param t
-        *            a {@link java.lang.Throwable} object.
-        */
-       public static void error(Class source, String message, Throwable t) {
-               IStatus status = new Status(IStatus.ERROR, getPluginId(), message, t);
-               error(source, status);
-       }
-
-       /**
-        * <p>
-        * error
-        * </p>
-        *
-        * @param source
-        *            a {@link java.lang.Class} object.
-        * @param status
-        *            a {@link org.eclipse.core.runtime.IStatus} object.
-        */
-       public static void error(Class source, IStatus status) {
-               getLog4JLogger(source)
-                               .error(status.getMessage(), status.getException());
-               log(status);
-       }
-
-       /**
-        * <p>
-        * getLog4JLogger
-        * </p>
-        *
-        * @param clazz
-        *            a {@link java.lang.Class} object.
-        * @return a {@link org.apache.log4j.Logger} object.
-        */
-       public static Logger getLog4JLogger(Class clazz) {
-               return Logger.getLogger(clazz);
-       }
-
-       /**
-        * @see {@link ILog#log(IStatus)}
-        *
-        * @param status
-        */
-       private static void log(IStatus status) {
-               TaxeditorStorePlugin.getDefault().getLog().log(status);
-       }
-
-       /**
-        * <p>
-        * getPluginId
-        * </p>
-        *
-        * @return a {@link java.lang.String} object.
-        */
-       public static String getPluginId() {
-               return "eu.taxeditor";
-       }
-
-       /**
-        * <p>
-        * getActiveEditor
-        * </p>
-        *
-        * @return a {@link org.eclipse.ui.IEditorPart} object.
-        */
-       public static IEditorPart getActiveEditor() {
-               return getActivePage() != null ? getActivePage().getActiveEditor()
-                               : null;
-       }
-
-       /**
-        * <p>
-        * getDetailsView
-        * </p>
-        *
-        * @return a {@link eu.etaxonomy.taxeditor.view.detail.DetailsViewPart}
-        *         object.
-        */
-       public static DetailsViewPart getDetailsView() {
-               return (DetailsViewPart) getView(DetailsViewPart.ID, false);
-       }
-
-       /**
-        * <p>
-        * refreshDetailsViewer
-        * </p>
-        */
-       public static void refreshDetailsViewer() {
-               if (getDetailsView() != null) {
-                       ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
-               }
-       }
-
-       /**
-        * <p>
-        * reflowDetailsViewer
-        * </p>
-        */
-       public static void reflowDetailsViewer() {
-               if (getDetailsView() != null) {
-                       ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
-               }
-       }
-
-       public static SupplementalDataViewPart getSupplementalDataView() {
-               return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
-                               false);
-       }
-
-       public static void reflowSupplementalViewer() {
-               if (getSupplementalDataView() != null) {
-                       ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
-                                       .reflow();
-               }
-       }
+                statusLineManager.setMessage(message);
+            }
+
+        });
+
+    }
+
+    public static IProgressMonitor getMonitor() {
+        statusLineManager.setCancelEnabled(false);
+        return statusLineManager.getProgressMonitor();
+    }
+
+    /**
+     * Starts either the given {@link IProgressMonitor} if it's not
+     * <code>null</code> or a new {@link NullProgressMonitor}.
+     *
+     * @param progressMonitor
+     *            The {@link IProgressMonitor} or <code>null</code> if no
+     *            progress should be reported.
+     * @param taskName
+     *            The name of the main task.
+     * @param steps
+     *            The number of steps this task is subdivided into.
+     * @return The {@link IProgressMonitor}.
+     */
+    public static IProgressMonitor startMainMonitor(
+            IProgressMonitor progressMonitor, String taskName, int steps) {
+        IProgressMonitor newMonitor = progressMonitor;
+        if (newMonitor == null) {
+            newMonitor = new NullProgressMonitor();
+        }
+        newMonitor.beginTask(taskName == null ? "" : taskName, steps);
+        newMonitor.subTask(" ");
+        return newMonitor;
+    }
+
+    /**
+     * Creates a {@link SubProgressMonitor} if the given
+     * {@link IProgressMonitor} is not <code>null</code> and not a
+     * {@link NullProgressMonitor}.
+     *
+     * @param progressMonitor
+     *            The parent {@link IProgressMonitor} of the
+     *            {@link SubProgressMonitor} to be created.
+     * @param ticks
+     *            The number of steps this subtask is subdivided into. Must be a
+     *            positive number and must not be
+     *            {@link IProgressMonitor#UNKNOWN}.
+     * @return The {@link IProgressMonitor}.
+     */
+    public static IProgressMonitor getSubProgressMonitor(
+            IProgressMonitor progressMonitor, int ticks) {
+        if (progressMonitor == null) {
+            return new NullProgressMonitor();
+        }
+        if (progressMonitor instanceof NullProgressMonitor) {
+            return progressMonitor;
+        }
+
+        return new SubProgressMonitor(progressMonitor, ticks);
+    }
+
+    /**
+     * Checks whether the user canceled this operation. If not canceled, the
+     * given number of steps are declared as done.
+     *
+     * @param newMonitor
+     *            a {@link org.eclipse.core.runtime.IProgressMonitor} object.
+     * @param steps
+     *            a int.
+     */
+    public static void workedChecked(IProgressMonitor newMonitor, int steps) {
+        // In case the progress monitor was canceled throw an exception.
+        if (newMonitor.isCanceled()) {
+            throw new OperationCanceledException();
+        }
+        // Otherwise declare this step as done.
+        newMonitor.worked(steps);
+    }
+
+    /**
+     * Present a progress dialog to the user. This dialog will block the UI
+     *
+     * @param runnable
+     *            an implementation of {@link IRunnableWithProgress}
+     * @throws java.lang.InterruptedException
+     *             if any.
+     * @throws java.lang.reflect.InvocationTargetException
+     *             if any.
+     */
+    public static void busyCursorWhile(IRunnableWithProgress runnable)
+            throws InvocationTargetException, InterruptedException {
+        getProgressService().busyCursorWhile(runnable);
+    }
+
+    public static void runInUI(IRunnableWithProgress runnable,
+            ISchedulingRule rule) throws InvocationTargetException,
+            InterruptedException {
+        getProgressService().runInUI(getWorkbenchWindow(), runnable, rule);
+    }
+
+    public static void run(boolean fork, boolean cancelable,
+            IRunnableWithProgress runnable) throws InvocationTargetException,
+            InterruptedException {
+        getProgressService().run(fork, cancelable, runnable);
+    }
+
+    public static IProgressService getProgressService() {
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        return workbench.getProgressService();
+    }
+
+    public static IWorkbenchSiteProgressService getProgressService2() {
+        return (IWorkbenchSiteProgressService) getService(IWorkbenchSiteProgressService.class);
+    }
+
+    public static String getPluginId() {
+        return "eu.taxeditor";
+    }
+
+    public static IEditorPart getActiveEditor() {
+        return getActivePage() != null ? getActivePage().getActiveEditor()
+                : null;
+    }
+
+    public static Object getActiveE4Editor() {
+        if(getActivePage()!=null){
+            IEditorPart activeEditor = getActivePage().getActiveEditor();
+            Object wrappedPart = getE4WrappedPart(getActivePage().getActivePart());
+            return wrappedPart!=null?wrappedPart:activeEditor;
+        }
+        return null;
+    }
+
+    public static DetailsViewPart getDetailsView() {
+        return (DetailsViewPart) getView(DetailsViewPart.ID, false);
+    }
+
+    public static void refreshDetailsViewer() {
+        if (getDetailsView() != null) {
+            ((AbstractCdmDataViewer) getDetailsView().getViewer()).refresh();
+        }
+    }
+
+    public static void reflowDetailsViewer() {
+        if (getDetailsView() != null) {
+            ((AbstractCdmDataViewer) getDetailsView().getViewer()).reflow();
+        }
+    }
+
+    public static SupplementalDataViewPart getSupplementalDataView() {
+        return (SupplementalDataViewPart) getView(SupplementalDataViewPart.ID,
+                false);
+    }
+
+    public static void reflowSupplementalViewer() {
+        if (getSupplementalDataView() != null) {
+            ((AbstractCdmDataViewer) getSupplementalDataView().getViewer())
+            .reflow();
+        }
+    }
 
 
     /**
@@ -1016,10 +702,6 @@ public abstract class AbstractUtility {
         private final T term;
         private final TreeSet<TermNode<T>> children;
 
-        /**
-         * @param term
-         * @param children
-         */
         public TermNode(T term) {
             super();
             this.term = term;
@@ -1030,23 +712,14 @@ public abstract class AbstractUtility {
             this.children.add(child);
         }
 
-        /**
-         * @return the children
-         */
         public TreeSet<TermNode<T>> getChildren() {
             return children;
         }
 
-        /**
-         * @return the term
-         */
         public T getTerm() {
             return term;
         }
 
-        /* (non-Javadoc)
-         * @see java.lang.Object#hashCode()
-         */
         @Override
         public int hashCode() {
             final int prime = 31;
@@ -1055,9 +728,6 @@ public abstract class AbstractUtility {
             return result;
         }
 
-        /* (non-Javadoc)
-         * @see java.lang.Object#equals(java.lang.Object)
-         */
         @Override
         public boolean equals(Object obj) {
             if (this == obj) {
@@ -1080,13 +750,54 @@ public abstract class AbstractUtility {
             return true;
         }
 
-        /* (non-Javadoc)
-         * @see java.lang.Comparable#compareTo(java.lang.Object)
-         */
         @Override
         public int compareTo(TermNode<T> that) {
             return this.term.getMessage().compareTo(that.term.getMessage());
         }
     }
 
+
+    public static void executeCommand(String commandId, Object source, String pluginId) {
+        IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
+        Exception exception = null;
+        try {
+            handlerService.executeCommand(commandId, null);
+        } catch (ExecutionException e) {
+            exception = e;
+        } catch (NotDefinedException e) {
+            exception = e;
+        } catch (NotEnabledException e) {
+            exception = e;
+        } catch (NotHandledException e) {
+            exception = e;
+        } finally {
+            if(exception != null) {
+                MessagingUtils.errorDialog("Error executing command",
+                        source,
+                        "Could not execute command with id " + commandId ,
+                        pluginId,
+                        exception,
+                        true);
+            }
+        }
+    }
+
+    /**
+     * @param event
+     * @return
+     */
+    public static Object getElementsFromSelectionChangedEvent(SelectionChangedEvent event) {
+        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+        Object selectionToSet;
+        if(selection.size() == 1){
+            selectionToSet = selection.getFirstElement();
+        }
+        else if(!selection.isEmpty()){
+            selectionToSet = selection.toArray();
+        }
+        else{
+            selectionToSet = selection;
+        }
+        return selectionToSet;
+    }
 }