/*******************************************************************************
 * Copyright (c) 2010 Symbian Foundation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * Symbian Foundation - initial contribution.
 * Contributors:
 * Description:
 * Overview:
 * Details:
 * Platforms/Drives/Compatibility:
 * Assumptions/Requirement/Pre-requisites:
 * Failures and causes:
 *******************************************************************************/
package org.symbian.tools.tmw.internal.ui.wizard;

import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdfill;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdhspan;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gdwhint;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.gl;
import static org.eclipse.wst.common.project.facet.ui.internal.util.GridLayoutUtil.glmargins;
import static org.eclipse.wst.common.project.facet.ui.internal.util.SwtUtil.getPreferredWidth;
import static org.eclipse.wst.common.project.facet.ui.internal.util.SwtUtil.runOnDisplayThread;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.events.IProjectFacetsChangedEvent;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleEvent;
import org.eclipse.wst.common.project.facet.core.runtime.events.IRuntimeLifecycleListener;
import org.eclipse.wst.common.project.facet.ui.IDecorationsProvider;
import org.eclipse.wst.common.project.facet.ui.internal.FacetUiPlugin;
import org.symbian.tools.tmw.core.TMWCore;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */
@SuppressWarnings("restriction")
public final class FacetsSelectionPanel extends Composite implements ISelectionProvider {
    private final Composite topComposite;
    private final SashForm sform1;
    private final CheckboxTableViewer tableViewer;
    private final Table table;
    private final FixedFacetToolTip fixedFacetToolTip;
    private final TableViewer problemsView;
    private boolean showToolTips;
    private final IFacetedProjectWorkingCopy fpjwc;
    private final List<IFacetedProjectListener> registeredWorkingCopyListeners;
    private final Map<IProjectFacet, IProjectFacetVersion> selectedVersions;
    private final List<ISelectionChangedListener> selectionListeners;
    private Object selection;
    private final ImageRegistry imageRegistry;
    private final IRuntimeLifecycleListener runtimeLifecycleListener;
    private final Text description;
    private final Composite facets;

