/*******************************************************************************
 * Copyright (c) 2008, 2021 SAP AG, IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    SAP AG - initial API and implementation
 *    IBM Corporation - accessibility related fixes 
 *    Chris Grindstaff
 *******************************************************************************/
package org.eclipse.mat.ui.snapshot.views.inspector;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
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.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.query.IContextObject;
import org.eclipse.mat.query.IContextObjectSet;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.OQL;
import org.eclipse.mat.snapshot.model.GCRootInfo;
import org.eclipse.mat.snapshot.model.IClass;
import org.eclipse.mat.snapshot.model.IInstance;
import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.snapshot.model.IObjectArray;
import org.eclipse.mat.snapshot.model.IPrimitiveArray;
import org.eclipse.mat.snapshot.model.ObjectReference;
import org.eclipse.mat.ui.MemoryAnalyserPlugin;
import org.eclipse.mat.ui.Messages;
import org.eclipse.mat.ui.accessibility.AccessibleCompositeAdapter;
import org.eclipse.mat.ui.accessibility.AccessibleToolbarAdapter;
import org.eclipse.mat.ui.snapshot.ImageHelper;
import org.eclipse.mat.ui.snapshot.editor.HeapEditor;
import org.eclipse.mat.ui.snapshot.editor.ISnapshotEditorInput;
import org.eclipse.mat.ui.util.Copy;
import org.eclipse.mat.ui.util.PopupMenu;
import org.eclipse.mat.ui.util.QueryContextMenu;
import org.eclipse.mat.util.MessageUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;

public class InspectorView extends ViewPart implements IPartListener, ISelectionChangedListener
{
    private HeapEditor editor;
    /* package */ISnapshot snapshot;

    private Composite top;
    private Composite visualViewer;
    private TableViewer topTableViewer;
    private CTabFolder tabFolder;
    private TableViewer attributesTable;
    private TableViewer staticsTable;
    private TreeViewer classHierarchyTree;
    private StyledText resolvedValue;
    private boolean pinSelection = false;
    private Font font;

    private List<Menu> contextMenus = new ArrayList<Menu>();

    boolean keepInSync = true;

    /* package */static class BaseNode
    {
        int objectId;
        long addr;

        public BaseNode(int objectId)
        {
            this(objectId, 0);
        }
        public BaseNode(int objectId, long addr)
        {
            this.objectId = objectId;
            this.addr = addr;
        }

        static int objectID(IObject object)
        {
            if (object == null)
                return -1;
            try
            {
                return object.getObjectId();
            }
            catch (RuntimeException e)
            {
                if (e.getCause() instanceof SnapshotException)
                    return -1;
                throw e;
            }
        }
    }

    private static class ObjectNode extends BaseNode
    {
        String label;
        int imageType;

        public ObjectNode(IObject object)
        {
            super(objectID(object), object.getObjectAddress());
            this.label = object.getTechnicalName();
            this.imageType = ImageHelper.getType(object);
        }

        public String getLabel()
        {
            return label;
        }

        public int getImageType()
        {
            return imageType;
        }
    }

    private static class TopTableLabelProvider extends LabelProvider
    {

        @Override
        public String getText(Object element)
        {
            if (element instanceof InfoItem)
                return ((InfoItem) element).getText();
            else if (element instanceof ObjectNode)
                return ((ObjectNode) element).getLabel();
            else if (element instanceof GCRootInfo[])
                return Messages.InspectorView_GCroot + GCRootInfo.getTypeSetAsString((GCRootInfo[]) element);
            else
                return "";//$NON-NLS-1$
        }

        @Override
        public Image getImage(Object element)
        {
            if (element instanceof InfoItem)
                return MemoryAnalyserPlugin.getDefault().getImage(((InfoItem) element).getDescriptor());
            else if (element instanceof ObjectNode)
                return ImageHelper.getImage(((ObjectNode) element).getImageType());
            else if (element instanceof GCRootInfo[])
                return MemoryAnalyserPlugin.getImage(ImageHelper.Decorations.GC_ROOT);
            else
                return null;
        }

    }

    private static final class TableContentProvider implements IStructuredContentProvider
    {
        Object[] elements;

        public Object[] getElements(Object inputElement)
        {
            return elements;
        }

        public void dispose()
        {}

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
        {
            if (newInput instanceof Collection<?>)
            {
                this.elements = ((Collection<?>) newInput).toArray();
            }
            else
            {
                this.elements = (Object[]) newInput;
            }
        }
    }

