Index: engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java
===================================================================
--- engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java	(revision 3554)
+++ engine/src/main/java/org/teiid/dqp/internal/process/RequestWorkItem.java	(working copy)
@@ -524,7 +524,6 @@
 	    	resultsBuffer = this.processor.getBufferManager().createTupleBuffer(this.originalCommand.getProjectedSymbols(), this.request.context.getConnectionID(), TupleSourceType.FINAL);
 		}
 		analysisRecord = request.analysisRecord;
-		analysisRecord.setQueryPlan(processor.getProcessorPlan().getDescriptionProperties());
 		transactionContext = request.transactionContext;
 		if (this.transactionContext != null && this.transactionContext.getTransactionType() != Scope.NONE) {
 			this.transactionState = TransactionState.ACTIVE;
Index: engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java
===================================================================
--- engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java	(revision 3554)
+++ engine/src/main/java/org/teiid/dqp/internal/process/DQPWorkContext.java	(working copy)
@@ -54,7 +54,9 @@
 		SEVEN_1("7.1"), //$NON-NLS-1$
 		SEVEN_2("7.2"), //$NON-NLS-1$
 		SEVEN_3("7.3"), //$NON-NLS-1$
-		SEVEN_4("7.4"); //$NON-NLS-1$
+		SEVEN_4("7.4"), //$NON-NLS-1$
+		SEVEN_5("7.5"), //$NON-NLS-1$
+		SEVEN_6("7.6"); //$NON-NLS-1$
 		
 		private String string;
 		
Index: engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
===================================================================
--- engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java	(revision 3554)
+++ engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java	(working copy)
@@ -465,7 +465,7 @@
         rm = execute(userName, sessionid, reqMsg);
         assertEquals(0, rm.getResults().length); //$NON-NLS-1$
         
-        assertEquals(2, this.core.getPrepPlanCache().getCacheHitCount());
+        assertEquals(3, this.core.getPrepPlanCache().getCacheHitCount());
     }
     
     @Test public void testRsCacheInvalidation() throws Exception {
Index: engine/src/main/java/org/teiid/query/sql/symbol/Constant.java
===================================================================
--- engine/src/main/java/org/teiid/query/sql/symbol/Constant.java	(revision 3554)
+++ engine/src/main/java/org/teiid/query/sql/symbol/Constant.java	(working copy)
@@ -75,7 +75,13 @@
 	 */
 	public Constant(Object value) {
 		this.value = DataTypeManager.convertToRuntimeType(value);
-		this.type = DataTypeManager.determineDataTypeClass(this.value);
+		if (this.value == null) {
+			this.type = DataTypeManager.DefaultDataClasses.NULL;
+		} else if (DataTypeManager.getAllDataTypeClasses().contains(this.value.getClass())) {
+			this.type = this.value.getClass();
+		} else {
+			this.type = DataTypeManager.DefaultDataClasses.OBJECT; 
+		}
 	}
 
 	/**
Index: engine/src/main/java/org/teiid/dqp/internal/process/PreparedPlan.java
===================================================================
--- engine/src/main/java/org/teiid/dqp/internal/process/PreparedPlan.java	(revision 3554)
+++ engine/src/main/java/org/teiid/dqp/internal/process/PreparedPlan.java	(working copy)
@@ -29,6 +29,8 @@
 import org.teiid.common.buffer.BufferManager;
 import org.teiid.query.analysis.AnalysisRecord;
 import org.teiid.query.processor.ProcessorPlan;
+import org.teiid.query.processor.relational.AccessNode;
+import org.teiid.query.processor.relational.RelationalPlan;
 import org.teiid.query.sql.lang.Command;
 import org.teiid.query.sql.symbol.Reference;
 import org.teiid.query.util.CommandContext;
@@ -77,6 +79,13 @@
 	public void setPlan(ProcessorPlan planValue, CommandContext context){
 		plan = planValue;
 		this.accessInfo.populate(context, false);
+		//TODO: expand this logic
+		if (planValue instanceof RelationalPlan) {
+			RelationalPlan rp = (RelationalPlan)planValue;
+			if (rp.getRootNode() instanceof AccessNode) {
+				this.accessInfo.setSensitiveToMetadataChanges(false);
+			}
+		}
 	}
 	
 	/**
Index: common-core/src/main/java/org/teiid/core/types/DataTypeManager.java
===================================================================
--- common-core/src/main/java/org/teiid/core/types/DataTypeManager.java	(revision 3554)
+++ common-core/src/main/java/org/teiid/core/types/DataTypeManager.java	(working copy)
@@ -323,14 +323,20 @@
 	 * this is simply the class of the object. Some special cases are when the
 	 * value is of type Object or Null.
 	 */
-	public static Class determineDataTypeClass(Object value) {
+	public static Class<?> determineDataTypeClass(Object value) {
 		// Handle null case
 		if (value == null) {
 			return DefaultDataClasses.NULL;
 		}
-
-		return getDataTypeClass(getDataTypeName(convertToRuntimeType(value)
-				.getClass()));
+		Class<?> clazz = value.getClass();
+		if (DATA_TYPE_CLASSES.contains(clazz)) {
+			return clazz;
+		}
+		clazz = convertToRuntimeType(value).getClass();
+		if (DATA_TYPE_CLASSES.contains(clazz)) {
+			return clazz;
+		}
+		return DefaultDataClasses.OBJECT;
 	}
 
 	/**
@@ -745,7 +751,7 @@
 			return null;
 		}
 		Class<?> c = value.getClass();
-		if (getAllDataTypeClasses().contains(c)) {
+		if (DATA_TYPE_CLASSES.contains(c)) {
 			return value;
 		}
 		SourceTransform t = sourceConverters.get(c);
Index: engine/src/test/java/org/teiid/common/buffer/impl/TestSizeUtility.java
===================================================================
--- engine/src/test/java/org/teiid/common/buffer/impl/TestSizeUtility.java	(revision 3554)
+++ engine/src/test/java/org/teiid/common/buffer/impl/TestSizeUtility.java	(working copy)
@@ -35,6 +35,7 @@
 
 import org.junit.Test;
 import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.types.DataTypeManager;
 
 public class TestSizeUtility {
 
@@ -43,7 +44,7 @@
     }
 
     public void helpTestGetSize(Object obj, long expectedSize) {  
-        long actualSize = new SizeUtility().getSize(obj, true, false);
+        long actualSize = new SizeUtility().getSize(obj, DataTypeManager.determineDataTypeClass(obj), true, false);
         assertEquals("Got unexpected size: ", expectedSize, actualSize); //$NON-NLS-1$
     }
 
Index: test-integration/common/src/test/java/org/teiid/common/buffer/impl/StressTestSTree.java
===================================================================
--- test-integration/common/src/test/java/org/teiid/common/buffer/impl/StressTestSTree.java	(revision 0)
+++ test-integration/common/src/test/java/org/teiid/common/buffer/impl/StressTestSTree.java	(revision 0)
@@ -0,0 +1,121 @@
+package org.teiid.common.buffer.impl;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+import org.teiid.common.buffer.STree;
+import org.teiid.common.buffer.STree.InsertMode;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.query.sql.symbol.ElementSymbol;
+import org.teiid.services.BufferServiceImpl;
+
+public class StressTestSTree {
+	
+	static final int ThreadCount = 4;
+	
+	static volatile boolean stop;
+
+	public static void main(String[] args) throws Exception {
+		//System.setOut(new PrintStream("log.txt"));
+		BufferServiceImpl bufferService = new BufferServiceImpl();
+		//bufferService.setMemoryBufferOffHeap(true);
+		bufferService.setDiskDirectory(UnitTestUtil.getTestScratchPath());
+		bufferService.setMaxReserveKb(100000);
+		bufferService.setUseDisk(false);
+		bufferService.start();
+		
+		final BufferManagerImpl bm = (BufferManagerImpl) bufferService.getBufferManager();
+		bm.setProcessorBatchSize(128);
+		bm.setUseWeakReferences(false);
+		
+		Thread[] threads = new Thread[ThreadCount];
+		for (int j = 0; j < threads.length; j++) {
+			threads[j] = new Thread() {
+				@Override
+				public void run() {
+					try {
+						test(bm);
+					} catch (Exception e) {
+						stop = true;
+						e.printStackTrace();
+					}
+				}
+			};
+		}
+		
+		for (int j = 0; j < threads.length; j++) {
+			threads[j].start();
+		}
+		
+		for (int j = 0; j < threads.length; j++) {
+			threads[j].join();
+		}
+	}
+	
+	public static void test(final BufferManagerImpl bm) throws Exception {
+		ElementSymbol e1 = new ElementSymbol("x");
+		e1.setType(Integer.class);
+		ElementSymbol e2 = new ElementSymbol("y");
+		e2.setType(String.class);
+		ElementSymbol e3 = new ElementSymbol("z");
+		e3.setType(String.class);
+		
+		List<ElementSymbol> elements = Arrays.asList(e1, e2, e3);
+		STree map = bm.createSTree(elements, "1", 1);
+		STree map1 = bm.createSTree(elements, "1", 1);
+		
+		long start = System.currentTimeMillis();
+		
+		int size = 1 << 17;
+
+		Random r = new Random(0);
+
+		map.setBatchInsert(true);
+		map1.setBatchInsert(true);
+		for (int i = 0; i < size; i++) {
+			assertNull(map.insert(Arrays.asList(i, String.valueOf(r.nextLong()), String.valueOf(r.nextLong())), InsertMode.ORDERED, size));
+			assertNull(map1.insert(Arrays.asList(i, String.valueOf(r.nextLong()), String.valueOf(r.nextLong())), InsertMode.ORDERED, size));
+		}
+		map1.setBatchInsert(false);
+		map.setBatchInsert(false);
+		System.out.println(map.getRowCount() + " " + (System.currentTimeMillis() - start));
+		System.out.println(bm.getBatchesAdded() + " " +bm.getWriteCount() + " " + bm.getReadCount());
+
+		for (int i = 0; i < size; i++) {
+			if (stop) {
+				return;
+			}
+			map.remove(Arrays.asList(r.nextInt()%map.getRowCount()));
+			map.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map.insert(Arrays.asList(i, String.valueOf(r.nextLong()), String.valueOf(r.nextLong())), InsertMode.NEW, -1);
+			map.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map1.remove(Arrays.asList(r.nextInt()%map.getRowCount()));
+			map1.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map1.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			map1.insert(Arrays.asList(i, String.valueOf(r.nextLong()), String.valueOf(r.nextLong())), InsertMode.NEW, -1);
+			for (int j = 0; j < 20; j++) {
+				map1.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+				map.find(Arrays.asList(r.nextInt()%(map.getRowCount()/4)));
+			}
+			if ((i&0x1fff) == 0) {
+/*				BufferFrontedFileStoreCache cache = (BufferFrontedFileStoreCache) bm.getCache();
+				System.out.println(i + " " + cache.getInodesInUse() + " " + cache.getDataBlocksInUse() + " " + cache.memoryBufferEntries.getEvictionQueue().size() + " " + bm.evictionQueue.getEvictionQueue().size() + " " + bm.getMemoryCacheEntries());
+				System.out.println(cache.getStorageWrites() + " " + cache.getStorageReads());
+*/
+				System.out.println(i+ " " + bm.getBatchesAdded() + " " +bm.getWriteCount() + " " + bm.getReadCount());
+			}
+		}
+		
+		System.out.println(map.getRowCount() + " " + (System.currentTimeMillis() - start));
+		//BufferFrontedFileStoreCache cache = (BufferFrontedFileStoreCache) bm.getCache();
+		//System.out.println(cache.getInodesInUse() + " " + cache.getDataBlocksInUse() + " " + cache.memoryBufferEntries.getEvictionQueue().size() + " " + bm.evictionQueue.getEvictionQueue().size() + " " + bm.getMemoryCacheEntries());
+		System.out.println(bm.getBatchesAdded() + " " +bm.getWriteCount() + " " + bm.getReadCount());
+		//System.out.println(cache.getStorageWrites() + " " + cache.getStorageReads());
+	}	
+
+}
Index: engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java
===================================================================
--- engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java	(revision 3554)
+++ engine/src/main/java/org/teiid/query/metadata/TempMetadataID.java	(working copy)
@@ -62,13 +62,17 @@
 		List<List<TempMetadataID>> keys;
 		List<List<TempMetadataID>> indexes;
 		long lastDataModification;
