/**********************************************************************
 * Copyright (c) 2007 IBM Corporation.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ptp.pldt.common.views;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
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.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.ptp.pldt.common.ArtifactManager;
import org.eclipse.ptp.pldt.common.CommonPlugin;
import org.eclipse.ptp.pldt.common.IArtifact;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.texteditor.MarkerUtilities;

/**
 * Like SimpleTableMarkerView - easy view that shows markers - but uses a TreeTable to
 * show some hierarchy. Currently limited to one level of hierarchy
 * 
 * Intent: Markers are the leaf nodes.<br>
 * An attribute in the markers indicates the (artificial) parent node, for
 * grouping.
 * 
 * 
 */
public class SimpleTreeTableMarkerView extends ViewPart {
	protected TreeViewer viewer;

	/**
	 * marker attribute indicating parent node. All markers with this parentAttr
	 * will be the children of the same parent, and a node for that parent will
	 * be created so that the poor things won't be orphans. It's 4am what can I
	 * say?
	 */
	protected String parentMarkerAttrib = "parent";

	private Tree tree; // keep so we can dispose of listeners in dispose()?

	protected Action infoAction;

	private Action filterAction;

	private Action doubleClickAction;

	private static final boolean traceOn = false;

	private static final boolean traceStatusLine = false;

	protected ViewerSorter nameSorter;

	protected GenericSorter lineNoSorter;

	protected FilenameSorter filenameSorter;

	protected GenericSorter orderSorter; // by "icon"

	protected GenericSorter nameArtifactSorter;

	protected GenericSorter constructSorter;

	private IMarker selectedMarker_ = null;

	/**
	 * List of artifacts that were changed due to some action upon them in the
	 * view (currently unused)
	 */
	protected StackList changedArts_ = new StackList();

	/**
	 * List of markers that were involved in a change on the the associated
	 * artifact due to some action upon them here in the view (currently unused)
	 */
	protected StackList changedMarkers_ = new StackList();

	protected UpdateVisitor visitor_ = new UpdateVisitor();

	/**
	 * Be consistent about what we call these things; generic values (can be)
	 * replaced on ctor. <br>
	 * These are read from plugin.xml if not passed on ctor
	 */
	protected String thingname_ = "Artifact";

	protected String thingnames_ = "Artifacts";

	private String columnName_ = "Value";

	private AbstractUIPlugin thePlugin_;

	private String iconName_ = "icons/sample.gif";

	private String viewName_;

	private String markerID_;

	protected ArtifactManager artifactManager_;

	private String[] columnNames_;

	private String[] markerAttrNames_;

	/**
	 * The ID used in the marker for the unique ID for each artifact. Enables
	 * mapping back to the Artifact object if necessary.
	 */
	protected String uniqueID_ = "uniqueID";

	/**
	 * The ID used in the marker for the extra column of information (last
	 * column)
	 */
	protected String columnID_ = "constructType"; // id for (variable)

	/** Marker ID for artifact name - e.g. API name, pragma name, etc. */
	protected static final String NAME = "name";

	/** Marker ID for storage of the filename in which the artifact is found */
	protected static final String FILENAME = "filename";

	/**
	 * Marker id for storage of line number on which the artifact is found.
	 * Reuse of default ID used by IMarker, repeated here for ease of use and
	 * for clarity that THIS is the marker ID for line number.
	 */
	protected static final String LINE = IMarker.LINE_NUMBER;

	/** Marker id for storage of additional information about the artifact */
	protected static final String DESCRIPTION = "description";

	public static final int NONE = 0;

	public static final int FUNCTION_CALL = 1;

	public static final int CONSTANT = 2;

	/** types of constructs, for the default case */
	public static final String[] CONSTRUCT_TYPE_NAMES = { "None", "Function Call", "Constant" };

	/**
	 * Simple Artifact Table View constructor
	 * <p>
	 * Everything can be null, and defaults will be taken, or read from
	 * plugin.xml for the view.
	 * <p>
	 * Note: if a null plugIn instance is provided, the default plugin (this
	 * one) will not be able to find resources (e.g. icon images) if the derived
	 * class is in its own plug-in, and its icons are, too.
	 */
	public SimpleTreeTableMarkerView(AbstractUIPlugin thePlugin, String thingname, String thingnames,
			String columnName, String markerID, String parentMarkerAttrName) {

		if (thePlugin == null) {
			thePlugin_ = CommonPlugin.getDefault();
		} else {
			this.thePlugin_ = thePlugin;
		}
		if (thingname != null)
			this.thingname_ = thingname;
		if (thingnames != null)
			this.thingnames_ = thingnames;
		if (columnName != null) {
			this.columnName_ = columnName; // last column named by subclass
		}
		this.markerID_ = markerID;// if null, will use view id.
		this.parentMarkerAttrib=parentMarkerAttrName;

		findViewInfo();

	}

	/**
	 * Simple table view with an arbitrary number of extra columns
	 * 
	 * @param thePlugin
	 * @param thingname
	 * @param thingnames
	 * @param attrNames
	 *            list of marker attributes, for which the column values will be
	 *            extractd
	 * @param colNames
	 *            list of Column names, used as headers for the values found in
	 *            the marker attributes
	 * @param markerID_
	 */
	public SimpleTreeTableMarkerView(AbstractUIPlugin thePlugin, String thingname, String thingnames,
			String[] attrNames, String[] colNames, String markerID, String parentMarkerAttribName) {
		this(thePlugin, thingname, thingnames, null, markerID, parentMarkerAttribName);
		columnNames_ = colNames;
		columnName_ = null;// set this so we can tell we are using array of
		// attrs/cols
		markerAttrNames_ = attrNames;

	}

