Merge branch '0.42.1_staging'
diff --git a/org.eclipse.ote.connect.server.test/META-INF/MANIFEST.MF b/org.eclipse.ote.connect.server.test/META-INF/MANIFEST.MF
index 521508c..e0da635 100644
--- a/org.eclipse.ote.connect.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.ote.connect.server.test/META-INF/MANIFEST.MF
@@ -7,6 +7,5 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Require-Bundle: org.junit,
  org.eclipse.equinox.event;bundle-version="1.2.200"
-Import-Package: org.eclipse.osee.ote.server,
- org.osgi.framework;version="1.7.0",
+Import-Package: org.osgi.framework;version="1.7.0",
  org.osgi.service.packageadmin;version="1.2.0"
diff --git a/org.eclipse.ote.io.test/.classpath b/org.eclipse.ote.io.test/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/org.eclipse.ote.io.test/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.ote.io.test/.project b/org.eclipse.ote.io.test/.project
new file mode 100644
index 0000000..a637b88
--- /dev/null
+++ b/org.eclipse.ote.io.test/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.ote.io.test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.ote.io.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.ote.io.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c537b63
--- /dev/null
+++ b/org.eclipse.ote.io.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.eclipse.ote.io.test/META-INF/MANIFEST.MF b/org.eclipse.ote.io.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..3e6c48a
--- /dev/null
+++ b/org.eclipse.ote.io.test/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: OTE IO Test
+Bundle-SymbolicName: org.eclipse.ote.io.test
+Bundle-Version: 0.11.0.qualifier
+Fragment-Host: org.eclipse.ote.io;bundle-version="0.11.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.junit
diff --git a/org.eclipse.ote.io.test/build.properties b/org.eclipse.ote.io.test/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/org.eclipse.ote.io.test/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/org.eclipse.ote.io.test/pom.xml b/org.eclipse.ote.io.test/pom.xml
new file mode 100644
index 0000000..71833ed
--- /dev/null
+++ b/org.eclipse.ote.io.test/pom.xml
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.eclipse.ote</groupId>
+		<artifactId>org.eclipse.ote.parent</artifactId>
+		<version>0.11.0-SNAPSHOT</version>
+		<relativePath>../org.eclipse.ote.parent</relativePath>
+	</parent>
+
+	<artifactId>org.eclipse.ote.io.test</artifactId>
+	<packaging>eclipse-test-plugin</packaging>
+	<name>Eclipse OTE IO Test (Incubation)</name>
+ <!--
+   <build>
+     workaround for https://issues.sonatype.org/browse/TYCHO-168 
+     <resources>
+      <resource>
+        <directory>src</directory>
+        <excludes>
+          <exclude>**/*.java</exclude>
+        </excludes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-source-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+  -->
+</project>
\ No newline at end of file
diff --git a/org.eclipse.ote.io.test/src/org/eclipse/ote/io/CircularBufferTest.java b/org.eclipse.ote.io.test/src/org/eclipse/ote/io/CircularBufferTest.java
new file mode 100644
index 0000000..30571b2
--- /dev/null
+++ b/org.eclipse.ote.io.test/src/org/eclipse/ote/io/CircularBufferTest.java
@@ -0,0 +1,147 @@
+package org.eclipse.ote.io;
+
+import junit.framework.Assert;
+
+import org.eclipse.ote.io.CircularBuffer;
+import org.junit.Test;
+
+public class CircularBufferTest {
+
+   @Test
+   public void test() {
+      
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(5);
+      
+      for(int i = 1; i <= 5; i++){
+         buffer.add(i);
+      }
+      
+      for(int i = 1; i <= 5; i++){
+         Assert.assertEquals(i, buffer.remove().intValue());
+      }
+      
+      Assert.assertNull(buffer.remove());
+   
+   }
+   
+   @Test
+   public void testHead() {
+      
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(5);
+      
+      for(int i = 1; i <= 5; i++){
+         buffer.add(i);
+      }
+      
+      Assert.assertEquals(5, buffer.head().intValue());
+      
+   }
+   
+   @Test
+   public void testWrap() {
+
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(5);
+      
+      for(int i = 1; i <= 10; i++){
+         buffer.add(i);
+      }
+      for(int i = 6; i <= 10; i++){
+         Assert.assertEquals(i, buffer.remove().intValue());
+      }
+      
+      buffer.clear();
+      for(int i = 1; i <= 20; i++){
+         buffer.add(i);
+      }
+      for(int i = 16; i <= 20; i++){
+         Assert.assertEquals(i, buffer.remove().intValue());
+      }
+      for(int i = 21; i <= 23; i++){
+         buffer.add(i);
+      }
+      
+      Integer[] copy = new Integer[5];
+      copy = buffer.getCopy(Integer.class);
+      Assert.assertEquals(3, copy.length);
+      for(int i = 0; i < copy.length; i++){
+         Assert.assertEquals(21+i, copy[i].intValue());   
+      }
+      
+      buffer.clear();
+      
+      for(int i = 1; i <= 8; i++){
+         buffer.add(i);
+      }
+      copy = new Integer[5];
+      copy = buffer.getCopy(Integer.class);
+      Assert.assertEquals(5, copy.length);
+      for(int i = 0; i < copy.length; i++){
+         Assert.assertEquals(4+i, copy[i].intValue());   
+      }
+   }
+
+   @Test
+   public void testArrayAdd() {
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(20);
+      
+      addArray(buffer, 1, 1, 6);
+      addArray(buffer, 7, 1, 12);
+      addArray(buffer, 13, 1, 18);
+      addArray(buffer, 19, 5, 20);
+      addArray(buffer, 25, 11, 20);
+      addArray(buffer, 31, 17, 20);
+      addArray(buffer, 37, 23, 20);
+      addArray(buffer, 43, 29, 20);
+      
+   }
+   
+   @Test
+   public void testArrayAdd2() {
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(6);
+      
+      addArray(buffer, 1, 1, 6);
+      addArray(buffer, 7, 7, 6);
+      addArray(buffer, 13, 13, 6);
+      addArray(buffer, 19, 19, 6);
+      addArray(buffer, 25, 25, 6);
+      addArray(buffer, 31, 31, 6);
+      addArray(buffer, 37, 37, 6);
+      addArray(buffer, 43, 43, 6);
+      
+   }
+   
+   @Test
+   public void testException() {
+      CircularBuffer<Integer> buffer = new CircularBuffer<Integer>(4);
+      boolean exception = false;
+      try{
+         addArray(buffer, 1, 1, 6);
+      } catch (IllegalArgumentException ex){
+         exception = true;
+      }
+      Assert.assertTrue(exception);
+   }
+   
+   private void addArray(CircularBuffer<Integer> buffer, int offset, int offset2, int size){
+      Integer[] newData = new Integer[6];
+      for(int i = 0; i < newData.length; i++){
+         newData[i] = i+offset;
+      }
+      
+      Integer[] older = buffer.add(newData, 0, newData.length);
+      if(size < buffer.getTotalSize()){
+         Assert.assertEquals(0, older.length);
+      } else {
+         Assert.assertEquals(Math.min((offset+(newData.length-1)) - buffer.getTotalSize(), 6),older.length);
+         int olderOffset = Math.max(1, offset2-older.length);
+         for(int i = 0; i < older.length; i++){
+            Assert.assertEquals(i + olderOffset, older[i].intValue());   
+         }
+      }
+      Integer[] copy = buffer.getCopy(Integer.class);
+      Assert.assertEquals(size, copy.length);
+      for(int i = 0; i < copy.length; i++){
+         Assert.assertEquals(i + offset2, copy[i].intValue());   
+      }
+   }
+}
diff --git a/org.eclipse.ote.io/src/org/eclipse/ote/io/CircularBuffer.java b/org.eclipse.ote.io/src/org/eclipse/ote/io/CircularBuffer.java
new file mode 100644
index 0000000..3b47ab6
--- /dev/null
+++ b/org.eclipse.ote.io/src/org/eclipse/ote/io/CircularBuffer.java
@@ -0,0 +1,184 @@
+package org.eclipse.ote.io;
+
+import java.lang.reflect.Array;
+import java.util.logging.Level;
+
+import org.eclipse.osee.framework.logging.OseeLog;
+
+/**
+ * This class implements a circular buffer backed by an Object[].  It is useful for high IO application that 
+ * have high throughput.  It is not thread-safe, synchronization must be handled externally. 
+ * 
+ * @author Andrew M. Finkbeiner
+ *
+ * @param <T>
+ */
+public class CircularBuffer<T> {
+   
+   private static final String SIZE_COPY_ERROR__BUFFERSIZE__ADDEDSIZE = "Cannot copy array of size[%d] into circular buffer of size[%d]";
+   
+   private int head = -1;
+   private int tail = -1;
+   private int size;
+   private Object[] data;
+   
+   public CircularBuffer(int limit) {
+      size = limit;
+      data = new Object[limit];
+   }
+   
+   public T add(T entry){
+      T returnValue = null;
+      if(hasData() && isHeadPassingTail(1)){
+         returnValue = remove();
+      }
+      data[incrementAndGetHead()] = entry;
+      if(tail == -1){
+         tail = 0;
+      }
+      return returnValue;
+   }
+
+   @SuppressWarnings("unchecked")
+   public T[] add(T[] entry, int offset, int lengthToCopy){
+      if(lengthToCopy > size){
+         throw new IllegalArgumentException(String.format(SIZE_COPY_ERROR__BUFFERSIZE__ADDEDSIZE, lengthToCopy, size));
+      }
+      T[] returnValue = null;
+      if(hasData() && isHeadPassingTail(lengthToCopy)){
+         returnValue = getCopy(entry.getClass().getComponentType(), tail, lengthToCopy - getRemaining());
+         tail += returnValue.length;
+         if(tail > size){
+            tail-=size;
+         }
+      }
+      
+      int toEnd = (head == -1 ? size : (size) - (head+1));
+      if(toEnd >= lengthToCopy){
+         try{
+            System.arraycopy(entry, offset, data, head+1, lengthToCopy);
+            head+=lengthToCopy;
+         } catch (ArrayIndexOutOfBoundsException ex){
+            OseeLog.log(getClass(), Level.SEVERE, String.format("offset[%d], offset2[%d], length[%d] sourcesz[%d] destsz[%d]", offset, head+1, lengthToCopy, entry.length, data.length));
+         }
+      } else {
+         try{
+            System.arraycopy(entry, offset, data, head+1, toEnd);
+         } catch (ArrayIndexOutOfBoundsException ex){
+            OseeLog.log(getClass(), Level.SEVERE, String.format("offset[%d], offset2[%d], length[%d] sourcesz[%d] destsz[%d]", offset, head+1, toEnd, entry.length, data.length));
+         }
+         int left = (lengthToCopy - toEnd);
+         try{
+            System.arraycopy(entry, offset+toEnd, data, 0, left);
+         } catch (ArrayIndexOutOfBoundsException ex){
+            OseeLog.log(getClass(), Level.SEVERE, String.format("offset[%d], offset2[%d], length[%d] sourcesz[%d] destsz[%d]", offset+toEnd, 0, left, entry.length, data.length));
+         }
+         head = left-1;
+      }
+      if(tail == -1){
+         tail = 0;
+      }
+      if(returnValue == null){
+         returnValue = (T[]) Array.newInstance(entry.getClass().getComponentType(), 0);
+      }
+      return returnValue;
+   }
+   
+   private boolean isHeadPassingTail(int sizeToAdd) {
+      if(sizeToAdd == size){
+         return true;
+      }
+      return sizeToAdd > getRemaining();
+   }
+   
+   private int getRemaining(){
+      return head >= tail ? (size -1) - head + tail: tail - (head + 1);
+   }
+
+   private boolean hasData() {
+      if(head > -1 && tail > -1){
+         return true;
+      }
+      return false;
+   }
+
+   private int incrementAndGetHead() {
+      head++;
+      if(head == size){
+         head = 0;
+      }
+      return head;
+   }
+
+   @SuppressWarnings("unchecked")
+   public T head() {
+      return (T)data[head];
+   }
+
+   @SuppressWarnings("unchecked")
+   public T[] getCopy(Class<?> clazz) {
+      int currentSize = getSize();
+      T[] copy = (T[]) Array.newInstance(clazz, currentSize);
+      if(currentSize > 0){
+         if(head >= tail){
+            System.arraycopy(data, tail, copy, 0, currentSize);
+         } else {
+            System.arraycopy(data, tail, copy, 0, size-tail);
+            System.arraycopy(data, 0, copy, size-tail, head + 1);
+         }
+      }
+      return copy;
+   }
+   
+   @SuppressWarnings("unchecked")
+   private T[] getCopy(Class<?> clazz, int offset, int length){
+      T[] copy = (T[]) Array.newInstance(clazz, length);
+      if(offset + length > data.length){
+         int firstCopyLength = size-offset;
+         System.arraycopy(data, offset, copy, 0, firstCopyLength);
+         int remaining = length - firstCopyLength;
+         System.arraycopy(data, 0, copy, firstCopyLength, remaining);
+      } else {
+         System.arraycopy(data, offset, copy, 0, length);
+      }
+      return copy;
+   }
+   
+   private int getSize() {
+      if(head == -1 && tail == -1){
+         return 0;
+      } else if(head > tail){
+         return head - tail + 1;
+      } else {
+         return size - tail + head + 1;
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   public T remove(){
+      T value = null;
+      if(tail > -1){
+         value = (T)data[tail];
+         if(tail == head){
+            tail = -1;
+            head = -1;
+         } else {
+            tail++;
+            if(tail == size){
+               tail = 0;
+            }
+         }
+      }
+      return value;
+   }
+   
+   public void clear() {
+      head = -1;
+      tail = -1;
+   }
+
+   public int getTotalSize() {
+      return size;
+   }
+   
+}
diff --git a/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java b/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
index 942acf8..9ac6ece 100644
--- a/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
+++ b/org.eclipse.ote.io/src/org/eclipse/ote/io/DatagramChannelRunnable.java
@@ -18,9 +18,12 @@
 	private LinkedBlockingQueue<DatagramChannelData> data;
 	private InetSocketAddress address;   
 
-	DatagramChannelRunnable(InetSocketAddress address){
+	public DatagramChannelRunnable(InetSocketAddress address){
 		this.address = address;
 	}
+	
+	public DatagramChannelRunnable(){
+   }
 
 	void setQueue(LinkedBlockingQueue<DatagramChannelData> data) {
 		this.data = data;
diff --git a/org.eclipse.ote.mavenbuild/pom.xml b/org.eclipse.ote.mavenbuild/pom.xml
index 5fc0e1c..099ea94 100644
--- a/org.eclipse.ote.mavenbuild/pom.xml
+++ b/org.eclipse.ote.mavenbuild/pom.xml
@@ -11,8 +11,8 @@
 
 	<properties>
 		<build-alias>-DEV</build-alias>
-		<tycho-version>0.17.0</tycho-version>
-		<tychoExtrasVersion>0.17.0</tychoExtrasVersion>
+		<tycho-version>0.18.0</tycho-version>
+		<tychoExtrasVersion>0.18.0</tychoExtrasVersion>
 		<platform-version-name>juno</platform-version-name>
 		<orbit-version>R20120119162704</orbit-version>
 		<orbit-site>http://download.eclipse.org/tools/orbit/downloads/drops/${orbit-version}/repository</orbit-site>
diff --git a/org.eclipse.ote.parent/pom.xml b/org.eclipse.ote.parent/pom.xml
index b28e39f..69c6b5c 100644
--- a/org.eclipse.ote.parent/pom.xml
+++ b/org.eclipse.ote.parent/pom.xml
@@ -26,6 +26,7 @@
 	   <module>../org.eclipse.ote.connect.server.test</module>
 	   <module>../org.eclipse.ote.event.bridge.jms</module>
 		<module>../org.eclipse.ote.io</module>
+		<module>../org.eclipse.ote.io.test</module>
 	   <module>../org.eclipse.ote.jms.node</module>
 		<module>../org.eclipse.ote.services.core</module>
 		<module>../org.eclipse.ote.statemachine</module>
diff --git a/org.eclipse.ote.ui.eviewer/META-INF/MANIFEST.MF b/org.eclipse.ote.ui.eviewer/META-INF/MANIFEST.MF
index 1a6eef0..69f2fb2 100644
--- a/org.eclipse.ote.ui.eviewer/META-INF/MANIFEST.MF
+++ b/org.eclipse.ote.ui.eviewer/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Export-Package: org.eclipse.ote.ui.eviewer.view
 Import-Package: org.eclipse.osee.framework.jdk.core.persistence,
+ org.eclipse.ote.io,
  org.eclipse.ote.message.lookup,
  org.eclipse.ote.ui.message.util
 Service-Component: OSGI-INF/*.xml
diff --git a/org.eclipse.ote.ui.eviewer/icons/pause.gif b/org.eclipse.ote.ui.eviewer/icons/pause.gif
new file mode 100644
index 0000000..d645fa5
--- /dev/null
+++ b/org.eclipse.ote.ui.eviewer/icons/pause.gif
Binary files differ
diff --git a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/action/PauseUpdatesAction.java b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/action/PauseUpdatesAction.java
new file mode 100644
index 0000000..86652e6
--- /dev/null
+++ b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/action/PauseUpdatesAction.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Boeing.
+ * 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:
+ *     Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ote.ui.eviewer.action;
+
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ote.ui.eviewer.Activator;
+import org.eclipse.ote.ui.eviewer.view.ElementContentProvider;
+
+public class PauseUpdatesAction extends Action {
+	private final ElementContentProvider elementContentProvider;
+
+//private boolean test = true;
+	
+	public PauseUpdatesAction(ElementContentProvider elementContentProvider) {
+		super("Pause Updates", IAction.AS_CHECK_BOX);
+		this.elementContentProvider = elementContentProvider;
+		setImageDescriptor(Activator.getImageDescriptor("icons/pause.gif"));
+	}
+
+	@Override
+	public void run() {
+	   elementContentProvider.togglePauseUpdates();
+//	   test = !test;
+//	   elementContentProvider.setUpdateView(test);
+	}
+
+}
diff --git a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementContentProvider.java b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementContentProvider.java
index ec4f37b..334a6cc 100644
--- a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementContentProvider.java
+++ b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementContentProvider.java
@@ -25,6 +25,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Level;
 
 import org.eclipse.jface.viewers.IStructuredContentProvider;
@@ -60,6 +61,8 @@
 	private HashMap<ElementColumn, Integer> valueMap = new HashMap<ElementColumn, Integer>();
 
 	private ElementUpdate last = null;
+   private ReentrantLock streamWriteLock = new ReentrantLock();
+   private volatile boolean acceptUpdates = true;
 	
 	public ElementContentProvider(int limit) {
 		this.limit = limit;
@@ -78,6 +81,10 @@
 		}
 		disposeAllColumns();
 	}
+	
+	public void forceUpdate(){
+	   refresher.forceUpdate();
+	}
 
 	@Override
 	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
@@ -161,33 +168,40 @@
 
 	@Override
 	public  synchronized void update(SubscriptionDetails details) {
-		final ElementUpdate update;
-		if (last == null) {
-			update = new ElementUpdate(valueMap, elementColumns);
-		} else {
-			update = last.next(valueMap, elementColumns);
-		}
-		last = update;
-		refresher.addUpdate(update);
-		writeToStream(update);
+	   if(acceptUpdates ){
+	      final ElementUpdate update;
+	      if (last == null) {
+	         update = new ElementUpdate(valueMap, elementColumns);
+	      } else {
+	         update = last.next(valueMap, elementColumns);
+	      }
+	      last = update;
+	      refresher.addUpdate(update);
+	      writeToStream(update);
+	   }
 	}
 
 	private void writeToStream(ElementUpdate update) {
-		if (streamToFileWriter != null) {
-			int i;
-			for (i = 0; i < elementColumns.size() - 1; i++) {
-				Object o = update.getValue(elementColumns.get(i));
-				if (o != null) {
-					streamToFileWriter.append(o.toString());
-				}
-				streamToFileWriter.append(',');
-			}
-			Object o = update.getValue(elementColumns.get(i));
-			if (o != null) {
-				streamToFileWriter.append(o.toString());
-			}
-			streamToFileWriter.append('\n');
-		}
+	   try{
+	      streamWriteLock.lock();
+	      if (streamToFileWriter != null) {
+	         int i;
+	         for (i = 0; i < elementColumns.size() - 1; i++) {
+	            Object o = update.getValue(elementColumns.get(i));
+	            if (o != null) {
+	               streamToFileWriter.append(o.toString());
+	            }
+	            streamToFileWriter.append(',');
+	         }
+	         Object o = update.getValue(elementColumns.get(i));
+	         if (o != null) {
+	            streamToFileWriter.append(o.toString());
+	         }
+	         streamToFileWriter.append('\n');
+	      }
+	   } finally {
+	      streamWriteLock.unlock();
+	   }
 	}
 
 	public void clearAllUpdates() {
@@ -400,33 +414,36 @@
 		}
 	}
 
-	public synchronized void streamToFile(File file) throws FileNotFoundException, IOException {
+	public void streamToFile(File file) throws FileNotFoundException, IOException {
+	   try{
+	      streamWriteLock.lock();
+	      if (streamToFileWriter != null) {
+	         // stop streaming
+	         streamToFileWriter.flush();
+	         streamToFileWriter.close();
+	         streamToFileWriter = null;
+	      }
+	      if (file == null) {
+	         setMoveableColumns(true);
+	         return;
+	      }
+	      setMoveableColumns(false);
 
-		if (streamToFileWriter != null) {
-			// stop streaming
-			streamToFileWriter.flush();
-			streamToFileWriter.close();
-			streamToFileWriter = null;
-		}
-		if (file == null) {
-			setMoveableColumns(true);
-			return;
-		}
-		setMoveableColumns(false);
+	      streamToFileWriter = new PrintWriter(new FileOutputStream(file));
+	      int i;
+	      for (i = 0; i < elementColumns.size() - 1; i++) {
+	         streamToFileWriter.write(elementColumns.get(i).getName());
+	         streamToFileWriter.write(',');
+	      }
+	      if (elementColumns.size() > 0) {
+	         streamToFileWriter.write(elementColumns.get(i).getName());
+	         streamToFileWriter.write('\n');
+	      }
 
-		streamToFileWriter = new PrintWriter(new FileOutputStream(file));
-		int i;
-		for (i = 0; i < elementColumns.size() - 1; i++) {
-			streamToFileWriter.write(elementColumns.get(i).getName());
-			streamToFileWriter.write(',');
-		}
-		if (elementColumns.size() > 0) {
-			streamToFileWriter.write(elementColumns.get(i).getName());
-			streamToFileWriter.write('\n');
-		}
-
-		streamToFileWriter.flush();
-
+	      streamToFileWriter.flush();
+	   } finally {
+	      streamWriteLock.unlock();
+	   }
 	}
 
 	private void setMoveableColumns(boolean moveable) {
@@ -454,4 +471,12 @@
 	public TableViewer getViewer() {
 		return viewer;
 	}
+
+   public void setUpdateView(boolean updateView) {
+      refresher.setUpdateView(updateView);
+   }
+
+   public void togglePauseUpdates() {
+      acceptUpdates = !acceptUpdates;
+   }
 }
diff --git a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementViewer.java b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementViewer.java
index 3dd0893..b33b381 100644
--- a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementViewer.java
+++ b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ElementViewer.java
@@ -33,6 +33,7 @@
 import org.eclipse.ote.ui.eviewer.action.ConfigureColumnsAction;
 import org.eclipse.ote.ui.eviewer.action.CopyAllAction;
 import org.eclipse.ote.ui.eviewer.action.OpenNewElementViewer;
+import org.eclipse.ote.ui.eviewer.action.PauseUpdatesAction;
 import org.eclipse.ote.ui.eviewer.action.RemoveColumnAction;
 import org.eclipse.ote.ui.eviewer.action.SaveLoadAction;
 import org.eclipse.ote.ui.eviewer.action.SetActiveColumnAction;
@@ -69,6 +70,7 @@
 	private AddHeaderElementAction addHeaderElementAction;
 	private ClearAllUpdatesAction clearAllUpdatesAction;
 	private ToggleAutoRevealAction toggleAutoRevealAction;
+	private PauseUpdatesAction pauseUpdatesAction;
 	private RemoveColumnAction removeColumnAction;
 	private CopyAllAction copyAction;
 	private SetActiveColumnAction activeColumnAction;
@@ -102,6 +104,9 @@
 		viewer.getTable().setLinesVisible(true);
 
 
+//		viewer.setPreserveSelection(false);
+		
+		
 		makeActions();
 		hookContextMenu();
 		hookDoubleClickAction();
@@ -160,6 +165,7 @@
 		manager.add(clearAllUpdatesAction);
 		manager.add(toggleAutoRevealAction);
 		manager.add(saveLoadAction);
+		manager.add(pauseUpdatesAction);
 		manager.add(streamToFileAction);
 		manager.add(new OpenNewElementViewer());
 	}
@@ -181,6 +187,7 @@
 				elementContentProvider);
 		configureColumnAction = new ConfigureColumnsAction(
 				elementContentProvider);
+		pauseUpdatesAction = new PauseUpdatesAction(elementContentProvider);
 	}
 
 	private void hookDoubleClickAction() {
@@ -238,10 +245,9 @@
 				addElementAction.setEnabled(false);
 				addHeaderElementAction.setEnabled(false);
 				removeColumnAction.setEnabled(false);
-				if (disableRendering) {
-					viewer.getTable().update();
-					viewer.getTable().setRedraw(false);
-				}
+				
+				elementContentProvider.setUpdateView(!disableRendering);
+				
 			}
 		};
 		if (display.getThread() != Thread.currentThread()) {
@@ -259,9 +265,9 @@
 			@Override
 			public void run() {
 				try {
-					viewer.getTable().update();
-					viewer.getTable().setRedraw(true);		
+				   elementContentProvider.forceUpdate();
 					elementContentProvider.streamToFile(null);
+					elementContentProvider.setUpdateView(true);
 					configureColumnAction.setEnabled(true);
 					addElementAction.setEnabled(true);
 					addHeaderElementAction.setEnabled(true);
@@ -320,5 +326,5 @@
 	public void addElement(ElementPath elementPath){
 		elementContentProvider.add(elementPath);
 	}
-	
+
 }
\ No newline at end of file
diff --git a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ViewRefresher.java b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ViewRefresher.java
index 6343032..fdaa2d4 100644
--- a/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ViewRefresher.java
+++ b/org.eclipse.ote.ui.eviewer/src/org/eclipse/ote/ui/eviewer/view/ViewRefresher.java
@@ -11,8 +11,15 @@
 package org.eclipse.ote.ui.eviewer.view;
 
 import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Level;
+
 import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.osee.framework.logging.OseeLog;
 import org.eclipse.osee.framework.ui.swt.PeriodicDisplayTask;
+import org.eclipse.ote.io.CircularBuffer;
 
 /**
  * @author Ken J. Aguilar
@@ -20,74 +27,97 @@
 public class ViewRefresher extends PeriodicDisplayTask {
 
    private final TableViewer viewer;
-   private final ElementUpdate[] updates;
-   private int updateAppendIndex = 0;
    private ElementUpdate[] incomingUpdates = new ElementUpdate[2048];
+   
    private int incomingCount = 0;
    private boolean autoReveal = true;
-   private boolean updatesWrappedAround = false;
+   
+   private ReentrantLock lock;
+   private Condition clearIncomingUpdates;
+   private CircularBuffer<ElementUpdate> updatesNew;
+   private volatile boolean updateView = true;
+   
    public ViewRefresher(TableViewer viewer, int limit) {
       super(viewer.getTable().getDisplay(), 333);
+      lock = new ReentrantLock();
+      clearIncomingUpdates = lock.newCondition();
+      
+      updatesNew = new CircularBuffer<ElementUpdate>(limit);
+      
       this.viewer = viewer;
-      this.updates = new ElementUpdate[limit];
    }
 
    @Override
-   protected synchronized void update() {
-      if (incomingCount == 0) {
-         return;
-      }
-      viewer.getTable().setRedraw(false);
-      int newTotal = updateAppendIndex + incomingCount;
-      if (newTotal > updates.length) {
-         // remove the oldest updates from the viewer
-         int numberToRemove = newTotal - updates.length;
-         viewer.remove(Arrays.copyOfRange(updates, 0, numberToRemove));
-         
-         // the updates array is now wrapping around since we surpassed the arrays capacity
-         updatesWrappedAround = true;
-         
-         // find how much capacity with have remaining before we wrap
-         int remaining = updates.length - updateAppendIndex;
-         // fill the remaining portion of the updates array with the incoming 
-         System.arraycopy(incomingUpdates, 0, updates, updateAppendIndex, remaining);
-         // wrap around and fill the part of the updates array that got removed
-         System.arraycopy(incomingUpdates, remaining, updates, 0, numberToRemove);
-         updateAppendIndex = numberToRemove;
-      } else {
-         if (updatesWrappedAround) {
-            // if we are wrapping around then for every incoming update we must remove the oldest update from the viewwer
-            viewer.remove(getUpdatesWithWrapAround(incomingCount));
+   protected void update() {
+      try{
+         lock.lock();
+
+         if (incomingCount == 0) {
+            return;
          }
-         System.arraycopy(incomingUpdates, 0, updates, updateAppendIndex, incomingCount);
-         updateAppendIndex += incomingCount;
-      }
-      viewer.add(Arrays.copyOf(incomingUpdates, incomingCount));
-      incomingCount = 0;
-      if (autoReveal) {
-         viewer.reveal(updates[updateAppendIndex-1]);
-      }
-      viewer.getTable().setRedraw(true);
-   }
-
-   public synchronized void addUpdate(ElementUpdate update) {
-      if (incomingCount >= incomingUpdates.length) {
-         // force an update to free up space on our incoming array
-         getDisplay().syncExec(new Runnable() {
-            
-            @Override
-            public void run() {
-               update();
+         ElementUpdate[] overWritten = updatesNew.add(incomingUpdates, 0, incomingCount);
+         
+         if(updateView){
+            viewer.getTable().setRedraw(false);
+            viewer.remove(overWritten);
+            viewer.add(Arrays.copyOf(incomingUpdates, incomingCount > incomingUpdates.length ? incomingUpdates.length : incomingCount));
+            if (autoReveal) {
+               viewer.reveal(updatesNew.head());
             }
-         });
+            viewer.getTable().setRedraw(true);
+         }
+         
+         incomingCount = 0;
+         clearIncomingUpdates.signalAll();
+      } finally {
+         lock.unlock();
       }
-      incomingUpdates[incomingCount++] = update;
+   }
+   
+   public void forceUpdate(){
+      getDisplay().asyncExec(new Runnable() {
+         @Override
+         public void run() {
+            update();
+         }
+      });
    }
 
-   public synchronized void clearUpdates() {
-      updateAppendIndex = 0;
-      updatesWrappedAround = false;
-      viewer.refresh();
+   public void addUpdate(ElementUpdate update) {
+      try {
+         lock.lock();
+
+         boolean needsClear = incomingCount >= incomingUpdates.length;
+
+         if (needsClear) {
+            // force an update to free up space on our incoming array
+            forceUpdate();
+            try{
+               long nanoTime = TimeUnit.SECONDS.toNanos(5);
+               while(nanoTime > 0 && needsClear){
+                  nanoTime = clearIncomingUpdates.awaitNanos(nanoTime);
+                  needsClear = incomingCount >= incomingUpdates.length;
+               }
+            } catch(InterruptedException ex){
+               OseeLog.log(getClass(), Level.SEVERE, ex);
+            }
+         }
+         
+         incomingUpdates[incomingCount++] = update;
+         
+      } finally {
+         lock.unlock();
+      }
+   }
+
+   public void clearUpdates() {
+      try{
+         lock.lock();
+         updatesNew.clear();
+         viewer.refresh();
+      } finally {
+         lock.unlock();
+      }
    }
 
    /**
@@ -100,45 +130,31 @@
    /**
     * @param autoReveal the autoReveal to set
     */
-   public synchronized void setAutoReveal(boolean autoReveal) {
-      this.autoReveal = autoReveal;
+   public void setAutoReveal(boolean autoReveal) {
+      try{
+         lock.lock();
+         this.autoReveal = autoReveal;
+      } finally {
+         lock.unlock();
+      }
    }
 
-   public synchronized ElementUpdate getUpdate(int index) {
-      if (updatesWrappedAround) {
-         int calcIndex = updateAppendIndex + index ;
-         if (calcIndex >= updates.length) {
-            calcIndex -= updates.length;
-         }
-         return updates[calcIndex];
-      } else {
-         return updates[index];
+   public ElementUpdate[] getUpdates() {
+      try{
+         lock.lock();
+         return updatesNew.getCopy(ElementUpdate.class);
+      }finally{
+         lock.unlock();
       }
    }
-   
-   public synchronized ElementUpdate[] getUpdates() {
-      if (updatesWrappedAround) {
-         ElementUpdate[] copy = new ElementUpdate[updates.length];
-         int remaining = updates.length - updateAppendIndex;
-         System.arraycopy(updates, updateAppendIndex, copy, 0, remaining);
-         System.arraycopy(updates, 0, copy, remaining, updateAppendIndex);
-         return copy;
-      } else {
-         return Arrays.copyOf(updates, updateAppendIndex);
+
+   public void setUpdateView(boolean updateView) {
+      this.updateView = updateView;
+      if(updateView){
+         viewer.getTable().setRedraw(false);
+         viewer.refresh();
+         viewer.getTable().setRedraw(true);
       }
    }
    
-   private ElementUpdate[] getUpdatesWithWrapAround(int count) {
-         ElementUpdate[] copy = new ElementUpdate[count];
-         if ((count + updateAppendIndex) > updates.length) {
-            int remaining = updates.length - updateAppendIndex;
-            System.arraycopy(updates, updateAppendIndex, copy, 0, remaining);
-            System.arraycopy(updates, 0, copy, remaining, count - remaining);  
-         } else {
-            System.arraycopy(updates, updateAppendIndex, copy, 0, count);
-         }
-         return copy;
-   }
-   
-   
 }