Bug 55941	[CVS Console] ConsoleDocument store not releasing memory
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/CVSOutputConsole.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/CVSOutputConsole.java
index 59d9740..cc1cf86 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/CVSOutputConsole.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/CVSOutputConsole.java
@@ -8,7 +8,6 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jface.preference.PreferenceConverter;
 import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.graphics.Color;
@@ -57,10 +56,6 @@
 	 * and <code>dispose()</code>.
 	 */
 	class MyLifecycle implements org.eclipse.ui.console.IConsoleListener {
-		
-		/* (non-Javadoc)
-		 * @see org.eclipse.ui.console.IConsoleListener#consolesAdded(org.eclipse.ui.console.IConsole[])
-		 */
 		public void consolesAdded(IConsole[] consoles) {
 			for (int i = 0; i < consoles.length; i++) {
 				IConsole console = consoles[i];
@@ -70,10 +65,6 @@
 			}
 
 		}
-
-		/* (non-Javadoc)
-		 * @see org.eclipse.ui.console.IConsoleListener#consolesRemoved(org.eclipse.ui.console.IConsole[])
-		 */
 		public void consolesRemoved(IConsole[] consoles) {
 			for (int i = 0; i < consoles.length; i++) {
 				IConsole console = consoles[i];
@@ -85,6 +76,10 @@
 		}
 	}
 	
+	/**
+	 * Constructor initializes preferences and colors but doesn't create the console
+	 * page yet.
+	 */
 	public CVSOutputConsole() {
 		super("CVS", CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_CVS_CONSOLE)); //$NON-NLS-1$
 		// setup console showing preferences
@@ -132,16 +127,10 @@
 	private void dump() {
 		synchronized(document) {
 			initialized = true;
-			int lines = document.getNumberOfLines();
-			for (int i = 0; i < lines; i++) {
-				try {
-					int offset = document.getLineOffset(i);
-					String line = document.get(offset, document.getLineLength(i) - 1);
-					int type = document.getLineType(i);
-					appendLine(type, line);
-				} catch (BadLocationException e) {
-					continue;
-				}
+			ConsoleDocument.ConsoleLine[] lines = document.getLines();
+			for (int i = 0; i < lines.length; i++) {
+				ConsoleDocument.ConsoleLine line = lines[i];
+				appendLine(line.type, line.line);
 			}
 			document.clear();
 		}
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/ConsoleDocument.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/ConsoleDocument.java
index c551b4d..8757a30 100644
--- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/ConsoleDocument.java
+++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/console/ConsoleDocument.java
@@ -10,34 +10,37 @@
  *******************************************************************************/
 package org.eclipse.team.internal.ccvs.ui.console;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.jface.text.AbstractDocument;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.DefaultLineTracker;
-import org.eclipse.jface.text.GapTextStore;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
-
-public class ConsoleDocument extends AbstractDocument {
+/**
+ * Simple circular buffer that stores a fix number of lines.
+ */
+public class ConsoleDocument {
 	public static final int COMMAND = 0; // command text
 	public static final int MESSAGE = 1; // message received
 	public static final int ERROR = 2;   // error received
 	public static final int STATUS = 3;  // status text
 	public static final int DELIMITER = 4; // delimiter text between runs
 
-	private int[] lineTypes = null;
-	private int   currentLine = 0;
+	private int[] lineTypes;
+	private String[] lines;
+	
+	private int writeIndex = 0;
+	private int readIndex = 0;
 
+	private static final int BUFFER_SIZE = 200;
+	
+	protected static class ConsoleLine {
+		public String line;
+		public int type;
+		ConsoleLine(String line, int type) {
+			this.line = line;
+			this.type = type;
+		}
+	}
+	
 	/**
 	 * Creates an empty console document.
 	 */
 	public ConsoleDocument() {
-		setTextStore(new GapTextStore(512, 1024));
-		setLineTracker(new DefaultLineTracker());
-		completeInitialization();
 	}
 	
 	/**
@@ -45,57 +48,44 @@
 	 */
 	public void clear() {
 		lineTypes = null;
-		currentLine = 0;
-		set(""); //$NON-NLS-1$
-	}
-	
-	/**
-	 * Gets the line type for the line containing the specified offset.
-	 */
-	public int getLineType(int offset) {
-		try {
-			int line = getLineOfOffset(offset);
-			if (line < currentLine) return lineTypes[line];
-		} catch (BadLocationException e) {
-			CVSProviderPlugin.log(CVSException.wrapException(e));
-		}
-		return 0;
+		lines = null;
+		writeIndex = 0;
+		readIndex = 0;
 	}
 	
 	/**
 	 * Appends a line of the specified type to the end of the console.
 	 */
 	public void appendConsoleLine(int type, String line) {
-		if (lineTypes == null) {
-			lineTypes = new int[16];
-		} else if (currentLine >= lineTypes.length) {
-			int[] oldLineTypes = lineTypes;
-			lineTypes = new int[oldLineTypes.length * 2];
-			System.arraycopy(oldLineTypes, 0, lineTypes, 0, oldLineTypes.length);
+		if(lines == null) {
+			lines = new String[BUFFER_SIZE];
+			lineTypes = new int[BUFFER_SIZE];
 		}
-		lineTypes[currentLine++] = type;
-		try { 
-			replace(getLength(), 0, line + "\n"); //$NON-NLS-1$
-		} catch (BadLocationException e) {
-			CVSProviderPlugin.log(CVSException.wrapException(e));
+		lines[writeIndex] = line; //$NON-NLS-1$
+		lineTypes[writeIndex] = type;	
+		
+		if(++writeIndex >= BUFFER_SIZE) {
+			writeIndex = 0;
 		}
+		if(writeIndex == readIndex) {
+			if(++readIndex >= BUFFER_SIZE) {
+				readIndex = 0;
+			}
+		}
+	}	
+	
+	public ConsoleLine[] getLines() {
+		if(isEmpty()) return new ConsoleLine[0];
+		ConsoleLine[] docLines = new ConsoleLine[readIndex > writeIndex ? BUFFER_SIZE : writeIndex];
+		for (int i = readIndex; i < writeIndex; ) {
+			docLines[i] = new ConsoleLine(lines[i], lineTypes[i]);
+			if(++i >= BUFFER_SIZE)
+				i = 0;
+		}
+		return docLines;
 	}
 	
-	/**
-	 * Return the indicies of the lines that contain command strings
-	 */
-	private int[] getCommandLines() {
-		List commandLineList = new ArrayList();
-		for (int i = 0; i < currentLine; i++) {
-			if (lineTypes[i] == COMMAND) {
-				commandLineList.add(new Integer(i));
-			}			
-		}
-		int[] commandLines = new int[commandLineList.size()];
-		int i = 0;
-		for (Iterator iter = commandLineList.iterator(); iter.hasNext(); ) {
-			commandLines[i++] = ((Integer) iter.next()).intValue();
-		}
-		return commandLines;
-	}	
+	public boolean isEmpty() {
+		return writeIndex == readIndex;
+	}
 }