MD Cleanup - not completed
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
index 890df2d..01c12d2 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
@@ -13,6 +13,7 @@
  org.eclipse.jst.jsf.common.metadata.internal.impl;x-internal:=true,
  org.eclipse.jst.jsf.common.metadata.internal.util;x-internal:=true,
  org.eclipse.jst.jsf.common.metadata.query,
+ org.eclipse.jst.jsf.common.metadata.query.internal;x-friends:="org.eclipse.jst.jsf.metadata.tests",
  org.eclipse.jst.jsf.common.metadata.traittypes.traittypes,
  org.eclipse.jst.jsf.common.metadata.traittypes.traittypes.internal.impl;x-internal:=true,
  org.eclipse.jst.jsf.common.metadata.traittypes.traittypes.internal.util;x-internal:=true,
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataLocator.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataLocator.java
index a697ece..4bb67fe 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataLocator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IMetaDataLocator.java
@@ -22,6 +22,12 @@
 	 * @return a list of <code>IMetaDataModelProvider</code>s for the uri located by this instance 
 	 */
 	public List/*<IMetaDataModelProvider>*/ locateMetaDataModelProviders(String uri);
+	
+	/**
+	 * Opportunity for service to start (add listeners, etc.). 
+	 * Framework calls this immediately after construction and all setup should occur at this time.
+	 */
+	public void startLocating();
 	/**
 	 * Stop looking for instances of metadata model sources.  An opporttunity to cleanup. 
 	 */
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
index a9f4b40..ed92cf1 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
@@ -55,8 +55,10 @@
 			Class klass = JSFCommonPlugin.loadClass(locatorClassName, bundleId);
 			try {
 				locator = (IMetaDataLocator)klass.newInstance();
-				if (locator != null)
+				if (locator != null) {
 					getLocators().put(key, locator);
+					locator.startLocating();
+				}
 			} catch (InstantiationException e) {
 				JSFCommonPlugin.log(IStatus.ERROR, "Could not instantiate IMetaDataLocator: "+key, e);
 			} catch (IllegalAccessException e) {
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
index c9fa89e..6be9a4a 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
@@ -20,10 +20,13 @@
 import org.eclipse.jst.jsf.common.metadata.Model;
 import org.eclipse.jst.jsf.common.metadata.Trait;
 import org.eclipse.jst.jsf.common.metadata.query.IMetaDataModelContext;
+import org.eclipse.jst.jsf.common.metadata.query.MetaDataException;
 import org.eclipse.jst.jsf.common.metadata.query.MetaDataQueryHelper;
-import org.eclipse.jst.jsf.common.metadata.query.SearchControl;
-import org.eclipse.jst.jsf.common.metadata.query.SimpleMetaDataQueryVisitorImpl;
-import org.eclipse.jst.jsf.common.metadata.query.SimpleResultSet;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SearchControl;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleEntityQueryVisitorImpl;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleResultSet;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleTraitQueryVisitorImpl;
+import org.eclipse.jst.jsf.common.metadata.query.internal.HierarchicalSearchControl;
 /**
  * Implements {@link IMetaDataModelMergeAssistant}
  * 
@@ -38,17 +41,19 @@
 	
 	private MetaDataModel mergedModel;
 	private Copier copier;
-	private SimpleMetaDataQueryVisitorImpl visitor;
+	private SimpleEntityQueryVisitorImpl entityVisitor;
+	private SimpleTraitQueryVisitorImpl traitVisitor;
 	private IMetaDataSourceModelProvider provider;
 	
 	/**
-	 * Constructor
+	 * Constructor.   Queries with search control limited to first found.
 	 * @param model
 	 */
 	public MetaDataModelMergeAssistantImpl(MetaDataModel model) {
 		this.mergedModel = model;
 		copier = new Copier();
-		visitor = new SimpleMetaDataQueryVisitorImpl(new SearchControl(1, SearchControl.SCOPE_ALL_LEVELS));
+		entityVisitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, HierarchicalSearchControl.SCOPE_ALL_LEVELS));
+		traitVisitor = new SimpleTraitQueryVisitorImpl(new SearchControl(1));
 	}
 
 	/* (non-Javadoc)
@@ -233,11 +238,15 @@
 		
 		Entity ret = null;
 		String entityKey = getIdRelativeToRoot(entity);
-		SimpleResultSet rs = (SimpleResultSet)visitor.findEntities((Entity)mergedModel.getRoot(), entityKey);
-		if (rs.getResults().size() >0)
-			ret = (Entity)rs.getResults().get(0);
-		
-		rs.close();
+		SimpleResultSet rs = (SimpleResultSet)entityVisitor.findEntities((Entity)mergedModel.getRoot(), entityKey);
+		if (rs.getSize() >0) {
+			try {
+				ret = (Entity)rs.next();				
+				rs.close();
+			} catch (MetaDataException e) {
+				//MetaDataException is not currently being thrown
+			}
+		}
 		return ret;
 	}
 	
@@ -262,15 +271,19 @@
 	 * @return merged Trait
 	 */
 	public Trait getMergedTrait(Entity entity, Trait trait){
-		SimpleResultSet rs = (SimpleResultSet)visitor.findTraits(entity, trait.getId());
+		SimpleResultSet rs = (SimpleResultSet)traitVisitor.findTraits(entity, trait.getId());
 		Trait ret = null;
-		if (rs.getResults().size() >0)
-			ret = (Trait)rs.getResults().get(0);
-		
-		rs.close();
+		if (rs.getSize() > 0) {
+			try {
+				ret = (Trait)rs.next();				
+				rs.close();
+			} catch (MetaDataException e) {
+				//MetaDataException not currently being thrown
+			}
+		}
 		return ret;
 	}
