/*******************************************************************************
 * Copyright (c) 2014, 2017 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.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.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<>();

	@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<>();
	LinkedHashMap<String, EAttributeTableViewerColumn> optionalColumns = new LinkedHashMap<>();
	LinkedHashMap<String, TableColumn> requiredColumns = new LinkedHashMap<>();
	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(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<>();
			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, 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<>();
		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<>();
		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<>();
		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<>(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<>();
		final Collection<EObject> allEObjects = getAllEObjects();
		for (final EObject obj : allEObjects) {
			set.add(obj.eClass().getName());
		}

		final ArrayList<String> sorted = new ArrayList<>(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(attName);
			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<>();
		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<>();
		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);
	}

}