    public static class InfoItem extends BaseNode
    {
        private ImageDescriptor descriptor;
        private String text;

        public InfoItem(ImageDescriptor descriptor, String text)
        {
            this(null, descriptor, text);
        }

        public InfoItem(IObject object, ImageDescriptor descriptor, String text)
        {
            super(objectID(object), object != null ? object.getObjectAddress() : 0);
            this.descriptor = descriptor;
            this.text = text;
        }

        public ImageDescriptor getDescriptor()
        {
            return descriptor;
        }

        public String getText()
        {
            return text;
        }
    }

    private class MenuListener extends MenuAdapter
    {
        private Menu menu;
        private StructuredViewer viewer;

        public MenuListener(Menu menu, StructuredViewer viewer)
        {
            this.menu = menu;
            this.viewer = viewer;
        }

        @Override
        public void menuShown(MenuEvent e)
        {
            MenuItem[] items = menu.getItems();
            for (int ii = 0; ii < items.length; ii++)
                items[ii].dispose();

            PopupMenu popup = new PopupMenu();
            fillContextMenu(popup, viewer);
            popup.addToMenu(getViewSite().getActionBars().getStatusLineManager(), menu);
        }

    }

    private static class HierarchyTreeContentProvider implements ITreeContentProvider
    {
        LinkedList<IClass> supers;

        public Object[] getChildren(Object element)
        {
            int index = supers.indexOf(element);
            if (index >= 0 && index + 1 < supers.size())
                return new Object[] { supers.get(index + 1) };
            return ((IClass) element).getSubclasses().toArray();
        }

        public IClass getParent(Object element)
        {
            return ((IClass) element).getSuperClass();
        }

        public boolean hasChildren(Object element)
        {
            return !((IClass) element).getSubclasses().isEmpty();

        }

        public Object[] getElements(Object inputElement)
        {
            if (supers.isEmpty())
                return new Object[0];

            return new Object[] { supers.get(0) };
        }

        public void dispose()
        {}

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
        {
            supers = new LinkedList<IClass>();
            if (newInput instanceof IClass[])
            {
                IClass[] input = (IClass[]) newInput;

                supers = new LinkedList<IClass>();
                supers.add(input[0]);

                while (input[0].hasSuperClass())
                {
                    input[0] = input[0].getSuperClass();
                    supers.addFirst(input[0]);
                }
            }
        }
    }

    private class HierarchyLabelProvider extends LabelProvider implements IFontProvider
    {
        private int classId;

        public HierarchyLabelProvider(int classId)
        {
            super();
            this.classId = classId;
        }

        @Override
        public Image getImage(Object element)
        {
            return (element instanceof IClass) ? ImageHelper.getImage(ImageHelper.Type.CLASS) : null;
        }

        @Override
        public String getText(Object element)
        {
            return (element instanceof IClass) ? ((IClass) element).getName() : "";//$NON-NLS-1$
        }

        public Font getFont(Object element)
        {
            if (element instanceof IClass && ((IClass) element).getObjectId() == classId)
                return font;
            return null;
        }

    }

    // //////////////////////////////////////////////////////////////
    // view construction
    // //////////////////////////////////////////////////////////////

    @Override
    public void createPartControl(final Composite parent)
    {
        SashForm form = new SashForm(parent, SWT.VERTICAL);
        GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).spacing(1, 1).applyTo(form);

