/*******************************************************************************
 * Copyright (c) 2014 TwelveTone LLC and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Steven Spungin <steven@spungin.tv> - initial API and implementation, Bug 432555, Bug 436889, Bug 437372, Bug 440469,
 * Ongoing Maintenance
 *******************************************************************************/

package org.eclipse.e4.tools.emf.ui.internal.common.component.tabs;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.tools.emf.ui.common.IModelResource;
import org.eclipse.e4.tools.emf.ui.common.ModelEditorPreferences;
import org.eclipse.e4.tools.emf.ui.common.Plugin;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.e4.tools.emf.ui.internal.common.ModelEditor;
import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.BundleImageCache;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.EAttributeEditingSupport.ATT_TYPE;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.E;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.EmptyFilterOption;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.TitleAreaFilterDialog;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.TitleAreaFilterDialogWithEmptyOptions;
import org.eclipse.e4.tools.emf.ui.internal.common.xml.EMFDocumentResourceMediator;
import org.eclipse.e4.tools.services.IResourcePool;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
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.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.osgi.service.prefs.BackingStoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * A tab that contains a list EObjects, and provides editable columns for
 * EObject features.
 *
 * @author Steven Spungin
 *
 */
public class ListTab implements IViewEObjects {

	static final String ELIPSIS = "..."; //$NON-NLS-1$

	ConcurrentHashMap<String, List<EObject>> mapId_Object = new ConcurrentHashMap<String, List<EObject>>();

	@Inject
	private IEclipseContext context;

	@Inject
	private IModelResource modelResource;

	private TableViewer tvResults;

	@Inject
	private IGotoObject gotoObjectHandler;

	@Inject
	private IResourcePool resourcePool;

	@Inject
	@Translation
	protected Messages Messages;

	@Inject
	MApplication app;

	BundleImageCache imageCache;

	private CTabItem tabItem;

	private ModelResourceContentProvider provider;

	private IDocumentListener documentListener;

	private Collection<?> highlightedItems;

	protected Image imgMarkedItem;

	LinkedHashMap<String, EAttributeTableViewerColumn> defaultColumns = new LinkedHashMap<String, EAttributeTableViewerColumn>();
	LinkedHashMap<String, EAttributeTableViewerColumn> optionalColumns = new LinkedHashMap<String, EAttributeTableViewerColumn>();
	LinkedHashMap<String, TableColumn> requiredColumns = new LinkedHashMap<String, TableColumn>();
	private TableViewerColumn colItem;
	private TableViewerColumn colGo;
	private TableViewerColumn colGoXmi;
	private TableViewerColumn colMarked;

	private ToolItem filterByItem;
	private ToolItem filterByAttribute;
	private String filterByAttrName;
	private String filterByItemName;
	private EmptyFilterOption filterByAttrEmptyOption;

	@PreDestroy
	public void preDestroy() {
		// race condition issue with observables (exception is not thrown when
		// break points are set)
		tvResults.setContentProvider(ArrayContentProvider.getInstance());
		context.get(EMFDocumentResourceMediator.class).getDocument().removeDocumentListener(documentListener);
	}

	// save custom column and filter settings
	public void saveSettings() {
		final IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(Plugin.ID);
		try {
			final Document doc = DocUtil.createDocument("list-tab"); //$NON-NLS-1$
			final Element cols = DocUtil.createChild(doc.getDocumentElement(), "columns"); //$NON-NLS-1$

			final ArrayList<TableColumn> allCols = TableViewerUtil.getColumnsInDisplayOrder(tvResults);
			for (final TableColumn col : allCols) {
				String id;
				if (requiredColumns.containsValue(col)) {
					id = getKey(requiredColumns, col);
				} else {
					id = col.getText();
				}
				saveColumn(cols, id, col);
			}

			final Element filters = DocUtil.createChild(doc.getDocumentElement(), "filters"); //$NON-NLS-1$
			if (E.notEmpty(filterByAttrName)) {
				final Element filter = DocUtil.createChild(filters, "filter"); //$NON-NLS-1$
				DocUtil.createChild(filter, "type").setTextContent("attribute"); //$NON-NLS-1$//$NON-NLS-2$
				DocUtil.createChild(filter, "condition").setTextContent(filterByAttrName); //$NON-NLS-1$
				DocUtil.createChild(filter, "emptyOption").setTextContent(filterByAttrEmptyOption.name()); //$NON-NLS-1$
			}
			if (E.notEmpty(filterByItemName)) {
				final Element filter = DocUtil.createChild(filters, "filter"); //$NON-NLS-1$
				DocUtil.createChild(filter, "type").setTextContent("item"); //$NON-NLS-1$ //$NON-NLS-2$
				DocUtil.createChild(filter, "condition").setTextContent(filterByItemName); //$NON-NLS-1$
			}

			pref.put("list-tab-xml", docToString(doc)); //$NON-NLS-1$
		} catch (final ParserConfigurationException e1) {
			e1.printStackTrace();
		} catch (final TransformerException e) {
			e.printStackTrace();
		}

		try {
			pref.flush();
		} catch (final BackingStoreException e) {
			e.printStackTrace();
		}
	}