    public FacetsSelectionPanel(final Composite parent, final IFacetedProjectWorkingCopy fpjwc) {
        super(parent, SWT.NONE);

        this.fpjwc = fpjwc;
        this.registeredWorkingCopyListeners = new ArrayList<IFacetedProjectListener>();
        this.selectedVersions = new HashMap<IProjectFacet, IProjectFacetVersion>();
        this.selection = null;
        this.selectionListeners = new ArrayList<ISelectionChangedListener>();
        this.showToolTips = false;

        // Initialize the image registry.

        this.imageRegistry = new ImageRegistry();
        // Layout the panel.

        setLayout(glmargins(new GridLayout(1, false), 0, 0));

        this.topComposite = new Composite(this, SWT.NONE);
        this.topComposite.setLayout(glmargins(new GridLayout(4, false), 0, 0));

        this.sform1 = new SashForm(this.topComposite, SWT.VERTICAL | SWT.SMOOTH);
        this.sform1.setLayoutData(gdhspan(gdfill(), 4));

        facets = new Composite(sform1, SWT.NONE);
        facets.setLayout(new GridLayout(2, false));
        this.table = new Table(facets, SWT.BORDER | SWT.CHECK);
        GridData gd = new GridData(GridData.FILL_VERTICAL);
        gd.widthHint = 250;
        table.setLayoutData(gd);
        description = new Text(facets, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.BORDER);
        gd = new GridData(GridData.FILL_BOTH);
        description.setLayoutData(gd);
        this.tableViewer = new CheckboxTableViewer(this.table);

        this.tableViewer.setLabelProvider(new FacetColumnLabelProvider());
        this.tableViewer.setContentProvider(new ContentProvider());
        this.tableViewer.setSorter(new Sorter());

        this.fixedFacetToolTip = new FixedFacetToolTip(this.table);

        this.tableViewer.setInput(new Object());
        this.tableViewer.setFilters(new ViewerFilter[] { new RuntimeFacetsFilter(fpjwc) });
        this.tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(final SelectionChangedEvent e) {
                FacetsSelectionPanel.this.handleSelectionChangedEvent();
            }
        });

        this.tableViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(final CheckStateChangedEvent e) {
                FacetsSelectionPanel.this.handleCheckStateChanged(e);
            }
        });

        this.table.addListener(SWT.MouseDown, new Listener() {
            public void handleEvent(final Event event) {
                handleMouseDownEvent(event);
            }
        });

        this.problemsView = new TableViewer(this.sform1, SWT.BORDER);
        this.problemsView.setContentProvider(new ProblemsContentProvider());
        this.problemsView.setLabelProvider(new ProblemsLabelProvider());
        this.problemsView.setInput(new Object());

        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(final DisposeEvent e) {
                handleDisposeEvent();
            }
        });

        Dialog.applyDialogFont(parent);

        // Setup runtime lifecycle listener.

        this.runtimeLifecycleListener = new IRuntimeLifecycleListener() {
            public void handleEvent(final IRuntimeLifecycleEvent event) {
                handleValidationProblemsChangedEvent();
            }
        };

        RuntimeManager
                .addListener(this.runtimeLifecycleListener, IRuntimeLifecycleEvent.Type.VALIDATION_STATUS_CHANGED);

        // Bind to the model.

        addWorkingCopyListener(new IFacetedProjectListener() {
            public void handleEvent(final IFacetedProjectEvent event) {
                handleProjectFacetsChangedEvent(event);
            }
        }, IFacetedProjectEvent.Type.PROJECT_FACETS_CHANGED);

        handleProjectFacetsChangedEvent(null);

        addWorkingCopyListener(new IFacetedProjectListener() {
            public void handleEvent(final IFacetedProjectEvent event) {
                handleValidationProblemsChangedEvent();
            }
        }, IFacetedProjectEvent.Type.VALIDATION_PROBLEMS_CHANGED, IFacetedProjectEvent.Type.PROJECT_MODIFIED);

        handleValidationProblemsChangedEvent();

        addWorkingCopyListener(new IFacetedProjectListener() {
            public void handleEvent(final IFacetedProjectEvent event) {
                handleModelChangedEvent(event);
            }
        }, IFacetedProjectEvent.Type.FIXED_FACETS_CHANGED, IFacetedProjectEvent.Type.SELECTED_PRESET_CHANGED,
                IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED);

        // Set the preferred dimensions of the panel.

        final int prefWidthTree = getPreferredWidth(this.table);
        final int prefWidth = prefWidthTree + 80;

        this.topComposite.setLayoutData(gdwhint(gdhhint(gdfill(), 200), prefWidth));

        this.sform1.setWeights(new int[] { 70, 30 });

        // Select the first item in the table.

        if (this.table.getItemCount() > 0) {
            final TableItem firstItem = this.table.getItem(0);
            this.tableViewer.setSelection(new StructuredSelection(firstItem.getData()));
        }

        handleSelectionChangedEvent();
    }

    public IFacetedProjectWorkingCopy getFacetedProjectWorkingCopy() {
        return this.fpjwc;
    }

    public boolean isSelectionValid() {
        return (this.fpjwc.validate().getSeverity() != IStatus.ERROR);
    }

    public boolean setFocus() {
        return this.table.setFocus();
    }

    public void addSelectionChangedListener(final ISelectionChangedListener listener) {
        this.selectionListeners.add(listener);
    }

    public void removeSelectionChangedListener(final ISelectionChangedListener listener) {
        this.selectionListeners.remove(listener);
    }

    public ISelection getSelection() {
        if (this.selection != null) {
            return new StructuredSelection(this.selection);
        } else {
            return new StructuredSelection(new Object[0]);
        }
    }

    public void setSelection(final ISelection selection) {
        throw new UnsupportedOperationException();
    }

    private void notifySelectionChangedListeners() {
        final SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

        for (ISelectionChangedListener listener : this.selectionListeners) {
            listener.selectionChanged(event);
        }
    }

    private ImageRegistry getImageRegistry() {
        return this.imageRegistry;
    }

    public Image getImage(final IProjectFacet facet, final boolean showDecorations) {
        final boolean isFixed = getFacetedProjectWorkingCopy().isFixedProjectFacet(facet);
        final String id = (isFixed && showDecorations ? "F:" : "f:") + facet.getId(); //$NON-NLS-1$ //$NON-NLS-2$

        Image image = getImageRegistry().get(id);

        if (image == null) {
            final IDecorationsProvider decprov = (IDecorationsProvider) facet.getAdapter(IDecorationsProvider.class);

            ImageDescriptor imgdesc = decprov.getIcon();

            if (isFixed && showDecorations) {
                imgdesc = new FixedFacetImageDescriptor(imgdesc);
            }

            getImageRegistry().put(id, imgdesc);
            image = getImageRegistry().get(id);
        }

        return image;
    }

    private void refresh() {
        // Somehow the checked state of nested items gets lost when a refresh
        // is performed, so we have to do this workaround.

        final Object[] checked = this.tableViewer.getCheckedElements();
        this.tableViewer.refresh();
        this.tableViewer.setCheckedElements(checked);
    }

    public boolean getShowToolTips() {
        return this.showToolTips;
    }

    public void setShowToolTips(final boolean showToolTips) {
        this.showToolTips = showToolTips;
    }

    private void addWorkingCopyListener(final IFacetedProjectListener listener,
            final IFacetedProjectEvent.Type... types) {
        this.fpjwc.addListener(listener, types);
        this.registeredWorkingCopyListeners.add(listener);
    }

    public IProjectFacet getSelectedProjectFacet() {
        final IProjectFacetVersion fv = getSelectedProjectFacetVersion();

        if (fv != null) {
            return fv.getProjectFacet();
        }

        return null;
    }

    public IProjectFacetVersion getSelectedProjectFacetVersion() {
        if (this.selection != null && this.selection instanceof IProjectFacetVersion) {
            return (IProjectFacetVersion) this.selection;
        }

        return null;
    }

    private IProjectFacetVersion getSelectedVersion(final IProjectFacet f) {
        final Set<IProjectFacetVersion> availableVersions = this.fpjwc.getAvailableVersions(f);

        if (availableVersions.isEmpty()) {
            throw new IllegalStateException();
        }

        IProjectFacetVersion selectedVersion = this.fpjwc.getProjectFacetVersion(f);

        if (selectedVersion == null) {
            selectedVersion = this.selectedVersions.get(f);

            if (selectedVersion == null) {
                selectedVersion = f.getDefaultVersion();
            }

            if (!availableVersions.contains(selectedVersion)) {
                selectedVersion = this.fpjwc.getHighestAvailableVersion(f);
            }
        }

        this.selectedVersions.put(f, selectedVersion);

        return selectedVersion;
    }

    private void handleSelectionChangedEvent() {
        Object selection = ((IStructuredSelection) this.tableViewer.getSelection()).getFirstElement();

        if (selection != null && selection instanceof IProjectFacet) {
            selection = getSelectedVersion((IProjectFacet) selection);
            description.setText(((IProjectFacetVersion) selection).getProjectFacet().getDescription());
        }

        if (selection != this.selection) {
            this.selection = selection;

            notifySelectionChangedListeners();
        }
    }

    private void handleCheckStateChanged(final CheckStateChangedEvent event) {
        final Object el = event.getElement();
        final boolean checked = event.getChecked();

        final IProjectFacet f = (IProjectFacet) el;

        if (this.fpjwc.getFixedProjectFacets().contains(f)) {
            if (!checked) {
                this.tableViewer.setChecked(el, true);

                final String msg = MessageFormat
                        .format("Project facet {0} cannot be deselected. It is critical to the proper function of this project.",
                                f.getLabel());

                this.fixedFacetToolTip.setMessage(msg);

                final Point cursorLocation = getDisplay().getCursorLocation();
                this.fixedFacetToolTip.show(this.table.toControl(cursorLocation));
            }

            return;
        }

        if (checked) {
            this.fpjwc.addProjectFacet(getSelectedVersion(f));
        } else {
            this.fpjwc.removeProjectFacet(f);
        }

        this.fpjwc.setSelectedPreset(null);
    }

    private void handleMouseDownEvent(final Event event) {
        handleMouseDownEventHelper(event, this.table.getItems());
    }

    private boolean handleMouseDownEventHelper(final Event event, final TableItem[] items) {
        for (TableItem item : items) {
            if (item.getBounds(1).contains(event.x, event.y)) {
                final TableItem[] newSelection = new TableItem[] { item };

                if (!Arrays.equals(this.table.getSelection(), newSelection)) {
                    this.table.setSelection(new TableItem[] { item });
                    this.tableViewer.editElement(item.getData(), 1);
                }

                return true;
            }
        }

        return false;
    }

    private void handleDisposeEvent() {
        this.imageRegistry.dispose();

        for (IFacetedProjectListener listener : this.registeredWorkingCopyListeners) {
            this.fpjwc.removeListener(listener);
        }

        RuntimeManager.removeListener(this.runtimeLifecycleListener);
    }

    private void handleProjectFacetsChangedEvent(final IFacetedProjectEvent event) {
        if (!Thread.currentThread().equals(getDisplay().getThread())) {
            final Runnable uiRunnable = new Runnable() {
                public void run() {
                    handleProjectFacetsChangedEvent(event);
                }
            };

            getDisplay().asyncExec(uiRunnable);

            return;
        }

        if (event != null) {
            final IFacetedProjectWorkingCopy fpjwc = event.getWorkingCopy();

            final IProjectFacetsChangedEvent evt = (IProjectFacetsChangedEvent) event;

            for (IProjectFacetVersion fv : evt.getAllAffectedFacets()) {
                final IProjectFacet f = fv.getProjectFacet();
                final boolean checked = fpjwc.hasProjectFacet(fv);

                this.tableViewer.setChecked(f, checked);
                this.tableViewer.update(f, null);
            }
        } else {
            final List<IProjectFacet> facets = new ArrayList<IProjectFacet>();

            for (IProjectFacetVersion fv : this.fpjwc.getProjectFacets()) {
                facets.add(fv.getProjectFacet());
            }

            this.tableViewer.setCheckedElements(facets.toArray());
            this.tableViewer.update(this.fpjwc.getAvailableFacets().keySet().toArray(), null);
        }
    }

    private void handleValidationProblemsChangedEvent() {
        if (!Thread.currentThread().equals(getDisplay().getThread())) {
            final Runnable uiRunnable = new Runnable() {
                public void run() {
                    handleValidationProblemsChangedEvent();
                }
            };

            getDisplay().asyncExec(uiRunnable);

            return;
        }

        this.problemsView.refresh();

        if (getFilteredProblems().length == 0) {
            if (this.sform1.getMaximizedControl() == null) {
                this.sform1.setMaximizedControl(facets);
            }
        } else {
            if (this.sform1.getMaximizedControl() != null) {
                this.sform1.setMaximizedControl(null);
            }
        }
    }

    private void handleModelChangedEvent(final IFacetedProjectEvent event) {
        switch (event.getType()) {
        case FIXED_FACETS_CHANGED:
        case TARGETED_RUNTIMES_CHANGED: {
            final Runnable runnable = new Runnable() {
                public void run() {
                    refresh();
                }
            };

            runOnDisplayThread(getDisplay(), runnable);

            break;
        }
        }
    }

    private IStatus[] getFilteredProblems() {
        final IStatus[] unfiltered = this.fpjwc.validate().getChildren();
        boolean somethingToRemove = false;

        for (IStatus st : unfiltered) {
            if (st.getCode() == IFacetedProjectWorkingCopy.PROBLEM_PROJECT_NAME) {
                somethingToRemove = true;
                break;
            }
        }

        if (!somethingToRemove) {
            return unfiltered;
        }

        final List<IStatus> filtered = new ArrayList<IStatus>();

        for (IStatus st : unfiltered) {
            if (st.getCode() != IFacetedProjectWorkingCopy.PROBLEM_PROJECT_NAME) {
                filtered.add(st);
            }
        }

        return filtered.toArray(new IStatus[filtered.size()]);
    }

    private final class ContentProvider

    implements ITreeContentProvider

    {
        public Object[] getElements(final Object element) {
            final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
            final List<Object> list = new ArrayList<Object>();
            for (Map.Entry<IProjectFacet, SortedSet<IProjectFacetVersion>> entry : fpjwc.getAvailableFacets()
                    .entrySet()) {
                final IProjectFacet f = entry.getKey();
                final SortedSet<IProjectFacetVersion> availableVersions = entry.getValue();

                if (f.getCategory() == null && !availableVersions.isEmpty()) {
                    list.add(f);
                }
            }

            return list.toArray();
        }

        public Object[] getChildren(final Object parent) {
            return new Object[0];
        }

        public Object getParent(final Object element) {
            if (element instanceof IProjectFacet) {
                final IProjectFacet f = (IProjectFacet) element;
                return f.getCategory();
            } else {
                return null;
            }
        }

        public boolean hasChildren(final Object element) {
            return false;
        }

        public void dispose() {
        }

        public void inputChanged(final Viewer viewer, final Object oldObject, final Object newObject) {
        }
    }

    private final class FacetColumnLabelProvider extends LabelProvider {
        @Override
        public String getText(final Object element) {
            return ((IProjectFacet) element).getLabel();
        }

        @Override
        public Image getImage(final Object element) {
            return FacetsSelectionPanel.this.getImage((IProjectFacet) element, true);
        }
    }

    private static final class FixedFacetImageDescriptor

    extends CompositeImageDescriptor

    {
        private static final String OVERLAY_IMG_LOCATION = "images/lock.gif"; //$NON-NLS-1$

        private static final ImageData OVERLAY = FacetUiPlugin.getImageDescriptor(OVERLAY_IMG_LOCATION).getImageData();

        private final ImageData base;
        private final Point size;

        public FixedFacetImageDescriptor(final ImageDescriptor base) {
            this.base = base.getImageData();
            this.size = new Point(this.base.width, this.base.height);
        }

        protected void drawCompositeImage(final int width, final int height) {
            drawImage(this.base, 0, 0);
            drawImage(OVERLAY, 0, height - OVERLAY.height);
        }

        protected Point getSize() {
            return this.size;
        }
    }

    private static final class Sorter extends ViewerSorter {
        public int compare(final Viewer viewer, final Object a, final Object b) {
            return getLabel(a).compareToIgnoreCase(getLabel(b));
        }

        private static String getLabel(final Object obj) {
            return ((IProjectFacet) obj).getLabel();
        }
    }

    private static final class FixedFacetToolTip extends ToolTip {
        private static final int FAKE_EVENT_TYPE = -9999;

        private String message = ""; //$NON-NLS-1$

        @Override
        protected Composite createToolTipContentArea(final Event event, final Composite parent) {
            final Display display = parent.getDisplay();

            final Composite composite = new Composite(parent, SWT.NONE);
            composite.setLayout(gl(1));
            composite.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));

            final Label label = new Label(composite, SWT.WRAP);
            label.setLayoutData(gdwhint(gdfill(), 300));
            label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
            label.setText(this.message);

            return composite;
        }

        public void setMessage(final String message) {
            this.message = message;
        }

        public FixedFacetToolTip(final Control control) {
            super(control);
            setPopupDelay(0);
            setShift(new Point(10, 3));
        }

        public void show(final Point location) {
            // The JFace ToolTip class does not support alternative methods of tool tip activation.
            // An enhancement request https://bugs.eclipse.org/bugs/show_bug.cgi?id=174844 tracks
            // this issue. When that enhancement request has been resolved, this hacky 
            // implementation should be replaced with something more sensible.

            final Event fakeEvent = new Event();
            fakeEvent.type = FAKE_EVENT_TYPE;
            fakeEvent.x = location.x;
            fakeEvent.y = location.y;

            try {
                final Method method = ToolTip.class.getDeclaredMethod("toolTipCreate", Event.class); //$NON-NLS-1$

                method.setAccessible(true);
                method.invoke(this, fakeEvent);
            } catch (Exception e) {
                TMWCore.log(null, e);
            }
        }

        @Override
        protected final boolean shouldCreateToolTip(final Event event) {
            return (event.type == FAKE_EVENT_TYPE);
        }
    }

    private final class ProblemsContentProvider implements IStructuredContentProvider {
        public Object[] getElements(final Object element) {
            return getFilteredProblems();
        }

        public void inputChanged(final Viewer viewer, final Object oldObject, final Object newObject) {
        }

        public void dispose() {
        }
    }

    private static final class ProblemsLabelProvider implements ITableLabelProvider {
        public String getColumnText(final Object element, final int column) {
            return ((IStatus) element).getMessage();
        }

        public Image getColumnImage(final Object element, final int column) {
            final ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
            final String imageType;
            if (((IStatus) element).getSeverity() == IStatus.ERROR) {
                imageType = ISharedImages.IMG_OBJS_ERROR_TSK;
            } else {
                imageType = ISharedImages.IMG_OBJS_WARN_TSK;
            }
            return sharedImages.getImage(imageType);
        }

        public boolean isLabelProperty(final Object obj, final String s) {
            return false;
        }

        public void dispose() {
        }

        public void addListener(final ILabelProviderListener listener) {
        }

        public void removeListener(ILabelProviderListener listener) {
        }
    }
}