	/**
	 * Ctor that uses defaults for everything (testing? theoretically, this
	 * should work, and should be reusable since info that must be unique is
	 * read from from plugin.xml.)
	 * 
	 */
	public SimpleTreeTableMarkerView() {
		this(null, null, null, null, null,null);
	}

	/**
	 * Find info from the view info in the manifest. This includes the icon
	 * name, the view id (used as marker id if none given on ctor), and
	 * constructs an artifact manager for this view's artifact objects
	 * 
	 */
	protected void findViewInfo() {
		String classname = this.getClass().getName();
		// try to find the icon specified in the plugin.xml for this
		// extension/view
		IExtension[] ext = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.ui.views").getExtensions();
		for (int i = 0; i < ext.length; i++) {
			IExtension extension = ext[i];
			IConfigurationElement[] ces = extension.getConfigurationElements();
			for (int j = 0; j < ces.length; j++) {
				IConfigurationElement cElement = ces[j];
				String iconName = cElement.getAttribute("icon");
				String classN = cElement.getAttribute("class");
				String name = cElement.getAttribute("name");
				if (classname.equals(classN)) {
					if (iconName != null) {
						iconName_ = iconName;
					}
					this.viewName_ = name;
					if (markerID_ == null) {
						// use plugin id for marker id, if not specified
						markerID_ = cElement.getAttribute("id");
					}
					artifactManager_ = ArtifactManager.getManager(markerID_);
					if (artifactManager_ == null) {
						artifactManager_ = new ArtifactManager(markerID_);
					}
				}

			}

		}
	}

	/**
	 * It might be useful for subclasses to override this, to say which
	 * filenames should allow the action "run analysis" to create new artifacts
	 * and thus new markers. <br>
	 * This is a default implementation
	 * 
	 * @param filename
	 * @return
	 */
	public boolean validForAnalysis(String filename) {
		// return MpiUtil.validForAnalysis(filename);
		return true;

	}

	/**
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */
	class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider, IResourceChangeListener {
		private IResource input;

		private List<ParentNode> parentList = new ArrayList<ParentNode>();

		private boolean hasRegistered = false;

		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
			// could use this to change the list to just artifacts from one
			// resource,
			// etc...
			// could cache viewer here this.viewer=v;
			if (traceOn)
				System.out.println("ATV inputChanged()...");
			// if this is the first time we have been given an input
			if (!hasRegistered) {
				// add me as a resource change listener so i can refresh at
				// least when markers are changed
				// POST_CHANGE: only want event notifications for after-the-fact
				ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
				hasRegistered = true;
				if (traceOn)
					System.out.println("ATV: Registered RCL for ViewContentProvider");
			}
			if (newInput instanceof IResource) {
				this.input = (IResource) newInput;
			}

		}