	private String getKey(Map<String, ?> map, Object value) {
		for (final Entry<String, ?> entry : map.entrySet()) {
			if (entry.getValue().equals(value)) {
				return entry.getKey();
			}
		}
		return null;
	}

	private void saveColumn(Element eleCols, String columnName, TableColumn objCol) {
		final Element col = DocUtil.createChild(eleCols, "column"); //$NON-NLS-1$

		DocUtil.createChild(col, "attribute").setTextContent(columnName); //$NON-NLS-1$

		final Integer width = objCol.getWidth();
		DocUtil.createChild(col, "width").setTextContent(width.toString()); //$NON-NLS-1$
	}

	// load custom column and filter settings
	private void loadSettings() {
		final IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(Plugin.ID);

		final boolean restoreColumns = pref.getBoolean(ModelEditorPreferences.LIST_TAB_REMEMBER_COLUMNS, false);
		final boolean restoreFilters = pref.getBoolean(ModelEditorPreferences.LIST_TAB_REMEMBER_FILTERS, false);
		if (!restoreColumns && !restoreFilters) {
			return;
		}

		final String xml = pref.get("list-tab-xml", ""); //$NON-NLS-1$ //$NON-NLS-2$
		if (E.notEmpty(xml)) {
			try {
				final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
					.parse(new InputSource(new StringReader(xml)));
				final XPath xpath = XPathFactory.newInstance().newXPath();
				NodeList list;
				if (restoreColumns) {
					// restore columns and column widths
					list = (NodeList) xpath.evaluate("//columns/column", doc, XPathConstants.NODESET); //$NON-NLS-1$
					for (int i = 0; i < list.getLength(); i++) {
						final Element ele = (Element) list.item(i);
						TableColumn col;
						final String colName = xpath.evaluate("attribute/text()", ele); //$NON-NLS-1$
						if (colName.isEmpty()) {
							continue;
						}
						col = requiredColumns.get(colName);
						if (col == null) {
							col = addColumn(colName).getTableViewerColumn().getColumn();
						}

						// move it to the end of the list.
						final int currentIndex = TableViewerUtil.getVisibleColumnIndex(tvResults, col);
						final int[] order = tvResults.getTable().getColumnOrder();
						for (int idx = 0; idx < order.length; idx++) {
							if (order[idx] > currentIndex) {
								order[idx]--;
							} else if (order[idx] == currentIndex) {
								order[idx] = order.length - 1;
							}
						}
						tvResults.getTable().setColumnOrder(order);

						//					if ("Item".equals(colName)) { //$NON-NLS-1$
						// col = colItem;
						//					} else if ("Item".equals(colName)) { //$NON-NLS-1$
						// col = colItem;
						// }

						final String sWidth = xpath.evaluate("width/text()", ele); //$NON-NLS-1$
						try {
							col.setWidth(Integer.parseInt(sWidth));
						} catch (final Exception e) {
						}
					}
				}

				if (restoreFilters) {
					// restore filters
					list = (NodeList) xpath.evaluate("//filters/filter", doc, XPathConstants.NODESET); //$NON-NLS-1$
					for (int i = 0; i < list.getLength(); i++) {
						final Element ele = (Element) list.item(i);
						final String type = xpath.evaluate("type/text()", ele); //$NON-NLS-1$
						final String condition = xpath.evaluate("condition/text()", ele); //$NON-NLS-1$
						final String emptyOption = xpath.evaluate("emptyOption/text()", ele); //$NON-NLS-1$
						if ("item".equals(type)) { //$NON-NLS-1$
							filterByItem(condition);
						} else if ("attribute".equals(type)) { //$NON-NLS-1$
							EmptyFilterOption emptyFilterOption;
							try {
								emptyFilterOption = EmptyFilterOption.valueOf(emptyOption);
							} catch (final Exception e) {
								emptyFilterOption = EmptyFilterOption.INCLUDE;
							}
							filterByAttribute(condition, emptyFilterOption);
						}
					}
				}
			} catch (final Exception e) {
			}
		}
	}