        top = new Composite(form, SWT.TOP);
        GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).spacing(1, 1).applyTo(top);

        IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager();
        mgr.add(createSyncAction());

        FontDescriptor fontDescriptor = FontDescriptor.createFrom(JFaceResources.getDefaultFont());
        fontDescriptor = fontDescriptor.setStyle(SWT.BOLD);
        this.font = fontDescriptor.createFont(top.getDisplay());

        createTopTable(top);
        createTabFolder(top);
        createVisualViewer(form);
        form.setWeights(new int[] { 95, 5 });

        // add page listener
        getSite().getPage().addPartListener(this);

        hookContextMenu();
        showBootstrapPart();
    }

    private void createVisualViewer(Composite parent)
    {
        visualViewer = new Composite(parent, SWT.TOP);
        visualViewer.addPaintListener(new PaintListener()
        {
            public void paintControl(PaintEvent paintEvent)
            {
                Object toShow = visualViewer.getData("toShow");//$NON-NLS-1$
                if (toShow == null)
                    return;

                if (toShow instanceof Image)
                {
                    paintEvent.gc.drawImage((Image) toShow, 0, 0);
                }
                else if (toShow instanceof RGB)
                {
                    Color color = new Color(paintEvent.display, (RGB) toShow);
                    paintEvent.gc.setBackground(color);
                    paintEvent.gc.fillRectangle(0, 0, visualViewer.getSize().x, visualViewer.getSize().y);
                    color.dispose();
                }
            }
        });
        visualViewer.setVisible(false);
    }

    private Action createSyncAction()
    {
        Action syncAction = new Action(null, IAction.AS_CHECK_BOX)
        {

            @Override
            public void run()
            {
                if (!keepInSync)
                {
                    showBootstrapPart();
                    if (editor != null)
                        updateOnSelection(editor.getSelection());
                    keepInSync = true;
                }
                else
                {
                    keepInSync = false;
                }
                this.setChecked(!keepInSync);
            }

        };
        syncAction.setImageDescriptor(MemoryAnalyserPlugin
                        .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SYNCED));
        syncAction.setToolTipText(Messages.InspectorView_LinkWithSnapshot);

        return syncAction;

    }

    private void createTopTable(Composite parent)
    {
        Composite composite = new Composite(parent, SWT.NONE);
        topTableViewer = new TableViewer(composite, SWT.FULL_SELECTION | SWT.MULTI);

        Table table = topTableViewer.getTable();
        AccessibleCompositeAdapter.access(table);
        TableColumnLayout columnLayout = new TableColumnLayout();
        composite.setLayout(columnLayout);

        TableColumn column = new TableColumn(table, SWT.LEFT);
        columnLayout.setColumnData(column, new ColumnWeightData(100, 10));

        // on win32, item height is reported too low the first time around
        int itemHeight = table.getItemHeight() + 1;
        if (itemHeight < 17)
            itemHeight = 17;

        int scrollbarHeight = 2;
        if (!Platform.OS_WIN32.equals(Platform.getOS()))//$NON-NLS-1$
            scrollbarHeight = table.getHorizontalBar().getSize().y;

        int detailsHeight = 9 * itemHeight + scrollbarHeight;

        table.setHeaderVisible(false);
        table.setLinesVisible(false);
        topTableViewer.setLabelProvider(new TopTableLabelProvider());
        topTableViewer.setContentProvider(new TableContentProvider());

        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, detailsHeight)//
                        .grab(true, false).applyTo(composite);

    }

    private void createTabFolder(Composite parent)
    {
        tabFolder = new CTabFolder(parent, SWT.TOP | SWT.FLAT);
        GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tabFolder);

        ToolBar toolBar = new ToolBar(tabFolder, SWT.HORIZONTAL | SWT.FLAT);
        // Add custom AccessibleAdapter, passing in associated ToolBar.
        toolBar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolBar) );
        tabFolder.setTopRight(toolBar);
        // set the height of the tab to display the tool bar correctly
        tabFolder.setTabHeight(Math.max(toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, tabFolder.getTabHeight()));
        final ToolItem pinItem = new ToolItem(toolBar, SWT.CHECK);
        pinItem.setImage(MemoryAnalyserPlugin.getImage(MemoryAnalyserPlugin.ISharedImages.PINNED));
        pinItem.setToolTipText(Messages.InspectorView_PinTab);
        pinItem.addSelectionListener(new SelectionAdapter()
        {
            @Override
            public void widgetSelected(SelectionEvent e)
            {
                pinSelection = !pinSelection;
                pinItem.setSelection(pinSelection);
            }
        });

        toolBar.pack();

        final CTabItem staticsTab = new CTabItem(tabFolder, SWT.NULL);
        staticsTab.setText(Messages.InspectorView_Statics);
        staticsTable = createTable(tabFolder);
        staticsTab.setControl(staticsTable.getTable().getParent());

        CTabItem instancesTab = new CTabItem(tabFolder, SWT.NULL);
        instancesTab.setText(Messages.InspectorView_Attributes);
        attributesTable = createTable(tabFolder);
        instancesTab.setControl(attributesTable.getTable().getParent());

        CTabItem classHierarchyTab = new CTabItem(tabFolder, SWT.NULL);
        classHierarchyTab.setText(Messages.InspectorView_ClassHierarchy);
        classHierarchyTree = createHierarchyTree(tabFolder);
        classHierarchyTab.setControl(classHierarchyTree.getTree().getParent());

        CTabItem valueTab = new CTabItem(tabFolder, SWT.NULL);
        valueTab.setText(Messages.InspectorView_Value);
        resolvedValue = createValue(tabFolder);
        valueTab.setControl(resolvedValue);

        getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.COPY.getId(), new Action()
        {
            @Override
            public void run()
            {
                if (topTableViewer.getControl().isFocusControl())
                {
                    Copy.copyToClipboard(topTableViewer.getControl());
                }
                else
                {
                    int s = tabFolder.getSelectionIndex();
                    switch (s)
                    {
                        case 0:
                            Copy.copyToClipboard(staticsTable.getControl());
                            break;
                        case 1:
                            Copy.copyToClipboard(attributesTable.getControl());
                            break;
                        case 2:
                            Copy.copyToClipboard(classHierarchyTree.getControl());
                            break;
                        case 3:
                            String buffer = resolvedValue.getSelectionText();
                            Copy.copyToClipboard(buffer, resolvedValue.getDisplay());
                            break;
                        default:
                            break;
                    }
                }
            }
        });

        tabFolder.setSelection(0);
    }

    private StyledText createValue(CTabFolder parent)
    {
        StyledText ret = new StyledText(parent, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
        return ret;
    }

    private TreeViewer createHierarchyTree(CTabFolder parent)
    {
        Composite composite = new Composite(parent, SWT.NONE);
        TreeViewer classHierarchyTree = new TreeViewer(composite, SWT.FULL_SELECTION | SWT.MULTI);
        classHierarchyTree.setContentProvider(new HierarchyTreeContentProvider());
        classHierarchyTree.setLabelProvider(new HierarchyLabelProvider(-1));

        Tree tree = classHierarchyTree.getTree();
        AccessibleCompositeAdapter.access(tree);
        TreeColumnLayout columnLayout = new TreeColumnLayout();
        composite.setLayout(columnLayout);

        TreeColumn column = new TreeColumn(tree, SWT.LEFT);
        columnLayout.setColumnData(column, new ColumnWeightData(100, 10));

        return classHierarchyTree;
    }

    private TableViewer createTable(Composite parent)
    {
        Composite composite = new Composite(parent, SWT.NONE);
        TableColumnLayout columnLayout = new TableColumnLayout();
        composite.setLayout(columnLayout);
        GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(composite);

        final TableViewer viewer = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI);
        Table table = viewer.getTable();
        AccessibleCompositeAdapter.access(table);
        viewer.setContentProvider(new FieldsContentProvider());
        viewer.setLabelProvider(new FieldsLabelProvider(this, table.getFont()));

        TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
        tableColumn.setText(Messages.InspectorView_Type);
        tableColumn.setWidth(50);
        columnLayout.setColumnData(tableColumn, new ColumnWeightData(10, 50, false));

        tableColumn = new TableColumn(table, SWT.LEFT);
        tableColumn.setWidth(80);
        tableColumn.setText(Messages.InspectorView_Name);
        columnLayout.setColumnData(tableColumn, new ColumnWeightData(30, 80));

        tableColumn = new TableColumn(table, SWT.LEFT);
        tableColumn.setWidth(250);
        tableColumn.setText(Messages.InspectorView_Value);
        columnLayout.setColumnData(tableColumn, new ColumnWeightData(60, 250, true));

        table.setHeaderVisible(true);

        return viewer;
    }

    private void hookContextMenu()
    {
        createMenu(staticsTable);
        createMenu(attributesTable);
        createMenu(topTableViewer);
        createMenu(classHierarchyTree);
    }

    private void createMenu(StructuredViewer viewer)
    {
        Menu menu = new Menu(viewer.getControl());
        menu.addMenuListener(new MenuListener(menu, viewer));
        viewer.getControl().setMenu(menu);
        contextMenus.add(menu);
    }

    private void fillContextMenu(PopupMenu manager, StructuredViewer viewer)
    {
        IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();

        if (editor != null)
        {
            InspectorContextProvider contextProvider = new InspectorContextProvider(snapshot);
            final IContextObject firstElement = contextProvider.getContext(selection.getFirstElement());

            IStructuredSelection editorSelection = (IStructuredSelection) editor.getSelection();
            final Object editorElement = editorSelection.getFirstElement();

            boolean isObject = firstElement != null
                            && editorElement instanceof IContextObject
                            && firstElement.getObjectId() != ((IContextObject) editorElement)
                                            .getObjectId();

            if (isObject)
            {
                manager.add(new Action(Messages.InspectorView_GoInto)
                {
                    @Override
                    public void run()
                    {
                        updateOnSelection(new StructuredSelection(firstElement));
                    }
                });
                manager.addSeparator();
            }

            QueryContextMenu contextMenu = new QueryContextMenu(editor, contextProvider);
            contextMenu.addContextActions(manager, selection, viewer.getControl());
        }
    }

    private void showBootstrapPart()
    {
        IWorkbenchPage page = getSite().getPage();
        if (page != null)
            partActivated(page.getActiveEditor());
    }

    protected boolean isImportant(IWorkbenchPart part)
    {
        return part instanceof HeapEditor;
    }

    @Override
    public void dispose()
    {
        if (this.editor != null)
        {
            this.editor.removeSelectionChangedListener(this);
            this.editor = null;
        }

        for (Menu menu : contextMenus)
        {
            if (menu != null && !menu.isDisposed())
            {
                menu.dispose();
                menu = null;
            }
        }

        if (font != null)
            font.dispose();

        getSite().getPage().removePartListener(this);
        super.dispose();
    }

    // //////////////////////////////////////////////////////////////
    // view life-cycle
    // //////////////////////////////////////////////////////////////

    @Override
    public void setFocus()
    {
        tabFolder.getSelection().getControl().setFocus();
    }

    public void partActivated(IWorkbenchPart part)
    {
        if (!isImportant(part)) { return; }

        if (!keepInSync)
            return;

        HeapEditor heapEditor = (HeapEditor) part;

        if (this.editor != heapEditor)
        {
            if (this.editor != null)
            {
                this.editor.removeSelectionChangedListener(this);
            }

            this.editor = heapEditor;

            final ISnapshotEditorInput input = heapEditor.getSnapshotInput();
            if (input.hasSnapshot())
            {
                this.snapshot = input.getSnapshot();
            }
            else
            {
                this.snapshot = null;

                // snapshot is not yet available -> register to be informed once
                // the snapshot has been fully loaded
                input.addChangeListener(new ISnapshotEditorInput.IChangeListener()
                {

                    public void onBaselineLoaded(ISnapshot snapshot)
                    {}

                    public void onSnapshotLoaded(ISnapshot snapshot)
                    {
                        if (InspectorView.this.snapshot == null)
                            InspectorView.this.snapshot = snapshot;

                        input.removeChangeListener(this);
                    }

                });
            }

            this.editor.addSelectionChangedListener(this);

            updateOnSelection(this.editor.getSelection());
        }
    }

    public void partBroughtToTop(IWorkbenchPart part)
    {
        partActivated(part);
    }

    public void partClosed(IWorkbenchPart part)
    {
        if (!isImportant(part)) { return; }

        HeapEditor heapEditor = (HeapEditor) part;

        if (this.editor == heapEditor)
        {
            this.editor.removeSelectionChangedListener(this);

            clearInput();

            this.snapshot = null;
            this.editor = null;

            if (!keepInSync)
            {
                keepInSync = true;
                showBootstrapPart();
            }
        }
    }

    public void partDeactivated(IWorkbenchPart part)
    {}

    public void partOpened(IWorkbenchPart part)
    {}

    public void selectionChanged(SelectionChangedEvent event)
    {
        if (keepInSync)
        {
            ISelection selection = event.getSelection();
            updateOnSelection(selection);
        }
    }

    private void updateOnSelection(ISelection selection)
    {
        IContextObject objectSet = null;

        if (selection instanceof IStructuredSelection)
        {
            Object object = ((IStructuredSelection) selection).getFirstElement();
            if (object instanceof IContextObject)
                objectSet = (IContextObject) object;
        }

        long addr = 0;
        if (objectSet instanceof IContextObjectSet)
        {
            String oql = ((IContextObjectSet)objectSet).getOQL();
            if (oql != null && ((IContextObjectSet)objectSet).getObjectIds().length == 0)
            {
                String addr0 = OQL.forAddress(0);
                addr0 = addr0.substring(0, addr0.length() - 1);
                if (oql.startsWith(addr0.substring(0, addr0.length())) && oql.substring(addr0.length() - 2).matches("0[xX][0-9a-fA-F]+")) //$NON-NLS-1$
                {
                    addr = Long.parseUnsignedLong(oql.substring(addr0.length()), 16);
                }
            }
        }
        if (objectSet == null || (objectSet.getObjectId() < 0 && addr == 0))
        {
            clearInput();
        }
        else
        {
            final int objectId = objectSet.getObjectId();

            // do not update if the selection has not changed (double click)
            Object data = topTableViewer.getData("input"); //$NON-NLS-1$
            if (data != null)
            {
                int current = ((Integer) data).intValue();
                if (current == objectId)
                {
                    Object addr0 = topTableViewer.getData("address"); //$NON-NLS-1$
                    if (addr0 != null)
                    {
                        long currentAddr = ((Long) addr0).longValue();
                        if (currentAddr == addr)
                            return;
                    }
                }
            }
            final long objectAddress = addr;

            final ISnapshot savedSnapshot = snapshot;

            Job job = new Job(Messages.InspectorView_UpdateObjectDetails)
            {

                @Override
                protected IStatus run(IProgressMonitor monitor)
                {
                    try
                    {
                        if (snapshot == null || savedSnapshot != snapshot)
                            return Status.OK_STATUS;

                        final IObject object;
                        if (objectId >= 0)
                            object = savedSnapshot.getObject(objectId);
                        else
                            object = (new ObjectReference(savedSnapshot, objectAddress)).getObject();

                        // prepare object info
                        final List<Object> classInfos = prepareClassInfo(object);

                        // prepare static fields info
                        final LazyFields<?> staticFields = prepareStaticFields(object);

                        // prepare attributes
                        final LazyFields<?> attributeFields = prepareAttributes(object);

                        // update visual viewer
                        final Object toShow = prepareVisualInfo(object);

                        topTableViewer.getControl().getDisplay().asyncExec(new Runnable()
                        {
                            public void run()
                            {
                                topTableViewer.setInput(classInfos);
                                topTableViewer.setData("input", objectId);//$NON-NLS-1$
                                topTableViewer.setData("address", object.getObjectAddress());//$NON-NLS-1$
                                staticsTable.setInput(staticFields);
                                attributesTable.setInput(attributeFields);
                                updateVisualViewer(toShow);

                                IClass input = object instanceof IClass ? (IClass) object : object.getClazz();

                                try
                                {
                                    classHierarchyTree.getTree().setRedraw(false);
                                    classHierarchyTree.setInput(null);
                                    classHierarchyTree
                                                    .setLabelProvider(new HierarchyLabelProvider(input.getObjectId()));
                                    classHierarchyTree.setInput(new IClass[] { input });
                                    classHierarchyTree.expandAll();
                                }
                                finally
                                {
                                    classHierarchyTree.getTree().setRedraw(true);
                                }

                                String txt = object.getClassSpecificName();
                                resolvedValue.setText(txt != null ? txt : "");//$NON-NLS-1$

                                if (!pinSelection)// no tab pinned
                                {
                                    int selectionIndex = tabFolder.getSelectionIndex();
                                    if (selectionIndex <= 1)
                                    {
                                        int newSelectionIndex = (object instanceof IClass) ? 0 : 1;
                                        if (selectionIndex != newSelectionIndex)
                                            tabFolder.setSelection(newSelectionIndex);
                                    }
                                }

                            }

                            private void updateVisualViewer(Object toShow)
                            {
                                Object previous = visualViewer.getData("toShow");//$NON-NLS-1$
                                if (previous instanceof Image)
                                    ((Image) previous).dispose();

                                if (toShow != null)
                                {
                                    if (toShow instanceof ImageData)
                                    {
                                        Image image = new Image(visualViewer.getDisplay(), (ImageData) toShow);
                                        visualViewer.setData("toShow", image);//$NON-NLS-1$
                                    }
                                    else if (toShow instanceof RGB)
                                    {
                                        visualViewer.setData("toShow", toShow);//$NON-NLS-1$
                                    }
                                    visualViewer.redraw();
                                }
                                visualViewer.setVisible(toShow != null);
                                visualViewer.getParent().layout();
                            }
                        });

                        return Status.OK_STATUS;
                    }
                    catch (SnapshotException e)
                    {
                        return new Status(IStatus.ERROR, MemoryAnalyserPlugin.PLUGIN_ID,
                                        Messages.InspectorView_ErrorUpdatingInspector, e);
                    }
                }

                private Object prepareVisualInfo(IObject object) throws SnapshotException
                {
                    String kind = object.getClazz().getName();

                    if ("org.eclipse.swt.graphics.RGB".equals(kind))//$NON-NLS-1$
                    {
                        Integer red = (Integer) object.resolveValue("red");//$NON-NLS-1$
                        Integer green = (Integer) object.resolveValue("green");//$NON-NLS-1$
                        Integer blue = (Integer) object.resolveValue("blue");//$NON-NLS-1$

                        if (red == null || green == null || blue == null)
                            return null;

                        return new RGB(red, green, blue);
                    }
                    else if ("org.eclipse.swt.graphics.ImageData".equals(kind))//$NON-NLS-1$
                    {
                        IPrimitiveArray data = (IPrimitiveArray) object.resolveValue("data");//$NON-NLS-1$
                        Integer width = (Integer) object.resolveValue("width");//$NON-NLS-1$
                        Integer height = (Integer) object.resolveValue("height");//$NON-NLS-1$
                        Integer depth = (Integer) object.resolveValue("depth");//$NON-NLS-1$
                        Integer scanlinePad = (Integer) object.resolveValue("scanlinePad");//$NON-NLS-1$
                        Integer transparentPixel = (Integer) object.resolveValue("transparentPixel");//$NON-NLS-1$

                        if (data == null || width == null || height == null || depth == null || scanlinePad == null
                                        || transparentPixel == null)
                            return null;

                        PaletteData paletteData = makePaletteData((IInstance) object.resolveValue("palette"));//$NON-NLS-1$
                        if (paletteData == null)
                            return null;

                        byte[] dataArray = (byte[]) data.getValueArray();
                        byte[] dataCopy = new byte[dataArray.length];
                        System.arraycopy(dataArray, 0, dataCopy, 0, dataArray.length);

                        ImageData imageData = new ImageData(width, height, depth, paletteData, scanlinePad, dataCopy);
                        imageData.transparentPixel = transparentPixel;

                        IPrimitiveArray alphaBytes = (IPrimitiveArray) object.resolveValue("alphaData");//$NON-NLS-1$
                        if (alphaBytes != null)
                        {
                            byte[] alphaDataArray = (byte[]) alphaBytes.getValueArray();
                            byte[] alphaDataCopy = new byte[alphaDataArray.length];
                            System.arraycopy(alphaDataArray, 0, alphaDataCopy, 0, alphaDataArray.length);
                            imageData.alphaData = alphaDataCopy;
                        }

                        return imageData;
                    }

                    return null;
                }

                private LazyFields<?> prepareAttributes(final IObject object)
                {
                    LazyFields<?> fields = null;
                    if (object instanceof IInstance)
                        fields = new LazyFields.Instance((IInstance) object);
                    else if (object instanceof IPrimitiveArray)
                        fields = new LazyFields.PrimitiveArray((IPrimitiveArray) object);
                    else if (object instanceof IObjectArray)
                        fields = new LazyFields.ObjectArray((IObjectArray) object);
                    else if (object instanceof IClass)
                        fields = new LazyFields.Class((IClass) object, true, false);
                    else
                        fields = LazyFields.EMPTY;

                    return fields;
                }

                private LazyFields<?> prepareStaticFields(final IObject object)
                {
                    LazyFields<?> fields = null;
                    if (object instanceof IClass)
                        fields = new LazyFields.Class((IClass) object, false, false);
                    else if (object instanceof IInstance)
                        fields = new LazyFields.Class(object.getClazz(), false, true);
                    else
                        fields = LazyFields.EMPTY;

                    return fields;
                }

                private List<Object> prepareClassInfo(final IObject object) throws SnapshotException
                {
                    List<Object> details = new ArrayList<Object>();

                    details.add(new InfoItem(object, MemoryAnalyserPlugin
                                    .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.ID), "0x"//$NON-NLS-1$
                                    + Long.toHexString(object.getObjectAddress())));

                    String className = object instanceof IClass ? ((IClass) object).getName() : object.getClazz()
                                    .getName();

                    int p = className.lastIndexOf('.');
                    if (p < 0) // primitive
                    {
                        InfoItem item = new InfoItem(object, ImageHelper.getImageDescriptor(ImageHelper
                                        .getType(object)), className);
                        details.add(item);
                        details.add(new InfoItem(MemoryAnalyserPlugin
                                        .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.PACKAGE), ""));//$NON-NLS-1$
                    }
                    else
                    {
                        details.add(new InfoItem(object, ImageHelper.getImageDescriptor(ImageHelper
                                        .getType(object)), className.substring(p + 1)));
                        details.add(new InfoItem(MemoryAnalyserPlugin
                                        .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.PACKAGE), className
                                        .substring(0, p)));
                    }

                    details.add(new ObjectNode(object.getClazz()));

                    IClass superClass = object instanceof IClass ? ((IClass) object).getSuperClass() : object
                                    .getClazz().getSuperClass();

                    if (superClass != null)
                    {
                        details.add(new InfoItem(superClass, MemoryAnalyserPlugin
                                        .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SUPERCLASS), superClass
                                        .getName()));
                    }

                    ISnapshot snapshot = object.getSnapshot();
                    if (object instanceof IClass)
                        details.add(new ObjectNode(snapshot.getObject(((IClass) object).getClassLoaderId())));
                    else
                        details.add(new ObjectNode(snapshot.getObject(object.getClazz().getClassLoaderId())));

                    details.add(new InfoItem(MemoryAnalyserPlugin
                                    .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SIZE), MessageUtil.format(
                                    Messages.InspectorView_shallowSize, object.getUsedHeapSize())));
                    details.add(new InfoItem(MemoryAnalyserPlugin
                                    .getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SIZE), MessageUtil.format(
                                    Messages.InspectorView_retainedSize, object.getRetainedHeapSize())));

                    GCRootInfo[] gc;
                    try
                    {
                        gc = object.getGCRootInfo();
                    }
                    catch (SnapshotException e)
                    {
                        gc = null;
                    }
                    details.add(gc != null ? (Object) gc : new InfoItem(MemoryAnalyserPlugin
                                    .getImageDescriptor(ImageHelper.Decorations.GC_ROOT),
                                    Messages.InspectorView_noGCRoot));
                    return details;
                }

                private PaletteData makePaletteData(IInstance palette) throws SnapshotException
                {
                    Boolean isDirect = (Boolean) palette.resolveValue("isDirect");//$NON-NLS-1$
                    if (isDirect == null)
                        return null;

                    if (isDirect)
                    {
                        Integer redMask = (Integer) palette.resolveValue("redMask");//$NON-NLS-1$
                        Integer greenMask = (Integer) palette.resolveValue("greenMask");//$NON-NLS-1$
                        Integer blueMask = (Integer) palette.resolveValue("blueMask");//$NON-NLS-1$

                        if (redMask == null || greenMask == null || blueMask == null)
                            return null;

                        return new PaletteData(redMask, greenMask, blueMask);
                    }
                    else
                    {
                        IObjectArray array = (IObjectArray) palette.resolveValue("colors");//$NON-NLS-1$
                        if (array == null)
                            return null;

                        RGB[] rgbs = new RGB[array.getLength()];
                        long[] refs = array.getReferenceArray();
                        ISnapshot snapshot = palette.getSnapshot();
                        for (int ii = 0; ii < refs.length; ii++)
                        {
                            int id = snapshot.mapAddressToId(refs[ii]);
                            IObject obj = snapshot.getObject(id);
                            if (obj == null)
                                return null;

                            Integer red = (Integer) obj.resolveValue("red");//$NON-NLS-1$
                            Integer green = (Integer) obj.resolveValue("green");//$NON-NLS-1$
                            Integer blue = (Integer) obj.resolveValue("blue");//$NON-NLS-1$

                            if (red == null || green == null || blue == null)
                                return null;

                            rgbs[ii] = new RGB(red, green, blue);
                        }

                        return new PaletteData(rgbs);
                    }
                }
            };
            job.schedule();
        }
    }

    private void clearInput()
    {
        topTableViewer.getControl().getDisplay().asyncExec(new Runnable()
        {
            public void run()
            {
                // fix: add one (dummy) row to each table so that the
                // ColumnViewer does not cache the last (real) row subject
                // which in turn often has a reference to the snapshot

                if (topTableViewer.getContentProvider() != null)
                {
                    topTableViewer.setInput(new Object[] { new Object() });
                    topTableViewer.setData("input", null); //$NON-NLS-1$
                }

                if (staticsTable.getContentProvider() != null)
                {
                    staticsTable.setInput(LazyFields.EMPTY);
                }

                if (attributesTable.getContentProvider() != null)
                {
                    attributesTable.setInput(LazyFields.EMPTY);
                }

                if (classHierarchyTree.getContentProvider() != null)
                {
                    classHierarchyTree.setInput(new Object[] { new Object() });
                }

                if (!resolvedValue.isDisposed())
                {
                    resolvedValue.setText(""); //$NON-NLS-1$
                }

                for (Menu menu : contextMenus)
                {
                    if (!menu.isDisposed())
                        disposeItems(menu);
                }
            }
        });
    }

    private void disposeItems(Menu menu)
    {
        MenuItem[] items = menu.getItems();
        for (MenuItem menuItem : items)
        {
            if (!menuItem.isDisposed())
                menuItem.dispose();
        }
    }

}