-	
+
 	private void processIncludeGroups(final Model root) {
 		addEntityGroupReferencesRecursively(root);
 	}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataLocator.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataLocator.java
index 86cddf1..fd3e3ea 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataLocator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataLocator.java
@@ -31,9 +31,15 @@
 	/* 
 	 * Does nothing.
 	 */
+	public void startLocating() {
+		//do nothing
+	}
+
+	/* 
+	 * Does nothing.
+	 */
 	public void stopLocating() {
 		//do nothing
-
 	}
 
 
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
index 6df2fe5..da8c465 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/EntityImpl.java
@@ -2,7 +2,7 @@
  * <copyright>
  * </copyright>
  *
- * $Id: EntityImpl.java,v 1.4 2007/04/16 19:54:10 itrimble Exp $
+ * $Id: EntityImpl.java,v 1.5 2007/05/16 23:51:15 gkessler Exp $
  */
 package org.eclipse.jst.jsf.common.metadata.internal.impl;
 
@@ -258,7 +258,7 @@
 //				}
 //			}
 //		}
-		visitor.visitCompleted();
+		visitor.visitCompleted(this);
 	}
 
 	/**
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
index 8a5652c..764e9a2 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/impl/ModelImpl.java
@@ -2,7 +2,7 @@
  * <copyright>
  * </copyright>
  *
- * $Id: ModelImpl.java,v 1.4 2007/05/11 17:54:55 gkessler Exp $
+ * $Id: ModelImpl.java,v 1.5 2007/05/16 23:51:15 gkessler Exp $
  */
 package org.eclipse.jst.jsf.common.metadata.internal.impl;
 
@@ -239,7 +239,7 @@
 			}
 		}
 