	// @Refactor
	static private String docToString(Document doc) throws TransformerException {
		final TransformerFactory tf = TransformerFactory.newInstance();
		final Transformer transformer = tf.newTransformer();
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
		final StringWriter writer = new StringWriter();
		transformer.transform(new DOMSource(doc), new StreamResult(writer));
		final String output = writer.getBuffer().toString().replaceAll("\n|\r", ""); //$NON-NLS-1$ //$NON-NLS-2$
		return output;
	}

	// @Refactor
	static String join(Collection<String> items, String separator) {
		final StringBuilder sb = new StringBuilder();
		for (final String item : items) {
			sb.append(item);
			sb.append(separator);
		}
		if (sb.length() > 0) {
			sb.setLength(sb.length() - separator.length());
		}
		return sb.toString();
	}

	@PostConstruct
	public void postConstruct(final CTabFolder tabFolder) {
		imageCache = new BundleImageCache(context.get(Display.class), getClass().getClassLoader());
		tabFolder.addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent e) {
				imageCache.dispose();
			}
		});
		try {
			imgMarkedItem = imageCache.create(Plugin.ID, "/icons/full/obj16/mark_occurrences.png"); //$NON-NLS-1$
		} catch (final Exception e2) {
			e2.printStackTrace();
		}

		documentListener = new IDocumentListener() {

			@Override
			public void documentChanged(DocumentEvent event) {
				reload();
			}

			@Override
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
		};
		context.get(EMFDocumentResourceMediator.class).getDocument().addDocumentListener(documentListener);

		tabItem = new CTabItem(tabFolder, SWT.NONE, 1);

		final Composite composite = new Composite(tabFolder, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		composite.setLayout(new GridLayout(2, false));
		tabItem.setControl(composite);
		tabItem.setText(Messages.ListTab_0);

		tabItem.setImage(resourcePool.getImageUnchecked(ResourceProvider.IMG_Widgets_table_obj));

		final ToolBar toolBar = new ToolBar(composite, SWT.FLAT | SWT.NO_FOCUS);
		toolBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));

		{
			final ToolItem button = new ToolItem(toolBar, SWT.PUSH);
			button.setText(Messages.ListTab_addColumn + ELIPSIS);
			button.setImage(imageCache.create("/icons/full/obj16/add_column.gif")); //$NON-NLS-1$

			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialogWithEmptyOptions dlg = createEObjectAttributePicker(Messages.ListTab_addColumn);
					dlg.setShowEmptyOptions(false);
					if (dlg.open() == Window.OK) {
						// Add Column
						final String attName = dlg.getFirstElement().toString();
						final EAttributeTableViewerColumn col = addColumn(attName);
						col.getTableViewerColumn().getColumn().pack();
						tvResults.refresh();
					}
				}
			});
		}

		{
			final ToolItem button = new ToolItem(toolBar, SWT.PUSH);
			button.setText(Messages.ListTab_resetColumns);
			button.setImage(imageCache.create("/icons/full/obj16/reset_columns.gif")); //$NON-NLS-1$

			button.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					for (final EAttributeTableViewerColumn col : optionalColumns.values()) {
						col.dispose();
					}
					optionalColumns.clear();
				}
			});
		}

		new ToolItem(toolBar, SWT.SEPARATOR);

		filterByItem = new ToolItem(toolBar, SWT.NONE);
		{

			filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);
			filterByItem.setImage(imageCache.create("/icons/full/obj16/filter_by_item.gif")); //$NON-NLS-1$

			filterByItem.addSelectionListener(new SelectionAdapter() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialog dlg = createElementTypePicker(Messages.ListTab_filterByItem);
					if (dlg.open() == Window.OK) {
						filterByItem(dlg.getFirstElement().toString());
					}
				}
			});
		}

		filterByAttribute = new ToolItem(toolBar, SWT.NONE);
		{

			filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS);
			filterByAttribute.setImage(imageCache.create("/icons/full/obj16/filter_by_attribute.gif")); //$NON-NLS-1$

			filterByAttribute.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					final TitleAreaFilterDialogWithEmptyOptions dlg = createEObjectAttributePicker(Messages.ListTab_filterByAttribute);
					if (dlg.open() == Window.OK) {
						filterByAttribute(dlg.getFirstElement().toString(), dlg.getEmptyFilterOption());
					}
				}
			});
		}

		{
			final ToolItem filterRemove = new ToolItem(toolBar, SWT.NONE);
			filterRemove.setText(Messages.ListTab_removeFilter);
			filterRemove.setImage(imageCache.create("/icons/full/obj16/remove_filter.png")); //$NON-NLS-1$

			filterRemove.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					filterByItemName = null;
					filterByAttrName = null;
					tvResults.setFilters(new ViewerFilter[0]);
					filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);
					filterByAttribute.setText(Messages.ListTab_markAttribute + ELIPSIS);
				}
			});
		}

		new ToolItem(toolBar, SWT.SEPARATOR);

		{
			final E4ToolItemMenu tiCommands = new E4ToolItemMenu(toolBar, context);
			tiCommands.getToolItem().setImage(imageCache.create("/icons/full/obj16/command.gif")); //$NON-NLS-1$

			final ArrayList<String> commandIds = new ArrayList<String>();
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_attributes"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_ids"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.mark_duplicate_labels"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.repair_duplicate_ids"); //$NON-NLS-1$
			commandIds.add(E4ToolItemMenu.SEPARATOR);
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.unmark"); //$NON-NLS-1$
			commandIds.add(E4ToolItemMenu.SEPARATOR);
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.autosizeColumns"); //$NON-NLS-1$
			commandIds.add("org.eclipse.e4.tools.emf.ui.command.resetToDefault"); //$NON-NLS-1$
			tiCommands.addCommands(commandIds);
		}

		tvResults = new TableViewer(composite, SWT.FULL_SELECTION);
		tvResults.getTable().setHeaderVisible(true);
		tvResults.getTable().setLinesVisible(true);

		provider = new ModelResourceContentProvider();
		tvResults.setContentProvider(provider);

		tvResults.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		((GridData) tvResults.getTable().getLayoutData()).horizontalSpan = 2;

		final Image imgForm = resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_application_form);
		final Image imgXmi = resourcePool.getImageUnchecked(ResourceProvider.IMG_Obj16_chart_organisation);

		colGo = new TableViewerColumn(tvResults, SWT.NONE);
		colGo.getColumn().setText(Messages.ListTab_col_go);
		requiredColumns.put("GoTree", colGo.getColumn()); //$NON-NLS-1$
		colGo.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public Image getImage(Object element) {
				return imgForm;
			}

			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}
		});

		colGoXmi = new TableViewerColumn(tvResults, SWT.NONE);
		colGoXmi.getColumn().setText(Messages.ListTab_col_go);
		requiredColumns.put("GoXmi", colGoXmi.getColumn()); //$NON-NLS-1$
		colGoXmi.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}

			@Override
			public Image getImage(Object element) {
				return imgXmi;
			}
		});

		tvResults.getTable().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				if (TableViewerUtil.isColumnClicked(tvResults, e, colGo)) {
					gotoObjectHandler.gotoEObject(ModelEditor.TAB_FORM, (EObject) TableViewerUtil.getData(tvResults, e));
				} else if (TableViewerUtil.isColumnClicked(tvResults, e, colGoXmi)) {
					gotoObjectHandler.gotoEObject(ModelEditor.TAB_XMI, (EObject) TableViewerUtil.getData(tvResults, e));
				}
			}
		});

		colMarked = new TableViewerColumn(tvResults, SWT.NONE);
		colMarked.getColumn().setWidth(16);
		colMarked.getColumn().setText(Messages.ListTab_mark);
		requiredColumns.put("Marked", colMarked.getColumn()); //$NON-NLS-1$
		colMarked.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public Image getImage(Object element) {
				Image ret = null;
				if (isHighlighted(element)) {
					try {
						ret = imgMarkedItem;
					} catch (final Exception e) {
					}
				}
				return ret;
			}

			@Override
			public String getText(Object element) {
				return ""; //$NON-NLS-1$
			}
		});

		colItem = new TableViewerColumn(tvResults, SWT.NONE);
		colItem.getColumn().setText(Messages.ListTab_col_item);
		requiredColumns.put("Item", colItem.getColumn()); //$NON-NLS-1$
		colItem.setLabelProvider(new ColumnLabelProvider_Markable() {
			@Override
			public String getText(Object element) {
				final EObject eObject = (EObject) element;
				return super.getText(eObject.eClass().getName());
			}
		});

		app.getContext().set("org.eclipse.e4.tools.active-object-viewer", this); //$NON-NLS-1$

		final EAttributeTableViewerColumn colId = new EAttributeTableViewerColumn(tvResults,
			"elementId", "elementId", context); //$NON-NLS-1$//$NON-NLS-2$
		defaultColumns.put("elementId", colId); //$NON-NLS-1$

		final EAttributeTableViewerColumn colLabel = new EAttributeTableViewerColumn_Markable(tvResults,
			"label", "label", context); //$NON-NLS-1$//$NON-NLS-2$
		defaultColumns.put("label", colLabel); //$NON-NLS-1$

		// Custom selection for marked items
		tvResults.getTable().addListener(SWT.EraseItem, new Listener() {
			@Override
			public void handleEvent(Event event) {
				event.detail &= ~SWT.HOT;
				if ((event.detail & SWT.SELECTED) == 0)
				{
					return; // / item not selected
				}

				final TableItem item = (TableItem) event.item;
				if (isHighlighted(item.getData())) {

					final Table table = (Table) event.widget;
					final int clientWidth = table.getClientArea().width;
					final GC gc = event.gc;
					// Color oldForeground = gc.getForeground();
					// Color oldBackground = gc.getBackground();

					// gc.setBackground(item.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
					gc.setForeground(item.getDisplay().getSystemColor(SWT.COLOR_RED));
					gc.fillRectangle(0, event.y, clientWidth, event.height);

					// gc.setForeground(oldForeground);
					// gc.setBackground(oldBackground);
					event.detail &= ~SWT.SELECTED;
				}
			}
		});

		tvResults.getTable().setFocus();

		for (final EAttributeTableViewerColumn col : defaultColumns.values()) {
			col.getTableViewerColumn().getColumn().setMoveable(true);
		}
		for (final TableColumn col : requiredColumns.values()) {
			col.setMoveable(true);
		}

		makeSortable(colId.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colId
			.getTableViewerColumn().getColumn(), "elementId")); //$NON-NLS-1$
		makeSortable(colLabel.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colLabel
			.getTableViewerColumn().getColumn(), "label")); //$NON-NLS-1$
		makeSortable(colItem.getColumn(), new TableViewerUtil.ColumnLabelSorter(colItem.getColumn()));
		makeSortable(colMarked.getColumn(), new TableViewerUtil.AbstractInvertableTableSorter() {

			@Override
			public int compare(Viewer viewer, Object e1, Object e2) {
				final boolean mark1 = isHighlighted(e1);
				final boolean mark2 = isHighlighted(e2);
				if (mark1 && !mark2) {
					return -1;
				} else if (mark2 && !mark1) {
					return 1;
				} else {
					return 0;
				}
			}
		});

		reload();
		TableViewerUtil.refreshAndPack(tvResults);
		loadSettings();
	}

	private void makeSortable(TableColumn column, TableViewerUtil.AbstractInvertableTableSorter sorter) {
		new TableViewerUtil.TableSortSelectionListener(tvResults, column, sorter, SWT.UP, false);
	}

	public void reload() {
		tvResults.setInput(modelResource);
	}

	public TableViewer getViewer() {
		return tvResults;
	}

	public CTabItem getTabItem() {
		return tabItem;
	}

	public IEclipseContext getContext() {
		return context;
	}

	@Override
	public void highlightEObjects(Collection<EObject> items) {
		highlightedItems = items;
		tvResults.refresh();
	}

	@Override
	public List<EObject> getAllEObjects() {
		final ArrayList<EObject> list = new ArrayList<EObject>();
		final TreeIterator<Object> itTree = EcoreUtil.getAllContents(modelResource.getRoot());
		while (itTree.hasNext()) {
			final Object object = itTree.next();
			final EObject eObject = (EObject) object;
			final EAttribute att = EmfUtil.getAttribute(eObject, "elementId"); //$NON-NLS-1$
			if (att != null) {
				list.add(eObject);
			}
		}
		return list;
	}

	@Override
	public Collection<EObject> getSelectedEObjects() {
		final ArrayList<EObject> selected = new ArrayList<EObject>();
		for (final Object item : ((IStructuredSelection) tvResults.getSelection()).toList()) {
			if (item instanceof EObject) {
				selected.add((EObject) item);

			}
		}
		return selected;
	}

	@Override
	public void deleteEObjects(Collection<EObject> list) {
		if (list.isEmpty() == false) {
			final Command cmd = DeleteCommand.create(modelResource.getEditingDomain(), list);
			if (cmd.canExecute()) {
				modelResource.getEditingDomain().getCommandStack().execute(cmd);
			}
			reload();
		}
	}

	private TitleAreaFilterDialogWithEmptyOptions createEObjectAttributePicker(final String title) {
		// Get Attribute Names
		final HashSet<String> set = new HashSet<String>();
		final Collection<EObject> allEObjects = getAllEObjects();
		for (final EObject obj : allEObjects) {
			for (final EAttribute attribute : obj.eClass().getEAllAttributes()) {
				set.add(attribute.getName());
			}
		}
		final ArrayList<String> sorted = new ArrayList<String>(set);
		Collections.sort(sorted);

		// Select Attribute
		final ILabelProvider renderer = new LabelProvider() {
			@Override
			public String getText(Object element) {
				return String.valueOf(element);
			}
		};
		final TitleAreaFilterDialogWithEmptyOptions dlg = new TitleAreaFilterDialogWithEmptyOptions(
			context.get(Shell.class), renderer) {
			@Override
			protected Control createContents(Composite parent) {
				final Control ret = super.createContents(parent);
				setMessage(Messages.ListTab_selectAnAttribute);
				try {
					setTitleImage(imageCache.create(Plugin.ID, "/icons/full/wizban/attribute_wiz.gif")); //$NON-NLS-1$
				} catch (final Exception e) {
					e.printStackTrace();
				}
				setTitle(title);
				setElements(sorted.toArray(new String[0]));
				return ret;
			}
		};
		return dlg;
	}

	private TitleAreaFilterDialog createElementTypePicker(final String title) {
		// Get Attribute Names
		final HashSet<String> set = new HashSet<String>();
		final Collection<EObject> allEObjects = getAllEObjects();
		for (final EObject obj : allEObjects) {
			set.add(obj.eClass().getName());
		}

		final ArrayList<String> sorted = new ArrayList<String>(set);
		Collections.sort(sorted);

		final ILabelProvider renderer = new LabelProvider() {
			@Override
			public String getText(Object element) {
				return String.valueOf(element);
			}
		};
		final TitleAreaFilterDialog dlg = new TitleAreaFilterDialog(context.get(Shell.class), renderer) {

			@Override
			protected Control createContents(Composite parent) {
				final Control ret = super.createContents(parent);
				setMessage(Messages.ListTab_selectAType);
				setTitle(title);
				setElements(sorted.toArray(new String[0]));
				return ret;
			}
		};
		return dlg;
	}

	/**
	 * Adds a column if it does not already exist
	 *
	 * @param attName
	 * @return The existing or newly created column
	 */
	private EAttributeTableViewerColumn addColumn(String attName) {
		EAttributeTableViewerColumn colName = defaultColumns.get(attName);
		if (colName == null) {
			colName = optionalColumns.get(colName);
			if (colName == null) {
				colName = new EAttributeTableViewerColumn_Markable(tvResults, attName, attName, context);
				optionalColumns.put(attName, colName);
				colName.getTableViewerColumn().getColumn().setMoveable(true);
				makeSortable(colName.getTableViewerColumn().getColumn(), new AttributeColumnLabelSorter(colName
					.getTableViewerColumn().getColumn(), attName));
				tvResults.refresh();
			}
		}
		return colName;
	}

	static private class AttributeColumnLabelSorter extends TableViewerUtil.ColumnLabelSorter {

		private final String attName;

		AttributeColumnLabelSorter(TableColumn col, String attName) {
			super(col);
			this.attName = attName;
		}

		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			// if either is boolean, use boolean value, otherwise use text value
			final ATT_TYPE e1Type = EAttributeEditingSupport.getAttributeType(e1, attName);
			final ATT_TYPE e2Type = EAttributeEditingSupport.getAttributeType(e2, attName);
			if (e1Type == ATT_TYPE.BOOLEAN || e2Type == ATT_TYPE.BOOLEAN) {
				final Boolean b1 = (Boolean) EmfUtil.getAttributeValue((EObject) e1, attName);
				final Boolean b2 = (Boolean) EmfUtil.getAttributeValue((EObject) e2, attName);
				if (b1 == null && b2 != null) {
					return -2;
				} else if (b2 == null && b1 != null) {
					return 2;
				} else {
					return b1.compareTo(b2);
				}
			}
			return super.compare(viewer, e1, e2);
		}
	}

	private class EAttributeTableViewerColumn_Markable extends EAttributeTableViewerColumn {
		public EAttributeTableViewerColumn_Markable(TableViewer tvResults, String label, String attName,
			IEclipseContext context) {
			super(tvResults, label, attName, context);
		}

		@Override
		public Color getBackground(Object element) {
			Color ret;
			if (isHighlighted(element)) {
				return ret = tvResults.getTable().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
			}
			ret = super.getBackground(element);
			return ret;
		}
	}

	private class ColumnLabelProvider_Markable extends ColumnLabelProvider {
		@Override
		public Color getBackground(Object element) {
			Color ret;
			if (isHighlighted(element)) {
				ret = tvResults.getTable().getDisplay().getSystemColor(SWT.COLOR_YELLOW);
			} else {
				ret = super.getBackground(element);
			}
			return ret;
		}
	}

	@Override
	public EditingDomain getEditingDomain() {
		return modelResource.getEditingDomain();
	}

	public boolean isHighlighted(Object element) {
		return highlightedItems != null && highlightedItems.contains(element);
	}

	private void filterByItem(String name) {
		filterByItemName = name;
		filterByAttrName = null;
		filterByAttrEmptyOption = null;
		mapId_Object.clear();
		final ArrayList<EObject> filtered = new ArrayList<EObject>();
		for (final EObject object : getAllEObjects()) {
			if (object.eClass().getName().equals(filterByItemName)) {
				filtered.add(object);
				// filter.setText(Messages.ListTab_7 +
				// attFilter);

			}

			final ViewerFilter viewerFilter = new ViewerFilter() {

				@Override
				public boolean select(Viewer viewer, Object parentElement, Object element) {
					return filtered.contains(element);
				}

			};
			tvResults.setFilters(new ViewerFilter[] { viewerFilter });
			filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS + "(" + filterByItemName + ")"); //$NON-NLS-1$//$NON-NLS-2$
			filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS);
		}
	}

	private void filterByAttribute(String name, final EmptyFilterOption emptyOption) {
		filterByAttrName = name;
		filterByAttrEmptyOption = emptyOption;
		filterByItemName = null;
		mapId_Object.clear();
		final ArrayList<EObject> filtered = new ArrayList<EObject>();
		for (final EObject object : getAllEObjects()) {
			if (EmfUtil.getAttribute(object, filterByAttrName) != null) {
				filtered.add(object);
				final ViewerFilter viewerFilter = new ViewerFilter() {

					@Override
					public boolean select(Viewer viewer, Object parentElement, Object element) {
						// if filtering on attribute, always
						// reject if not defined for model
						// element
						if (EmfUtil.getAttribute((EObject) element, filterByAttrName) == null) {
							return false;
						}
						switch (emptyOption) {
						case EXCLUDE:
							if (E.isEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return false;
							}
							return filtered.contains(element);
						case ONLY:
							if (E.notEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return false;
							}
							return true;
						default:
						case INCLUDE:
							if (E.isEmpty(EmfUtil.getAttributeValue((EObject) element, filterByAttrName))) {
								return true;
							}
							return filtered.contains(element);
						}
					}
				};
				tvResults.setFilters(new ViewerFilter[] { viewerFilter });
				filterByAttribute.setText(Messages.ListTab_filterByAttribute + ELIPSIS + "(" + filterByAttrName + ")"); //$NON-NLS-1$//$NON-NLS-2$
				filterByItem.setText(Messages.ListTab_filterByItem + ELIPSIS);

			}
		}
		final TableViewerColumn viewerColumn = addColumn(filterByAttrName).getTableViewerColumn();
		viewerColumn.getColumn().pack();
	}

	@Override
	public void autosizeContent() {
		for (final TableColumn col : tvResults.getTable().getColumns()) {
			col.pack();
			if (col.getWidth() < 10) {
				col.setWidth(10);
			}
		}
	}

	@Override
	public void resetToDefault() {
		for (final EAttributeTableViewerColumn col : optionalColumns.values()) {
			col.dispose();
		}
		optionalColumns.clear();

		TableViewerUtil.resetColumnOrder(tvResults);
		TableViewerUtil.packAllColumns(tvResults);
	}

}