-		long lastModified;
+		long lastModified = System.currentTimeMillis();
 		int modCount;
 		
 		public long getLastDataModification() {
 			return lastDataModification;
 		}
 		
+		public void removed() {
+			this.lastModified = -1;
+		}
+		
 		public void dataModified(int updateCount) {
 			if (updateCount == 0) {
 				return;
Index: engine/src/main/java/org/teiid/query/tempdata/TempTable.java
===================================================================
--- engine/src/main/java/org/teiid/query/tempdata/TempTable.java	(revision 3566)
+++ engine/src/main/java/org/teiid/query/tempdata/TempTable.java	(working copy)
@@ -485,6 +485,7 @@
 	
 	public void remove() {
 		tree.remove();
+		this.tid.getTableData().removed();
 		if (this.indexTables != null) {
 			for (TempTable indexTable : this.indexTables.values()) {
 				indexTable.remove();
Index: engine/src/main/java/org/teiid/dqp/internal/process/AccessInfo.java
===================================================================
--- engine/src/main/java/org/teiid/dqp/internal/process/AccessInfo.java	(revision 3554)
+++ engine/src/main/java/org/teiid/dqp/internal/process/AccessInfo.java	(working copy)
@@ -52,7 +52,7 @@
 	private static final long serialVersionUID = -2608267960584191359L;
 	
 	private transient Set<Object> objectsAccessed;
-	
+	private boolean sensitiveToMetadataChanges = true;
 	private List<List<String>> externalNames;
 	
 	private transient long creationTime = System.currentTimeMillis();
@@ -67,6 +67,14 @@
 		this.creationTime = System.currentTimeMillis();
 	}
 	
+	public boolean isSensitiveToMetadataChanges() {
+		return sensitiveToMetadataChanges;
+	}
+	
+	public void setSensitiveToMetadataChanges(boolean sensitiveToMetadataChanges) {
+		this.sensitiveToMetadataChanges = sensitiveToMetadataChanges;
+	}
+	
 	private static List<List<String>> initExternalList(List<List<String>> externalNames, Set<? extends Object> accessed) {
 		if (externalNames == null) {
 			externalNames = new ArrayList<List<String>>(accessed.size());
@@ -153,8 +161,14 @@
 		}
 		for (Object o : this.objectsAccessed) {
 			if (!data) {
-				if (o instanceof Modifiable && ((Modifiable)o).getLastModified() - modTime > this.creationTime) {
-					return false;
+				if (o instanceof Modifiable) {
+					Modifiable m = (Modifiable)o;
+					if (m.getLastModified() < 0) {
+						return false; //invalid object
+					}
+					if (sensitiveToMetadataChanges && m.getLastModified() - modTime > this.creationTime) {
+						return false;
+					}
 				}
 			} else if (o instanceof DataModifiable && ((DataModifiable)o).getLastDataModification() - modTime > this.creationTime) {
 				return false;
Index: engine/src/main/java/org/teiid/common/buffer/impl/SizeUtility.java
===================================================================
--- engine/src/main/java/org/teiid/common/buffer/impl/SizeUtility.java	(revision 3554)
+++ engine/src/main/java/org/teiid/common/buffer/impl/SizeUtility.java	(working copy)
@@ -68,14 +68,13 @@
             		|| type == DataTypeManager.DefaultDataClasses.OBJECT
             		|| type == DataTypeManager.DefaultDataClasses.BIG_INTEGER
             		|| type == DataTypeManager.DefaultDataClasses.BIG_DECIMAL) {
-            	int estRow = 0;
-                for (int row = 0; row < rowLength; row++) {
-                	boolean updateEst = row == estRow;
-                    size += getSize(data.getTuples().get(row).get(col), updateEst, accountForValueCache);
-                    if (updateEst) {
-                    	estRow = estRow * 2 + 1;
-                    }
+            	int rowsSampled = 0;
+            	int estimatedSize = 0;
+                for (int row = 0; row < rowLength; row=row*2+1) {
+                	rowsSampled++;
+                	estimatedSize += getSize(data.getTuples().get(row).get(col), type, true, accountForValueCache);
                 }
+                size += estimatedSize/(float)rowsSampled * rowLength;
             } else {
             	size += getSize(accountForValueCache, type) * rowLength;
             }
@@ -121,25 +120,17 @@
      * Get size of object
      * @return Size in bytes
      */
-    protected long getSize(Object obj, boolean updateEstimate, boolean accountForValueCache) {
+    protected long getSize(Object obj, Class<?> type, boolean updateEstimate, boolean accountForValueCache) {
         if(obj == null) {
             return 0;
         }
 
-        Class<?> type = DataTypeManager.determineDataTypeClass(obj);
         if(type == DataTypeManager.DefaultDataClasses.STRING) {
             int length = ((String)obj).length();
             if (length > 0) {
                 return alignMemory(40 + (2 * length));
             }
             return 40;
-        } else if(obj instanceof Iterable<?>) {
-        	Iterable<?> i = (Iterable<?>)obj;
-        	long total = 16;
-        	for (Object object : i) {
-				total += getSize(object, true, false) + REFERENCE_SIZE;
-			}
-        	return total;
         } else if(type == DataTypeManager.DefaultDataClasses.BIG_DECIMAL) {
         	if (!updateEstimate) {
         		return bigDecimalEstimate;
@@ -161,13 +152,20 @@
             	bigIntegerEstimate = (bigIntegerEstimate + result)/2;
             }
             return result;
+        } else if(obj instanceof Iterable<?>) {
+        	Iterable<?> i = (Iterable<?>)obj;
+        	long total = 16;
+        	for (Object object : i) {
+				total += getSize(object, DataTypeManager.determineDataTypeClass(object), true, false) + REFERENCE_SIZE;
+			}
+        	return total;
         } else if(obj.getClass().isArray()) {
         	Class<?> componentType = obj.getClass().getComponentType(); 
         	if (!componentType.isPrimitive()) {
 	            Object[] rows = (Object[]) obj;
 	            long total = 16 + alignMemory(rows.length * REFERENCE_SIZE); // Array overhead
 	            for(int i=0; i<rows.length; i++) {
-	                total += getSize(rows[i], true, false);
+	                total += getSize(rows[i], DataTypeManager.determineDataTypeClass(rows[i]), true, false);
 	            }
 	            return total;
         	}