-		visitor.visitCompleted();
+		visitor.visitCompleted(this);
 	}
 	/**
 	 * <!-- begin-user-doc -->
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityQueryVisitor.java
similarity index 60%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityQueryVisitor.java
index 3e0481a..bf89e84 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityQueryVisitor.java
@@ -9,15 +9,20 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
+import org.eclipse.jst.jsf.common.metadata.Entity;
 
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
+ * Abstract class implmenting {@link IEntityQueryVisitor} that concrete subclasses should provide implementations
  *
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public class AbstractEntityQueryVisitor extends AbstractEntityVisitor
+		implements IEntityQueryVisitor {
+
+	public IResultSet findEntities(Entity initialEntityContext, String entityKey) {
+		return new EmptyResultSet();
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityVisitor.java
similarity index 64%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityVisitor.java
index 3e0481a..4cae207 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractEntityVisitor.java
@@ -9,15 +9,23 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
+import org.eclipse.jst.jsf.common.metadata.Entity;
 
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
- *
+ * Abstract implementation that concrete subclasses should ovveride
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public abstract class AbstractEntityVisitor extends AbstractMetaDataVisitor
+		implements IEntityVisitor {
+
+	public void visit(Entity entity){
+		//
+	}
+
+	public void visitCompleted(Entity entity) {
+		//
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractMetaDataVisitor.java
similarity index 66%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractMetaDataVisitor.java
index 3e0481a..9466d2a 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractMetaDataVisitor.java
@@ -9,15 +9,19 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
-
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
- *
+ * Abstract class implementing {@link IMetaDataVisitor}
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public abstract class AbstractMetaDataVisitor implements IMetaDataVisitor {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.common.metadata.query.IMetaDataVisitor#stopVisiting()
+	 */
+	public boolean stopVisiting() {		
+		return false;
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractResultSet.java
index abfd1c1..4e220b2 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractResultSet.java
@@ -1,86 +1,59 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2007 Oracle Corporation and others.
+ * Copyright (c) 2007 Oracle 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:
- *     Oracle Corporation - initial API and implementation
- *******************************************************************************/
+ *    Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.Collection;
+import java.util.Iterator;
 
 /**
  * Default implementation of {@link IResultSet}.   Developers may subclass.
- *
+ * Currently MetaDataException is not being thrown but is in the interface for the future.
+ * Users should assume that the results are only valid at the time of the query.  This may change in the future. 
  */
 public abstract class AbstractResultSet/*<T>*/ implements IResultSet/*<T>*/ {
+	private Iterator 	_iterator;
+	private Collection	_results;
 	
-	private List/*<T>*/ results;
 	
-	/**
-	 * Constructor passing a list to hold the results
-	 * @param results 
-	 */
-	public AbstractResultSet(List/*<T>*/ results){
-		super();
-		this.results = results;
-	}
-	
-	/**
-	 * Constructor
-	 */
-	public AbstractResultSet(){
-		results = new ArrayList/*<T>*/();
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jst.jsf.common.metadata.query.IResultSet#close()
-	 */
-	public void close() {
-		//nothing to do really
-		if (results != null)
-			results.clear();
-	}
-	
-	/**
-	 * @param item
-	 */
-	public void addItem(Object item){
-		getInternalResults().add(item);
+	public void close() throws MetaDataException {
+		_results = null;
+		_iterator = null;
 	}
 
-    // API: should return Collection so that subs can use
-    // co-variance to return other sorts of collections
-    // API: consider making final and make getInternalResults protected abstract
-	public List/*<T>*/ getResults() {
-		if (results == null)
-			return Collections.EMPTY_LIST;
-	
-		return results;
+	public final int getSize(){
+		initIfNecessary();
+		return _results.size();		
 	}
 
+	public boolean hasNext() throws MetaDataException {
+		initIfNecessary();
+		return _iterator.hasNext();			
+	}
+
+	public Object next() throws MetaDataException {
+		initIfNecessary();		
+		return _iterator.next();
+	}
 	/**
-	 * @return resultset size
+	 * @return Collection of results.  Implementer must NOT return null.  Return Collections.EMPTY_LIST instead.
 	 */
-    // API: should make this final and force
-    // implementers to handle getInternalResults
-	public int size(){
-		if (results == null)
-			return 0;
-		
-		return getInternalResults().size();
-	}
-
-	private List getInternalResults() {
-		if (results == null){
-			results = new ArrayList();
+	protected abstract Collection getInternalResults();
+	
+	private void initIfNecessary() {
+		if (_results == null) {
+			_results = getInternalResults();
+			_iterator = _results.iterator();
 		}
-		return results;
 	}
 
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitQueryVisitor.java
similarity index 61%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitQueryVisitor.java
index 3e0481a..61a269f 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitQueryVisitor.java
@@ -9,15 +9,19 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
+import org.eclipse.jst.jsf.common.metadata.Entity;
 
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
- *
+ * Abstract implmentation of {@link ITraitQueryVisitor} that subclasses should use to provide implmentation 
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public abstract class AbstractTraitQueryVisitor extends AbstractTraitVisitor implements
+		ITraitQueryVisitor {
+
+	public IResultSet findTraits(Entity entity, String traitKey) {
+		return new EmptyResultSet();
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitVisitor.java
similarity index 66%
rename from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
rename to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitVisitor.java
index 3e0481a..2870a4c 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/AbstractTraitVisitor.java
@@ -9,15 +9,17 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
+import org.eclipse.jst.jsf.common.metadata.Trait;
 
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
  *
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public abstract class AbstractTraitVisitor extends AbstractMetaDataVisitor implements ITraitVisitor{
+
+	public void visit(Trait trait) { // 
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/EmptyResultSet.java
similarity index 64%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/EmptyResultSet.java
index 3e0481a..86a7c84 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/EmptyResultSet.java
@@ -9,15 +9,27 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
-
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
- *
+ * Implementation of an empty result set
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public class EmptyResultSet implements IResultSet {
+
+	public void close() {//
+	}
+
+	public int getSize() throws MetaDataException {
+		return 0;
+	}
+
+	public boolean hasNext() throws MetaDataException {				
+		return false;
+	}
+
+	public Object next() throws MetaDataException {
+		return null;
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityQueryVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityQueryVisitor.java
index ccdc353..a7a8b6b 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityQueryVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityQueryVisitor.java
@@ -15,13 +15,14 @@
 
 /**
  * Entity querying interface
+ * NOT to implemented by clients directly.   Clients should subclass AbstractEntityQueryVisitor instead.
  *
  */
 public interface IEntityQueryVisitor extends IEntityVisitor{
 	/**
 	 * @param initialEntityContext
 	 * @param entityKey to find relative to the passed intialEntityContext
-	 * @return IResultSet of Entities matching the key.  IResultSet should NOT be null.
+	 * @return IResultSet of Entities matching the key.  IResultSet must NOT be null.  Implementers may return {@link EmptyResultSet}.
 	 */
 	public IResultSet/*<Entity>*/ findEntities(final Entity initialEntityContext,
 			final String entityKey);
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityVisitor.java
index 007e208..73e74cd 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IEntityVisitor.java
@@ -15,18 +15,19 @@
 
 /**
  * Visitor interface for Entities
- * API: should we force extension through an abstract class?
+ * NOT to implemented by clients directly.   Clients should subclass AbstractEntityVisitor instead.
  */
-public abstract interface IEntityVisitor extends IMetaDataVisitor {
+public interface IEntityVisitor extends IMetaDataVisitor {
 	/**
-	 * Visit the entity
-	 * @param entity
+	 * Visit the entity. 
+	 * The entity and then it's children are visited
+	 * @param entity - must not be NULL
 	 */
 	public void visit(final Entity entity);
 	/**
-	 * Signal that the last visited entity is now completely 'visited'.  
-	 * Needed to signal that all children have also been visited.
-     * API: what is the contract here for implementers of this interface?
+	 * Signal that the entity and all it's children is now completely 'visited'.  
+	 * The entity will call this method at the end of the accept method.
+	 * @param entity - must not be NULL
 	 */
-	public void visitCompleted();
+	public void visitCompleted(Entity entity);
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IMetaDataVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IMetaDataVisitor.java
index 7ed06be..cf92317 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IMetaDataVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IMetaDataVisitor.java
@@ -13,9 +13,9 @@
 
 /**
  * Common interface for Entity and Trait visitors
+ * NOT to implemented by clients directly.   Clients should subclass AbstractMetaDataVisitor instead.
  */
-public abstract interface IMetaDataVisitor {
-    // API: contract?
+public interface IMetaDataVisitor {
 	/**
 	 * @return true if visitor has recognized that visiting should stop
 	 */
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IResultSet.java
index cbe91ee..5df6eb6 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/IResultSet.java
@@ -11,24 +11,36 @@
  ********************************************************************************/
 package org.eclipse.jst.jsf.common.metadata.query;
 
-import java.util.List;
 
 
 /**
- * Results from a metadata query.
+ * Results from a metadata query.  The resultset should be considered valid only at the time that the query is performed.
  * 
- * Not intended to be implemented directly by clients.  Developers may extend {@link AbstractResultSet} instead.
+ * Not intended to be implemented directly by clients.  Developers should extend {@link AbstractResultSet} instead.
  */
 public interface IResultSet/*<T>*/{
 	
 	/**
-	 * @return List of results.  May NOT be null.  Implementer must return Collections.EMPTY_LIST instead.
+	 * @return size of the resultset.  
+	 * @throws MetaDataException 
 	 */
-	public List/*<T>*/ getResults();
+	public int getSize() throws MetaDataException;
+		
+	/**
+	 * @return next result.   Clients should check hasNext() before calling.
+	 * @throws MetaDataException 
+	 */
+	public Object/*<T>*/ next() throws MetaDataException;
 	
 	/**
-	 * Signal that the query results are no longer required allowing for any cleanup that may be required
-     * API: event to signal that result set is no longer valid?
+	 * @return true if the resultset has more elements
+	 * @throws MetaDataException
 	 */
-	public void close();
+	public boolean hasNext() throws MetaDataException;
+
+	/**
+	 * Signal that the query results are no longer required allowing for any cleanup that may be required
+	 * @throws MetaDataException 
+	 */
+	public void close() throws MetaDataException;
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitQueryVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitQueryVisitor.java
index 7309ebe..07e8f32 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitQueryVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitQueryVisitor.java
@@ -15,12 +15,13 @@
 
 /**
  * Trait querying interface
+ * NOT to implemented by clients directly.   Clients should subclass AbstractTraitQueryVisitor instead.
  */
 public interface ITraitQueryVisitor extends ITraitVisitor{
 	/**
 	 * @param entity
 	 * @param traitKey
-	 * @return IResultSet of Traits.  IResultSet should NOT be null.
+	 * @return IResultSet of Traits.  IResultSet must NOT be null.  Implementers may return {@link EmptyResultSet}.
 	 */
 	public IResultSet/*<Trait>*/ findTraits(final Entity entity,
 			final String traitKey);
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitVisitor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitVisitor.java
index 031442c..3254cee 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitVisitor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/ITraitVisitor.java
@@ -15,14 +15,13 @@
 
 /**
  * Visitor interface for Traits
- *
+ * NOT to implemented by clients directly.   Clients should subclass AbstractTraitVisitor instead.
  */
-public abstract interface ITraitVisitor extends IMetaDataVisitor {
+public interface ITraitVisitor extends IMetaDataVisitor {
 	/**
-	 * Visit the Trait
-	 * @param trait
-     * API: what is the responsibilit of the implementor? pre/post-conditions?
-     * API: what is the order of the visitation (or should it not be assumed)
-	 */
-	abstract void visit(final Trait trait);
+	 * Visit the Trait.
+	 * Implementer cannot assume ordering of trait visiting. 
+	 * @param trait - must not be null
+ 	 */
+	public void visit(final Trait trait);
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataException.java
similarity index 66%
copy from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
copy to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataException.java
index 3e0481a..6ea0a4a 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleResultSet.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataException.java
@@ -9,15 +9,16 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
+
 package org.eclipse.jst.jsf.common.metadata.query;
 
-
-
 /**
- * Simple implementation of {@link IResultSet} by extending AbstractResultSet
- *
+ * Exception intended to be superclass of all exceptions thrown while handling metadata during query
  */
-public class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
-    // API: Should push down overridable functionality from AbstractResultSet
-    // and make final all functionality left in AbstractResultSet
+public class MetaDataException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataQueryHelper.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataQueryHelper.java
index a7a1555..e1feb2b 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataQueryHelper.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/MetaDataQueryHelper.java
@@ -18,6 +18,9 @@
 import org.eclipse.jst.jsf.common.metadata.internal.MetaDataModel;
 import org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelContextImpl;
 import org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelManager;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleEntityQueryVisitorImpl;
+import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleTraitQueryVisitorImpl;
+import org.eclipse.jst.jsf.common.metadata.query.internal.HierarchicalSearchControl;
 
 
 /**
@@ -27,7 +30,7 @@
  * 
  * This class need not be used.   Visitors can be created and used directly on the model.
  * 
- * @see SimpleMetaDataQueryVisitorImpl
+ * @see SimpleEntityQueryVisitorImpl
  * @see IEntityQueryVisitor
  * @see ITraitQueryVisitor
  * @see IMetaDataModelContext
@@ -41,6 +44,13 @@
 	public static final String TAGLIB_DOMAIN = "TagLibraryDomain"; //need better place for this
 	
 	/**
+	 * private constructor
+	 */
+	private MetaDataQueryHelper (){
+		super();
+	}
+	
+	/**
 	 * @param project
 	 * @param domain id
 	 * @param uri
@@ -79,13 +89,18 @@
 	 */
 	public static Entity getEntity(final IMetaDataModelContext modelContext,
 			final String entityKey) {
-		IEntityQueryVisitor visitor = new SimpleMetaDataQueryVisitorImpl(new SearchControl(1, SearchControl.SCOPE_ALL_LEVELS));
+		IEntityQueryVisitor visitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, HierarchicalSearchControl.SCOPE_ALL_LEVELS));
 		IResultSet/*<Entity>*/ rs = getEntities(modelContext,entityKey,  visitor);
 		Entity e = null;
-		if (rs.getResults().size() > 0){
-			e = (Entity)rs.getResults().get(0);				
+		try {
+			if (rs.getSize() > 0){
+				e = (Entity)rs.next();				
+			}
+			rs.close();
+		} catch (MetaDataException ex) {
+			//Currently MetaDataException is never actually thrown
 		}
-		rs.close();
+
 		return e;
 	}
 
@@ -106,16 +121,21 @@
 	/**
 	 * @param entity
 	 * @param traitKey
-	 * @return a trait or null for the given entity and traitKey using a SimpleMetaDataQueryVisitorImpl 
+	 * @return a trait or null for the given entity and traitKey using a SimpleEntityQueryVisitorImpl 
 	 */
 	public static Trait getTrait(final Entity entity, final String traitKey){
-		ITraitQueryVisitor visitor = new SimpleMetaDataQueryVisitorImpl();	
+		ITraitQueryVisitor visitor = new SimpleTraitQueryVisitorImpl();	
 		Trait t= null;
 		IResultSet/*<Trait>*/ rs = getTraits(entity, traitKey, visitor);
-		if (rs.getResults().size() > 0){
-			t = (Trait)rs.getResults().get(0);				
+		try {
+			if (rs.getSize() > 0){
+				t = (Trait)rs.next();				
+			}
+			rs.close();
+		} catch (MetaDataException ex) {
+			//Currently MetaDataException is never actually thrown
 		}
-		rs.close();
+
 		return t;
 	}
 
@@ -134,16 +154,20 @@
 	/**
 	 * @param initialEntityContext
 	 * @param entityKey relative to initial passed entity
-	 * @return the first entity located by key using SimpleMetaDataQueryVisitorImpl
+	 * @return the first entity located by key using SimpleEntityQueryVisitorImpl
 	 */
 	public static Entity getEntity(Entity initialEntityContext, String entityKey) {
-		IEntityQueryVisitor visitor = new SimpleMetaDataQueryVisitorImpl(new SearchControl(1, SearchControl.SCOPE_ALL_LEVELS));
+		IEntityQueryVisitor visitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, HierarchicalSearchControl.SCOPE_ALL_LEVELS));
 		Entity e= null;
 		IResultSet/*<Entity>*/ rs = getEntities(initialEntityContext, entityKey, visitor);
-		if (rs.getResults().size() > 0)
-			e = (Entity)rs.getResults().get(0);
-		
-		rs.close();
+		try {
+			if (rs.getSize() > 0)
+				e = (Entity)rs.next();	
+			rs.close();
+		} catch (MetaDataException ex) {
+			//Currently MetaDataException is never actually thrown
+		}		
+
 		return e;		
 	}
 
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SearchControl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SearchControl.java
deleted file mode 100644
index a9510da..0000000
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SearchControl.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 Oracle 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:
- *    Oracle - initial API and implementation
- *    
- ********************************************************************************/
-package org.eclipse.jst.jsf.common.metadata.query;
-
-/**
- * Simple class used by {@link SimpleMetaDataQueryVisitorImpl} allowing some control of a metadata query.  
- * A query visitor can use this to optimize the query results and signal completion.
- * API: extensibility?  should this be package private? 
- */
-public class SearchControl {
-	
-	//scope levels
-	/**
-	 * Do not recurse.  
-	 */
-	public static final int SCOPE_CURRENT_LEVEL = 0;
-	/**
-	 * Allow for one level of children to be visited from initial context
-	 */
-	public static final int SCOPE_ONE_LEVEL = 1;
-	/**
-	 * Allow unlimited recursion of children
-	 */
-	public static final int SCOPE_ALL_LEVELS = 2;
-	
-	/**
-	 * No limit on query results
-	 */
-	public static final int COUNT_LIMIT_NONE = -1;
-	
-	//default settings
-	private int countLimit = COUNT_LIMIT_NONE;
-	private int scope = SCOPE_ALL_LEVELS;
-	
-	/**
-	 * Constructor using defaults of COUNT_LIMIT_NONE and SCOPE_ALL_LEVELS 
-	 */
-	public SearchControl(){
-		//use default settings
-	}
-	
-	/**
-	 * Constructor
-	 * @param countLimit
-	 * @param scope
-	 */
-	public SearchControl(int countLimit, int scope){
-		this.scope = scope;
-		this.countLimit = countLimit;
-	}
-	
-	/**
-	 * @param limit results count limit
-	 */
-	public void setCountLimit(int limit){
-		this.countLimit = limit;
-	}
-	
-	/**
-	 * @return query results count limit
-	 */
-	public int getCountLimit(){
-		return countLimit;
-	}
-	
-	/**
-	 * @param scope
-	 */
-	public void setScope(int scope){
-		this.scope= scope;
-	}
-	
-	/**
-	 * @return scope
-	 */
-	public int getScope(){
-		return scope;
-	}
-}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/HierarchicalSearchControl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/HierarchicalSearchControl.java
new file mode 100644
index 0000000..36d446e
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/HierarchicalSearchControl.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle 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:
+ *    Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+
+package org.eclipse.jst.jsf.common.metadata.query.internal;
+
+/**
+ * Sets controls on how a tree of nodes can be searched
+ */
+public class HierarchicalSearchControl extends SearchControl {
+	//scope levels
+	/**
+	 * Do not recurse.  
+	 */
+	public static final int SCOPE_CURRENT_LEVEL = 0;
+	/**
+	 * Allow for one level of children to be visited from initial context
+	 */
+	public static final int SCOPE_ONE_LEVEL = 1;
+	/**
+	 * Allow unlimited recursion of children
+	 */
+	public static final int SCOPE_ALL_LEVELS = 2;
+	
+	private int scope = SCOPE_ALL_LEVELS;
+	
+	/**
+	 * Constructor using defaults of COUNT_LIMIT_NONE and SCOPE_ALL_LEVELS 
+	 */
+	public HierarchicalSearchControl(){
+		super();
+	}
+	/**
+	 * Constructor
+	 * @param countLimit
+	 * @param scope
+	 */
+	public HierarchicalSearchControl(int countLimit, int scope){
+		super(countLimit);
+		this.scope = scope;
+	}
+	
+	
+	/**
+	 * @param scope
+	 */
+	public void setScope(int scope){
+		this.scope= scope;
+	}
+	
+	/**
+	 * @return scope
+	 */
+	public int getScope(){
+		return scope;
+	}
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SearchControl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SearchControl.java
new file mode 100644
index 0000000..ee59315
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SearchControl.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle 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:
+ *    Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+package org.eclipse.jst.jsf.common.metadata.query.internal;
+
+/**
+ * Simple class used by {@link SimpleEntityQueryVisitorImpl} allowing some control of a metadata query.  
+ * A query visitor can use this to optimize the query results and signal completion.
+ * API: extensibility?  should this be package private? 
+ */
+public class SearchControl {
+	
+
+	/**
+	 * No limit on query results
+	 */
+	public static final int COUNT_LIMIT_NONE = -1;
+	
+	//default settings
+	private int countLimit = COUNT_LIMIT_NONE;
+
+	
+	/**
+	 * Constructor using defaults of COUNT_LIMIT_NONE
+	 */
+	public SearchControl(){
+		//use default settings
+	}
+	
+	/**
+	 * Constructor
+	 * @param countLimit
+	 */
+	public SearchControl(int countLimit){
+		this.countLimit = countLimit;
+	}
+	
+	/**
+	 * @param limit results count limit
+	 */
+	public void setCountLimit(int limit){
+		this.countLimit = limit;
+	}
+	
+	/**
+	 * @return query results count limit
+	 */
+	public int getCountLimit(){
+		return countLimit;
+	}
+
+}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleMetaDataQueryVisitorImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
similarity index 61%
rename from jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleMetaDataQueryVisitorImpl.java
rename to jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
index a6376e9..2b5d754 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/SimpleMetaDataQueryVisitorImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleEntityQueryVisitorImpl.java
@@ -9,14 +9,18 @@
  *    Oracle - initial API and implementation
  *    
  ********************************************************************************/
-package org.eclipse.jst.jsf.common.metadata.query;
+package org.eclipse.jst.jsf.common.metadata.query.internal;
 
-import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Stack;
 
 import org.eclipse.jst.jsf.common.metadata.Entity;
 import org.eclipse.jst.jsf.common.metadata.EntityGroup;
-import org.eclipse.jst.jsf.common.metadata.Trait;
+import org.eclipse.jst.jsf.common.metadata.query.AbstractEntityQueryVisitor;
+import org.eclipse.jst.jsf.common.metadata.query.IEntityQueryVisitor;
+import org.eclipse.jst.jsf.common.metadata.query.IResultSet;
+import org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor;
 
 
 /**
@@ -25,61 +29,29 @@
  * - Does not allow for wild card searchs
  * API: extensibility?
  */
-public class SimpleMetaDataQueryVisitorImpl implements IEntityQueryVisitor, ITraitQueryVisitor  {
-
-	private String _traitQuery;
-	private SearchControl control;
+public class SimpleEntityQueryVisitorImpl extends AbstractEntityQueryVisitor  {
+	private HierarchicalSearchControl control;
 	private boolean _stop;
 
 	private EntityQueryComparator entityComparator;
-	private SimpleResultSet/*<Entity>*/ entityResultSet;
-	private SimpleResultSet/*<Trait>*/ traitResultSet;
+	private List/*<Entity>*/ _entityResults;
 
 	/**
 	 * Constructor that also creates a default SearchControl
 	 */
-	public SimpleMetaDataQueryVisitorImpl() {
+	public SimpleEntityQueryVisitorImpl() {
 		super();
-		control = new SearchControl();
+		control = new HierarchicalSearchControl();
 	}
 	
 	/**
 	 * Constructor
 	 * @param control
 	 */
-	public SimpleMetaDataQueryVisitorImpl(SearchControl control) {
+	public SimpleEntityQueryVisitorImpl(HierarchicalSearchControl control) {
 		super();
 		this.control = control;
 	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor#findTraits(org.eclipse.jst.jsf.common.metadata.Entity, java.lang.String)
-	 */
-	public IResultSet/*<Trait>*/ findTraits(final Entity entity, final String traitQuery){
-		
-		resetQuery();
-		if (entity != null){			
-			this._traitQuery = traitQuery;			
-			for (Iterator/*<Trait>*/ it=entity.getTraits().iterator();it.hasNext();){
-				Trait t = (Trait)it.next();
-				t.accept(this);
-				if (stopVisiting())
-					break;
-			}
-		}
-		return getTraitResultSet();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.jst.jsf.common.metadata.query.ITraitVisitor#visit(org.eclipse.jst.jsf.common.metadata.Trait)
-	 */
-	public void visit(Trait trait) {		
-		if (trait.equals(_traitQuery))
-			getTraitResultSet().addItem(trait);		
-		
-		checkShouldStopVisitingTraits();
-	}
-
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jst.jsf.common.metadata.query.IEntityQueryVisitor#findEntities(org.eclipse.jst.jsf.common.metadata.Entity, java.lang.String)
@@ -94,40 +66,28 @@
 			initialEntityContext.accept(this);			
 		}
 		
-		return getEntityResultSet();
+		return new SimpleResultSet(getInternalEntityResults());
 	}
 
 	private void resetQuery() {
 		_stop = false;
+		_entityResults = null;
 	}
 
-	/**
-	 * @return @return lazy init of a SimpleResultSet of Entities
-	 */
-	private SimpleResultSet/*<Entity>*/ getEntityResultSet(){
-		if (entityResultSet == null){
-			entityResultSet = new SimpleResultSet/*<Entity>*/();
+	private List/*<Entity>*/ getInternalEntityResults(){
+		if (_entityResults == null){
+			_entityResults = new ArrayList/*<Entity>*/();
 		}
-		return entityResultSet;
+		return _entityResults;
 	}
 
-	/**
-	 * @return lazy init of a SimpleResultSet of Traits
-	 */
-	private SimpleResultSet/*<Trait>*/ getTraitResultSet(){
-		if (traitResultSet == null){
-			traitResultSet = new SimpleResultSet/*<Trait>*/();
-		}
-		return traitResultSet;
-	}
-	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor#visit(org.eclipse.jst.jsf.common.metadata.Entity)
 	 */
 	public void visit(Entity key) {		
 		switch (entityComparator.compareTo(key)){
 			case 0:
-				getEntityResultSet().addItem(key);
+				getInternalEntityResults().add(key);
 				break;
 			default:
 				break;
@@ -136,9 +96,9 @@
 		checkShouldStopVisitingEntities();
 	}
 	/* (non-Javadoc)
-	 * @see org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor#visitCompleted()
+	 * @see org.eclipse.jst.jsf.common.metadata.query.IEntityVisitor#visitCompleted(Entity entity)
 	 */
-	public void visitCompleted() {
+	public void visitCompleted(Entity entity) {
 		entityComparator.popContext();
 	}
 	
@@ -151,16 +111,9 @@
 
 	private void checkShouldStopVisitingEntities(){
 		//implement how to set stop to signal to the entity accept() to skip visiting
-		if (control.getCountLimit()== getEntityResultSet().size() && control.getCountLimit() != SearchControl.COUNT_LIMIT_NONE )
+		if (control.getCountLimit()== getInternalEntityResults().size() && control.getCountLimit() != SearchControl.COUNT_LIMIT_NONE )
 			_stop = true;
 	}
-	
-	private void checkShouldStopVisitingTraits(){
-		//this simple visitor will only find a single trait as it checks for exact match only currently 
-		if (getTraitResultSet().size() > 0 )
-			_stop = true;
-	}
-
 
 	/**
 	 * Simple comparator that compares that an entity's id for with another
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleResultSet.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleResultSet.java
new file mode 100644
index 0000000..a43382c
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleResultSet.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle 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:
+ *    Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+package org.eclipse.jst.jsf.common.metadata.query.internal;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jst.jsf.common.metadata.query.AbstractResultSet;
+import org.eclipse.jst.jsf.common.metadata.query.IResultSet;
+
+/**
+ * Simple implementation of {@link IResultSet} by extending AbstractResultSet
+ *
+ */
+public final class SimpleResultSet/*<T>*/ extends AbstractResultSet/*<T>*/ {
+    // APIx: Should push down overridable functionality from AbstractResultSet
+    // and make final all functionality left in AbstractResultSet
+	
+	
+	private List/*<T>*/ results;
+	
+	/**
+	 * Constructor passing a list to hold the results
+	 * @param results 
+	 */
+	public SimpleResultSet(List/*<T>*/ results){
+		super();
+		this.results = results;
+	}
+
+
+	/**
+	 * @return List of results
+	 */
+	protected List getInternalResults(){
+		if (results == null){
+			results = new ArrayList();
+		}
+		return results;
+	}
+
+
+}
+
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleTraitQueryVisitorImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleTraitQueryVisitorImpl.java
new file mode 100644
index 0000000..41b0e56
--- /dev/null
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/query/internal/SimpleTraitQueryVisitorImpl.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle 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:
+ *    Oracle - initial API and implementation
+ *    
+ ********************************************************************************/
+package org.eclipse.jst.jsf.common.metadata.query.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jst.jsf.common.metadata.Entity;
+import org.eclipse.jst.jsf.common.metadata.Trait;
+import org.eclipse.jst.jsf.common.metadata.query.AbstractTraitQueryVisitor;
+import org.eclipse.jst.jsf.common.metadata.query.IResultSet;
+import org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor;
+
+
+/**
+ * A simple metadata query visitor implementing {@link ITraitQueryVisitor}.
+ * - simple find traits by id only 	
+ * - Does not allow for wild card searchs
+ */
+public class SimpleTraitQueryVisitorImpl extends AbstractTraitQueryVisitor  {
+
+	private String _traitQuery;
+	private SearchControl _control;
+	private boolean _stop;
+	private List/*<Trait>*/ _traitResults;
+
+	/**
+	 * Constructor that also creates a default SearchControl
+	 */
+	public SimpleTraitQueryVisitorImpl() {
+		super();
+		_control = new SearchControl();
+	}
+	
+	/**
+	 * Constructor
+	 * @param control
+	 */
+	public SimpleTraitQueryVisitorImpl(SearchControl control) {
+		super();
+		this._control = control;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.common.metadata.query.ITraitQueryVisitor#findTraits(org.eclipse.jst.jsf.common.metadata.Entity, java.lang.String)
+	 */
+	public IResultSet/*<Trait>*/ findTraits(final Entity entity, final String traitQuery){
+		
+		resetQuery();
+		if (entity != null){			
+			this._traitQuery = traitQuery;			
+			for (Iterator/*<Trait>*/ it=entity.getTraits().iterator();it.hasNext();){
+				Trait t = (Trait)it.next();
+				t.accept(this);
+				if (stopVisiting())
+					break;
+			}
+		}
+		return new SimpleResultSet(getInternalTraitResults());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.common.metadata.query.ITraitVisitor#visit(org.eclipse.jst.jsf.common.metadata.Trait)
+	 */
+	public void visit(Trait trait) {		
+		if (trait.equals(_traitQuery))
+			getInternalTraitResults().add(trait);		
+		
+		checkShouldStopVisitingTraits();
+	}
+
+	/**
+	 * 
+	 */
+	private void resetQuery() {
+		_stop = false;
+		_traitResults = null;
+	}
+
+	/**
+	 * @return lazy init of a SimpleResultSet of Traits
+	 */
+	private List/*<Trait>*/ getInternalTraitResults(){
+		if (_traitResults == null){
+			_traitResults = new ArrayList/*<Trait>*/();
+		}
+		return _traitResults;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jst.jsf.common.metadata.query.IMetaDataVisitor#stopVisiting()
+	 */
+	public boolean stopVisiting() {
+		return _stop;
+	}
+
+	private void checkShouldStopVisitingTraits(){
+		if (_control.getCountLimit()== getInternalTraitResults().size() && _control.getCountLimit() != SearchControl.COUNT_LIMIT_NONE)
+			_stop = true;
+	}
+	
+}