		public void dispose() {
			if (traceOn)
				System.out.println("ATV.ViewContentProvider.dispose()");
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);

		}

		/**
		 * Get the list of objects to populate this view.
		 */
		public Object[] getElements(Object parent) {
			Object[] objs = null;
			try {
				String id = markerID_;
				if (input == null) {
					if (traceOn)
						System.out.println("input is null in getElements...");
				}
				objs = input.findMarkers(id, false, IResource.DEPTH_INFINITE);
				parentList=createParents(objs);
			} catch (CoreException e) {
				System.out.println("ATV, exception getting model elements (markers for Table view)");
				e.printStackTrace();
			}
			if (traceOn)
				System.out.println("ATV.get---Elements, found " + objs.length + " markers");
			return parentList.toArray();

		}

		/**
		 * create the parent objects needed for these markers
		 * 
		 * @param objs
		 * @return
		 */
		private List<ParentNode> createParents(Object[] objs) {
			// remove (old) parent objects
			parentList = new ArrayList<ParentNode>();

			IMarker[] markers = (IMarker[]) objs;
			for (int i = 0; i < markers.length; i++) {
				IMarker marker = markers[i];
				String parentName = getParentAttr(marker);
				// make one single parent, if attrs don't have parent info (yet)
				if(parentName==null) {
					parentName="dummy";
				}
				getParentNode(parentName);
			}
			return parentList;
		}

		private String getParentAttr(IMarker marker) {
			String parentName = null;
			try {
				parentName = (String) marker.getAttribute(parentMarkerAttrib);
				// temporary override to create an intial parent for all
				if( parentName==null)
					parentName="dummy";
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return parentName;
		}

		/**
		 * get the parent node with the given name. If one doesn't exist, can create
		 * it.
		 * 
		 * @param parentName
		 *            the marker attribute with the name of the parent required
		 * @param createIfNeeded whether or not to create the parent node if we don't
		 * find one already exists
		 * @return
		 */
		private ParentNode getParentNode(String parentName, boolean createIfNeeded) {
			ParentNode parentNode;
			for (Iterator iter = parentList.iterator(); iter.hasNext();) {
				parentNode = (ParentNode) iter.next();
				if (parentNode.parentAttrName.equals(parentName)) {
					return parentNode;
				}
			}
			// not found; make a new one
			parentNode=null;
			if (createIfNeeded) {
				parentNode = new ParentNode(parentName);
				parentList.add(parentNode);
			}
			return parentNode;
		}

		private ParentNode getParentNode(String parentName) {
			final boolean createIfNeeded = false;
			return getParentNode(parentName, createIfNeeded);
		}

		/**
		 * react to a resource change event
		 * 
		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
		 */

		public void resourceChanged(IResourceChangeEvent event) {
			if (traceOn)
				System.out.println("-----------------resourceChanged()");
			final IResourceDelta delta = event.getDelta();
			if (traceOn)
				printResourcesChanged(delta, 1);
			// remove the following when resource delta visitor does it all?
			Control ctrl = viewer.getControl();
			if (ctrl != null && !ctrl.isDisposed()) {
				ctrl.getDisplay().syncExec(new Runnable() {
					public void run() {
						try {
							if (traceOn)
								System.out.println("viewer.update ea mkr in delta-- from resourceChanged()...");
							if (traceOn)
								System.out.println("----processResourceChangeDelta()...");
							processResourceChangeDelta(delta);
							if (traceOn)
								System.out.println("----END processResourceChangeDelta()...");
							if (traceOn)
								System.out.println("viewer.refresh()");
							// we should have updated the indiv. rows we care
							// about,
							// but need this for Marker display after initial
							// analysis,
							// and for markers deleted, etc. Can remove when we
							// more completely
							// handle things in processResourceChangeDelta
							// (removes etc.)
							viewer.refresh();

						} catch (Exception e) {
							System.out.println("ATV: Exception refreshing viewer: " + e);
							e.printStackTrace();
						}

					}
				});
			}
			if (traceOn)
				System.out.println("-----------------END resourceChanged()\n");

		}

		/**
		 * Debugging statement help - prints the events, indented by nesting
		 * level
		 * 
		 * @param delta
		 * @param indent
		 */
		private void printResourcesChanged(IResourceDelta delta, int indent) {
			printOneResourceChanged(delta, indent);
			IResourceDelta[] children = delta.getAffectedChildren();
			for (int i = 0; i < children.length; i++)
				printResourcesChanged(children[i], indent + 1);
		}

		/**
		 * Some debugging statement help
		 * 
		 * @param delta
		 * @param indent
		 */
		private void printOneResourceChanged(IResourceDelta delta, int indent) {
			StringBuffer buf = new StringBuffer(80);
			for (int i = 0; i < indent; i++)
				buf.append("  ");
			switch (delta.getKind()) {
			case IResourceDelta.ADDED:
				buf.append("ADDED");
				break;
			case IResourceDelta.REMOVED:
				buf.append("REMOVED");
				break;
			case IResourceDelta.CHANGED:
				buf.append("CHANGED");
				testDelta(delta);
				break;
			default:
				buf.append("[");
				buf.append(delta.getKind());
				buf.append("]");
				break;
			}
			buf.append(" ");
			buf.append(delta.getResource());
			System.out.println(buf);
		}

		/**
		 * Show debugging info for a resource delta change
		 * 
		 * @param delta
		 */
		private void testDelta(IResourceDelta delta) {
			// -- code from eclipse help:
			// case IResourceDelta.CHANGED:
			System.out.print("Resource ");
			System.out.print(delta.getFullPath());
			System.out.println(" has changed.");
			int flags = delta.getFlags();
			if ((flags & IResourceDelta.CONTENT) != 0) {
				System.out.println("--> Content Change");
			}
			if ((flags & IResourceDelta.REPLACED) != 0) {
				System.out.println("--> Content Replaced");
			}
			if ((flags & IResourceDelta.MARKERS) != 0) {
				System.out.println("--> Marker Change");
				// IMarkerDelta[] markers = delta.getMarkerDeltas();
				// if interested in markers, check these deltas
			}
		}

		/**
		 * Process the resource change - just the delta
		 * 
		 * @param delta
		 */
		protected void processResourceChangeDelta(IResourceDelta delta) {
			try {
				delta.accept(visitor_);

			} catch (CoreException e2) {
				System.out.println("Error in PITV.processResourceChangeDelta()..");
				e2.printStackTrace();
			}
		}

		/**
		 * get the children (markers) of a parent node
		 */
		public Object[] getChildren(Object parentElement) {
			ParentNode parentnode = (ParentNode) parentElement;
			String parentName = parentnode.getParentAttrName();
			IMarker[] markers = null;
			try {
				markers = input.findMarkers(markerID_, false, IResource.DEPTH_INFINITE);
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			List<IMarker> children = new ArrayList<IMarker>();
			for (int i = 0; i < markers.length; i++) {
				IMarker marker = markers[i];
				String parentAttr = getParentAttr(marker);
				if (parentAttr.equals(parentName)) {
					children.add(marker);
				}
			}
			return children.toArray();
		}

		public Object getParent(Object element) {
			IMarker marker = (IMarker) element;
			String parentName = getParentAttr(marker);
			ParentNode parent = getParent(marker, false);
			return parent;
		}

		private ParentNode getParent(IMarker marker, boolean b) {
			// TODO Auto-generated method stub
			return null;
		}

		public boolean hasChildren(Object element) {
			Object[] kids=getChildren(element);
			return kids.length>0;
		}

	} // end ViewContentProvider

	class ParentNode {
		private String parentAttrName;

		public ParentNode(String parentName) {
			this.parentAttrName = parentName;
		}

		public String getParentAttrName() {
			return parentAttrName;
		}

	}

	/**
	 * get artifact from marker
	 * 
	 * @param marker
	 * @return
	 */
	protected IArtifact getSimpleArtifact(IMarker marker) {
		String id = null;
		IArtifact artifact = null;
		try {
			id = (String) marker.getAttribute(uniqueID_);
			artifact = artifactManager_.getArtifact(id);

		} catch (CoreException e) {
			// e.printStackTrace();
			System.out.println(e.getMessage() + " ... STV, CoreException getting artifact from hashMap; " + thingname_
					+ " id=" + id);
		} catch (NullPointerException ne) {
			System.out.println(ne.getMessage() + " ... STV, NullPtrExcp getting artifact from hashMap;" + thingname_
					+ " id=" + id);
		}
		return artifact;

	}

	/**
	 * Get string representing the type of construct
	 * 
	 * @param marker
	 * @return
	 * @throws CoreException
	 */
	protected String getConstructStr(IMarker marker) throws CoreException {
		Integer temp = (Integer) marker.getAttribute(columnID_);
		if (temp != null) {
			Integer constructType = (Integer) temp;
			return CONSTRUCT_TYPE_NAMES[constructType.intValue()];
		} else
			return " ";
	}

	/**
	 * 
	 * ViewLabelProvider - provides the text and images for the artifacts in the
	 * Table View
	 * 
	 * @author Beth Tibbitts
	 * 
	 * 
	 */
	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
		/**
		 * Keep icons already created, and reuse the images
		 */
		private HashMap iconHash = new HashMap();

		private IArtifact artifact;

		/**
		 * provide what goes in each column; get the info from the marker
		 */
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
		 */
		public String getText(Object o) {
			String temp = super.getText(o);
			// System.out.println("Text: " + temp);
			return temp;
		}

		/**
		 * Determine the text to go in each column
		 * 
		 * @param obj
		 *            the Marker (we hope) that goes on the current row
		 * @param index
		 *            the column number in the table
		 * 
		 */
		public String getColumnText(Object obj, int index) {
			if (obj == null) {
				System.out.println("ATV: LabelProv obj is null; index=" + index);
				return "ATV obj null";
			}
			IMarker marker = (IMarker) obj;
			try {
				switch (index) {
				case 0:
					return "";
				case 1:
					String id = (String) marker.getAttribute(NAME);
					return id;
				case 2:

					return (String) marker.getAttribute(FILENAME);
				case 3:
					String line = (marker.getAttribute(IMarker.LINE_NUMBER)).toString();

					if (traceOn) { // all this is for debugging purposes so
						artifact = getSimpleArtifact(marker);
						String compLine = line + "-";
						if (artifact == null) {
							if (traceOn)
								System.out.println("ATV getColumnText- null artifact");
						} else {
							int lineArtifact = artifact.getLine();
							compLine = compLine + lineArtifact;
						}
						System.out.println("ATV.ViewLabelProvider gets marker line: mkr-artifact: " + compLine);
						showMarker(marker);
					}
					return line;
				case 4:
					if (columnName_ != null) {// we're not using array
						return getConstructStr(marker);
					}
					// else drop through...

				default:
					String attrName = markerAttrNames_[index - 4];
					String val = marker.getAttribute(attrName, "");
					return val;
				}
			} catch (CoreException ce) {
				// get this error 3x "Marker id: 999 not found." while deleting
				// markers. why?
				// Why is this even getting called, and why does it matter?
				// String tmp = ce.getMessage();
				// ce.printStackTrace();
				return ("ATV error");
			}
		}

		/**
		 * Provide the image that goes in a column, if any (Note that a table
		 * cell can contain both, an image and text, which will be displayed
		 * side-by-side)
		 * 
		 * @param obj -
		 *            the object we're getting the image for
		 * @param index -
		 *            the column that this image is to go in
		 */
		public Image getColumnImage(Object obj, int index) {
			// we only put image icon in the first column
			switch (index) {
			case 0:
				return getCustomImage(obj);
			default:
				return null;
			}
		}

		/**
		 * Get image for artifact. Note that different images could be used for
		 * different types of artifacts. For now we have a single image.
		 * 
		 * @param obj
		 *            the marker object that this artifact is represented by
		 * @return image for marker
		 *         <p>
		 *         Note: if a null plugIn instance is provided on the view ctor,
		 *         the default plugin (this one) will not be able to find
		 *         resources (e.g. icon images) if the derived class is in its
		 *         own plug-in, and its icons are, too.
		 * 
		 */
		protected Image getCustomImage(Object obj) {
			// if we've already created one of this type of icon, reuse it.
			// Note: use ImageRegistry instead?
			Image img = (Image) iconHash.get(iconName_);
			if (img == null) {
				Path path = new Path(iconName_);
				// BRT make sure the specific plugin is being used here to find
				// its OWN icons
				URL url = thePlugin_.find(path);
				ImageDescriptor id = ImageDescriptor.createFromURL(url);
				img = id.createImage();
				if (traceOn)
					System.out.println("ATV: ***** created image for " + iconName_);
				iconHash.put(iconName_, img);// save for reuse
			}
			return img;
		}

		/**
		 * Dispose of anything that would hang around rudely otherwise (such as
		 * image objects from the icons)
		 * 
		 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
		 */

		public void dispose() {
			if (traceOn)
				System.out.println("ATV.ViewLabelProvider.dispose(); dispose of icon images");
			for (Iterator iter = iconHash.values().iterator(); iter.hasNext();) {
				Image img = (Image) iter.next();
				img.dispose();
			}
			super.dispose();
		}

	}

	/**
	 * Default sorter for items - the order they were created, which tends to
	 * group items with their source code locations
	 * 
	 * @author Beth Tibbitts
	 */
	class NameSorter extends ViewerSorter {
	}

	/**
	 * Sort items by one or more of: artifact, filename, lineNo,
	 * variableColumnName.<br>
	 * The derived classes will implement combine() to say how the attributes
	 * are combined to get the sort desired.
	 * 
	 * @author Beth Tibbitts
	 */
	abstract class GenericSorter extends ViewerSorter {
		protected boolean ascending = true;

		/**
		 * Compare two items to determine sort order. Sort items by one or more
		 * of: artifact name, then file, then line number, then construct
		 */
		public int compare(Viewer viewer, Object e1, Object e2) {
			int result = 0;

			int cat1 = category(e1);
			int cat2 = category(e2);

			if (cat1 != cat2)
				return cat1 - cat2;

			java.text.Collator collator = this.getCollator();

			if (e1 instanceof IMarker) {
				try {
					IMarker m1 = (IMarker) e1;
					IMarker m2 = (IMarker) e2;
					String name1 = (String) m1.getAttribute(NAME);
					String file1 = (String) m1.getAttribute(FILENAME);

					String line1 = (String) m1.getAttribute(LINE).toString();
					String construct1 = getConstructStr(m1);
					String sort1 = combine(name1, file1, line1, construct1);

					String name2 = (String) m2.getAttribute(NAME);
					String file2 = (String) m2.getAttribute(FILENAME);
					String line2 = (String) m2.getAttribute(LINE).toString();
					String construct2 = getConstructStr(m2);
					String sort2 = combine(name2, file2, line2, construct2);

					if (ascending)
						result = collator.compare(sort1, sort2);
					else
						result = collator.compare(sort2, sort1);

					return result;
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
			return 0;

		}

		/**
		 * Combine name, file, and/or line number to provide the string to sort
		 * by. Will be overridden by derived classes as needed
		 * 
		 * @param name
		 * @param file
		 * @param line
		 * @param construct
		 * @return always return null, subclass can choose to impl. this method.
		 */
		protected String combine(String name, String file, String line, String construct) {
			return null;
		}

		/**
		 * switch to this sorter. If it was already this sorter, then toggle the
		 * sort order
		 * 
		 */
		public void sort() {
			// String className = this.getClass().getName();
			// System.out.println(className+".sort() ascending="+ascending);
			if (this == viewer.getSorter()) {
				ascending = !ascending;
				viewer.setSorter(null); // turn off to force re-sort
			} else {
				ascending = true;
			}
			viewer.setSorter(this);

		}

	}

	/**
	 * Sorter to sort by line number on which the SimpleArtifact is Found
	 * 
	 * @author Beth Tibbitts created
	 * 
	 * 
	 */
	class LineNoSorter extends GenericSorter {
		/**
		 * sort items by line number
		 */
		public int compare(Viewer viewer, Object e1, Object e2) {

			int cat1 = category(e1);
			int cat2 = category(e2);

			if (cat1 != cat2)
				return cat1 - cat2;

			if (e1 instanceof IMarker) {
				try {
					IMarker m1 = (IMarker) e1;
					Object tempObj = m1.getAttribute(LINE);
					int line1 = 0;
					int line2 = 0;
					if (tempObj instanceof Integer) {
						line1 = ((Integer) tempObj).intValue();
						IMarker m2 = (IMarker) e2;
						tempObj = m2.getAttribute(LINE);
						// we assume if the first was Integer, this one is, too.
						assert tempObj instanceof Integer;
						line2 = ((Integer) tempObj).intValue();

					}
					int result = 0;
					if (ascending)
						result = line1 - line2;
					else
						result = line2 - line1;

					return result;
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}
			return 0;

		}
	}

	/**
	 * Sort items by name
	 * 
	 * @author Beth Tibbitts
	 * 
	 * 
	 */
	class NameArtifactSorter extends GenericSorter {

		/**
		 * @param name
		 * @param file
		 * @param line
		 * @param construct
		 * @return BRT note: Sort isn't quite right: if name,filename identical,
		 *         "10" would sort before "2" e.g.
		 */
		protected String combine(String name, String file, String line, String construct) {
			final String delim = " - ";
			StringBuffer result = new StringBuffer(name);
			result.append(delim);
			result.append(file);
			result.append(delim);
			result.append(line);
			result.append(delim);
			result.append(construct);
			return result.toString();
		}
	}

	/**
	 * Sort items by filename (then line number)
	 * 
	 * @author Beth Tibbitts
	 * 
	 * 
	 */
	class FilenameSorter extends GenericSorter {
		public int compare(Viewer viewer, Object e1, Object e2) {

			int cat1 = category(e1);
			int cat2 = category(e2);

			if (cat1 != cat2)
				return cat1 - cat2;
			int res = 0;
			try {
				IMarker m1 = (IMarker) e1;
				IMarker m2 = (IMarker) e2;
				String file1 = (String) m1.getAttribute(FILENAME);
				String file2 = (String) m2.getAttribute(FILENAME);
				if(traceOn)System.out.println("ascending=" + ascending);
				if (ascending)
					res = collator.compare(file1, file2);
				else
					res = collator.compare(file2, file1);
				// if the filename is the same, only then do we look at line
				// number
				if (res == 0) {
					String line1 = m1.getAttribute(LINE).toString();
					String line2 = m2.getAttribute(LINE).toString();
					int l1 = Integer.parseInt(line1);
					int l2 = Integer.parseInt(line2);
					if (ascending)
						res = l1 - l2;
					else
						res = l2 - l1;
				}
				// if the filename and line no are the same, only then do we
				// look at construct
				if (res == 0) {
					if (ascending) {
						res = collator.compare(getConstructStr(m1), getConstructStr(m2));
					} else {
						res = collator.compare(getConstructStr(m2), getConstructStr(m1));
					}
				}
			} catch (CoreException e) {
				e.printStackTrace();
			}
			return res;
		}
	}

	class ConstructSorter extends GenericSorter {

		/**
		 * @param name
		 * @param file
		 * @param line
		 * @param construct
		 * @return BRT note: Sort isn't quite right: if name,filename identical,
		 *         "10" would sort before "2" e.g.
		 */
		protected String combine(String name, String file, String line, String construct) {
			final String delim = " - ";
			StringBuffer result = new StringBuffer(construct);
			result.append(delim);
			result.append(name);
			result.append(delim);
			result.append(file);
			result.append(delim);
			result.append(line);
			return result.toString();
		}
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		tree = new Tree(parent, SWT.BORDER);
		tree.setLinesVisible(true);
		tree.setHeaderVisible(true);

		TreeColumn column;
		column = new TreeColumn(tree, SWT.LEFT); // col 1
		column = new TreeColumn(tree, SWT.LEFT); // col 2
		column = new TreeColumn(tree, SWT.LEFT); // col 3
		column = new TreeColumn(tree, SWT.LEFT); // col 4

		// Widget created and customized and then passed to viewer during
		// creation :
/*		Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
		TableLayout layout = new TableLayout();
		table.setLayout(layout);
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		String[] STD_HEADINGS = { " ", thingname_, "Filename", "LineNo", this.columnName_ };

		layout.addColumnData(new ColumnWeightData(1, 1, true));
		TableColumn tc0 = new TableColumn(table, SWT.NONE);
		tc0.setText(STD_HEADINGS[0]);
		tc0.setAlignment(SWT.LEFT);
		tc0.setResizable(true);

		layout.addColumnData(new ColumnWeightData(10, true));
		TableColumn tc1 = new TableColumn(table, SWT.NONE);
		tc1.setText(STD_HEADINGS[1]);
		tc1.setAlignment(SWT.LEFT);
		tc1.setResizable(true);

		layout.addColumnData(new ColumnWeightData(10, true));
		TableColumn tc2 = new TableColumn(table, SWT.NONE);
		tc2.setText(STD_HEADINGS[2]);
		tc2.setAlignment(SWT.LEFT);
		tc2.setResizable(true);

		layout.addColumnData(new ColumnWeightData(5, true));
		TableColumn tc3 = new TableColumn(table, SWT.NONE);
		tc3.setText(STD_HEADINGS[3]);
		tc3.setAlignment(SWT.LEFT);
		tc3.setResizable(true);

		TableColumn tc4 = null;
		if (this.columnName_ != null) {
			layout.addColumnData(new ColumnWeightData(5, true));
			tc4 = new TableColumn(table, SWT.NONE);
			tc4.setText(STD_HEADINGS[4]);
			tc4.setAlignment(SWT.LEFT);
			tc4.setResizable(true);
		} else {
			int numCols = columnNames_.length;
			TableColumn[] tableCols = new TableColumn[numCols];
			for (int i = 0; i < numCols; i++) {
				layout.addColumnData(new ColumnWeightData(5, true));
				TableColumn tc = new TableColumn(table, SWT.NONE);
				tc.setText(columnNames_[i]);
				tc.setAlignment(SWT.LEFT);
				tc.setResizable(true);
				tableCols[i] = tc;
			}
		}

		// add listeners for table sorting
		// Sort by "icon" (the original sort order, actually)
		tc0.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				viewer.setSorter(null);
				viewer.setSorter(nameSorter);
			}

			public void widgetDefaultSelected(SelectionEvent event) {
			}
		});
		// Sort by artifact name
		tc1.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				nameArtifactSorter.sort();
			}

			public void widgetDefaultSelected(SelectionEvent event) {
			}
		});
		// Sort by file name (then by lineNo)
		tc2.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				filenameSorter.sort();
			}

			public void widgetDefaultSelected(SelectionEvent event) {
			}
		});
		// Sort by Line number
		tc3.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				lineNoSorter.sort();
			}

			public void widgetDefaultSelected(SelectionEvent event) {
			}
		});
		// Sort by Construct (if we're not doing an array of extra columns)
		if (tc4 != null) {
			tc4.addSelectionListener(new SelectionListener() {
				public void widgetSelected(SelectionEvent event) {
					constructSorter.sort();
				}

				public void widgetDefaultSelected(SelectionEvent event) {
				}
			});
		}
*/
		// Selection listener to know when a table row is selected.

		//table.addSelectionListener(new SelectionAdapter() {
		tree.addSelectionListener(new SelectionAdapter() {

			// public void widgetDefaultSelected(SelectionEvent e) {
			// // System.out.println("widgetDefaultSelected");
			// }

			public void widgetSelected(SelectionEvent e) {
				Object obj = e.getSource();
				if (obj instanceof Table) {
					Table t = (Table) obj;
					int row = t.getSelectionIndex();
					// rowSelected_ = row;
					// print marker info when selected in table
					if (traceOn) {
						TableItem ti = t.getItem(row);
						IMarker marker = (IMarker) ti.getData();
						IArtifact artifact = getSimpleArtifact(marker);
						String id = marker.getAttribute(uniqueID_, "(error)");
						int mLine = MarkerUtilities.getLineNumber(marker);
						int lineNo = 0;
						if (artifact != null)
							lineNo = artifact.getLine();

						if (traceOn)
							System.out.println("MARKER id=" + id + " mkrLineNo=" + mLine + " artifactLineNo=" + lineNo);
					}

				}
			}
		});

		viewer = new TreeViewer(tree);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		// Set up the sorters.
		nameSorter = new NameSorter();
		viewer.setSorter(nameSorter);
		lineNoSorter = new LineNoSorter();
		nameArtifactSorter = new NameArtifactSorter();
		filenameSorter = new FilenameSorter();
		constructSorter = new ConstructSorter();

		viewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
		// markers from workspace

		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection sel = (IStructuredSelection) event.getSelection();
				Object obj = sel.getFirstElement();
				if (obj instanceof IMarker) {
					selectedMarker_ = (IMarker) obj;
				}
				showStatusMessage("", "selectionChanged");
			}
		});

		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				SimpleTreeTableMarkerView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(infoAction);
		manager.add(new Separator());
		manager.add(filterAction);
	}

	private void fillContextMenu(IMenuManager manager) {
		manager.add(infoAction);
		// Other plug-ins can contribute their actions here
		manager.add(new Separator("Additions"));
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(infoAction);
	}

	/**
	 * Make the action objects for the menus and toolbar.
	 * 
	 */
	private void makeActions() {
		makeShowInfoAction();
		makeFilterAction();
		makeDoubleClickAction();
	}

	/**
	 * Make "show info" action to display artifact information
	 */
	protected void makeShowInfoAction() {
		infoAction = new Action() {
			public void run() {
				String title = thingname_ + " information";
				if (selectedMarker_ != null) {
					String idFromMarker = (String) selectedMarker_.getAttribute(uniqueID_, null);
					if (idFromMarker == null) {
						System.out.println("ATV: exception reading marker ID");
						return;
					}
					StringBuffer info = new StringBuffer();

					IArtifact artifact = artifactManager_.getArtifact(idFromMarker);
					info.append("\nFile name: ").append(artifact.getFileName());
					info.append("\nLine number: ").append(artifact.getLine());
					info.append("\nName: ").append(artifact.getShortName());
					info.append("\nDescription: ").append(artifact.getDescription());

					MessageDialog.openInformation(null, title, info.toString());
				}// end if selectedMarker!=null
				else {
					MessageDialog.openInformation(null, title, "No " + thingname_ + " selected.");
				}
				// ------------------
			}
		};
		infoAction.setText("Show Info");
		infoAction.setToolTipText("Show detailed info for selected " + thingname_);
		infoAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
				ISharedImages.IMG_OBJS_INFO_TSK));
	}

	/**
	 * make filter action (TBD)
	 */
	private void makeFilterAction() {
		filterAction = new Action() {
			public void run() {
				showMessage("Filter " + thingnames_ + "\nDetermine which " + thingnames_ + " are shown in this view.");
			}
		};
		filterAction.setText("Filter " + thingnames_);
		filterAction.setToolTipText("Filter which " + thingnames_ + " are shown in this view");
	}

	/**
	 * Make double-click action, which moves editor to the artifact instance in
	 * the source code (editor to line in source code)
	 * 
	 */
	private void makeDoubleClickAction() {

		doubleClickAction = new Action() {
			public void run() {
				ISelection selection = viewer.getSelection();
				Object obj = ((IStructuredSelection) selection).getFirstElement();
				// This action only makes sense on child nodes (markers)
				if (!(obj instanceof IMarker)) {
					return;
				}
				IMarker marker = (IMarker) obj;
				try {
					IFile f = (IFile) marker.getResource();
					int lineNo = getMarkerLineNo(marker);
					if (f != null && f.exists()) {
						IWorkbenchPage wbp = getSite().getPage();
						// IEditorInput ieu = new FileEditorInput(f);
						IEditorPart editor = IDE.openEditor(wbp, f);

						if (traceOn)
							System.out.println("dca: marker lineNo before " + MarkerUtilities.getLineNumber(marker));
						// note: (re?) setting linenumber here is required to
						// put marker in editor!?!
						MarkerUtilities.setLineNumber(marker, lineNo);
						if (traceOn)
							System.out.println("dca: marker lineNo after " + MarkerUtilities.getLineNumber(marker));
						IDE.gotoMarker(editor, marker);
						if (traceOn)
							System.out.println("ATV: DoubleClickAction, clear status");
						showStatusMessage("", "double click action");
					}
				} catch (Exception e) {
					System.out.println("ATV.doubleclickAction: Error positioning editor page from marker line number");
					showStatusMessage("Error positioning editor from marker line number", "error marker goto");
					e.printStackTrace();
				}
			}
		};
	}

	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				doubleClickAction.run();
			}
		});
	}

	private void showMessage(String message) {
		MessageDialog.openInformation(viewer.getControl().getShell(), viewName_, message);
	}

	private void showStatusMessage(String message, String debugMessage) {
		if (traceStatusLine) {
			message += " - ";
			message += debugMessage;
		}
		getViewSite().getActionBars().getStatusLineManager().setMessage(message);
		getViewSite().getActionBars().getStatusLineManager().update(true);

	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		showStatusMessage("", "setFocus"); // reset status message
		if (!viewer.getControl().isDisposed())
			viewer.getControl().setFocus();
	}

	public void dispose() {
		if (traceOn)
			System.out.println("SimpleTableView.dispose()");
		// BRT do we need to dispose of imageDescriptors we made? or just
		// images?

	}

	public void showMarker(IMarker marker) {
		System.out.println("Marker-------  IMarker.LINE_NUMBER=" + IMarker.LINE_NUMBER);
		try {
			Map attrs = marker.getAttributes();
			Iterator iter = attrs.entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry e = (Map.Entry) iter.next();
				System.out.println("   " + e.getKey() + " " + e.getValue());
			}

		} catch (CoreException e) {
			e.printStackTrace();
		}

	}

	public ImageDescriptor makeImageDescriptor(String iconName) {
		URL url = thePlugin_.find(new Path(iconName));
		ImageDescriptor id = ImageDescriptor.createFromURL(url);
		return id;
	}

	/**
	 * Push change info (artifact and marker) onto a stack so we can remember
	 * it, for possible undo action. Also enables/disables the Undo action
	 * button.
	 * 
	 * @param artifact
	 * @param marker
	 */
	protected void pushChangedInfo(IArtifact artifact, IMarker marker) {
		changedArts_.push(artifact);
		changedMarkers_.push(marker);
		checkUndoStatus();
	}

	/**
	 * Set status of undo action (enabled or disabled) based on if there are any
	 * artifact changes, or other changes, available to undo
	 * 
	 */
	protected void checkUndoStatus() {

	}

	/**
	 * Get marker line numbers.
	 * 
	 * @param marker
	 * @return
	 */
	protected int getMarkerLineNo(IMarker marker) {
		int lineNo = getIntAttr(marker, IMarker.LINE_NUMBER);
		return lineNo;
	}

	/**
	 * Get an int value that is assumed to be stored in a marker in a given
	 * attribute.
	 * 
	 * @param marker
	 * @param attr
	 *            the attribute name
	 * 
	 * @return the int value, or 0 if none found, or invalid value found
	 */
	protected int getIntAttr(IMarker marker, String attr) {
		String temp = null;
		try {
			temp = marker.getAttribute(attr).toString();
		} catch (Exception e) { // CoreException or ClassCastException possible
			e.printStackTrace();
			System.out.println("ATV: Marker lineNo(" + attr + ") invalid; using 0");
			return 0;
		}
		int lineNo = 0;
		try {
			lineNo = Integer.parseInt(temp);
		} catch (NumberFormatException nfe) {
			System.out.println("ATV: Marker lineNo(" + temp + " from attr " + attr
					+ ") invalid (NumberFormatException); using 0");
		}
		return lineNo;
	}

	/**
	 * convenience method for getting attribute String value.
	 * 
	 * @param marker
	 * @param attr
	 * @return
	 */
	protected String getAttribute(IMarker marker, String attr) {
		String result = null;
		try {
			result = (String) marker.getAttribute(attr);
		} catch (Exception e) {
			System.out.println("** Exception getting marker attribute " + e);
			e.printStackTrace();
		}
		return result;

	}

	/**
	 * a Stack that isn't based on Vector - Generic LIFO stack
	 * 
	 * @author Beth Tibbitts
	 * 
	 * 
	 */
	public class StackList {
		private LinkedList list = new LinkedList();

		public void push(Object v) {
			list.addFirst(v);
		}

		public Object top() {
			return list.getFirst();
		}

		public Object pop() {
			return list.removeFirst();
		}

		public boolean isEmpty() {
			return list.isEmpty();
		}

	}

	/**
	 * Visit the resource delta to look for the marker changes we are interested
	 * in
	 * 
	 * @author Beth Tibbitts
	 */
	public class UpdateVisitor implements IResourceDeltaVisitor {

		/**
		 * Visit appropriate parts of the resource delta to find the markers
		 * that changed that we care about.
		 * 
		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
		 */
		public boolean visit(IResourceDelta delta) throws CoreException {
			IResource resource = delta.getResource();
			String name = resource.getName();
			if (resource.getType() == IResource.FILE) {
				if (delta.getKind() == IResourceDelta.CHANGED) {
					if (traceOn)
						System.out.println("UpdateVisitor: file changed: " + name);

					// Handle file changes (saves) by reporting the changes
					// made to the file, to update backend analysis
					// representation
					IFile f = (IFile) resource;
					int flags = delta.getFlags();
					int contentChanged = flags & IResourceDelta.CONTENT;

					if (validForAnalysis(f.getName())) {
						if (traceOn)
							System.out.println("File " + f.getName()
									+ " is valid for analysis so will process the change...");
						if (contentChanged != 0) {
							// do we need to tell back end (analysis engine)
							// that file changed?
						}

						// refresh markers for that file?
						IMarkerDelta[] mDeltas = delta.getMarkerDeltas();
						int len = mDeltas.length;
						for (int j = 0; j < len; j++) {
							IMarkerDelta delta3 = mDeltas[j];
							if (traceOn)
								showMarkerDeltaKind(delta3);
							IMarker m = delta3.getMarker();
							String ln = IMarker.LINE_NUMBER;
							if (traceOn)
								System.out.println("---UpdateVisitor.visit():viewer update marker: (lineNo)");
							// showMarker(m);
							String[] props = new String[1]; // awkward. why???
							props[0] = ln;
							// just update viewer item, not the whole view
							// viewer.refresh();
							viewer.update(m, props);
						} // end loop
					} else {
						if (traceOn)
							System.out.println("File " + f.getName()
									+ " is NOT valid for analysis so will ignore change...");

					}
				} // end if CHANGED
				else if (delta.getKind() == IResourceDelta.ADDED) {
					//System.out.println("Resource added.");
					checkMarkerDeltas(delta);
				} else if (delta.getKind() == IResourceDelta.REPLACED) {
					//System.out.println("Resource replaced.");
					checkMarkerDeltas(delta);
				} else if (delta.getKind() == IResourceDelta.REMOVED) {
					//System.out.println("Resource removed.");
					checkMarkerDeltas(delta);
				}
			} // end if FILE
			return true; // keep going
		}

		private void checkMarkerDeltas(IResourceDelta delta) {
			IMarkerDelta[] md1 = delta.getMarkerDeltas();
			int len = md1.length;
			//System.out.println("       ... found " + len + " markerDeltas.");
		}

		/**
		 * Show info about the marker in the marker delta. This is just tracing
		 * the info available until we do something with it. For now, we're just
		 * doing a (big) viewer.refresh() to refresh all the markers. When we
		 * get more intelligent about just updating the ones that changed, we
		 * can remove that. Shouldn't make much different for small sets of
		 * markers, but for many markers, this could be a significant
		 * performance improvement.
		 * 
		 * @param delta3
		 */
		private void showMarkerDeltaKind(IMarkerDelta delta3) {

			// int mdKind = delta3.getKind();
			IMarker m = delta3.getMarker();

			String kind = "UNKNOWN";
			switch (delta3.getKind()) {
			case IResourceDelta.ADDED:
				kind = "ADDED";
				break;
			case IResourceDelta.CHANGED:
				kind = "CHANGED";
				break;
			case IResourceDelta.REMOVED:
				kind = "REMOVED";
				break;
			default:
				kind = "UNKNOWN";
				break;
			}

			if (traceOn)
				System.out.println("    markerDeltaKind=" + kind);
			String mid = "", ml = "", mlpi = "";
			try {
				// note: we're getting marker deltas on ALL markers,
				// not just artifact markers, which can throw us off.
				// in particular, temp markers used by actions?

				mid = m.getAttribute(uniqueID_).toString();
				ml = m.getAttribute(IMarker.LINE_NUMBER).toString();
				// mlpi = m.getAttribute(IDs.LINE).toString();
			} catch (Exception e1) {
				// ignore errors; only tracing for now.
				System.out.println("ATV.UpdateVisitor error getting marker info ");
				e1.printStackTrace();
			}
			if (traceOn)
				System.out.println("    markerID_=" + mid + "  lineNo(mkr-mpiA)=" + ml + "-" + mlpi);
		}

	} // end class UpdateVisitor

}