Fix #246086 (out of memory when building huge projects - don't read document contents when adding indexing job into queue, do it on demand)
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/DLTKSearchParticipant.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/DLTKSearchParticipant.java
index d78c03c..e84485f 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/DLTKSearchParticipant.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/DLTKSearchParticipant.java
@@ -9,7 +9,6 @@
  *******************************************************************************/
 package org.eclipse.dltk.core.search;
 
-import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
@@ -18,20 +17,16 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.dltk.core.DLTKCore;
 import org.eclipse.dltk.core.DLTKLanguageManager;
 import org.eclipse.dltk.core.IDLTKLanguageToolkit;
 import org.eclipse.dltk.core.ISourceModule;
-import org.eclipse.dltk.core.ModelException;
-import org.eclipse.dltk.core.environment.IFileHandle;
 import org.eclipse.dltk.core.search.index.Index;
 import org.eclipse.dltk.core.search.index.MixinIndex;
 import org.eclipse.dltk.core.search.indexing.SourceIndexer;
 import org.eclipse.dltk.core.search.matching.MatchLocator;
 import org.eclipse.dltk.internal.core.Model;
-import org.eclipse.dltk.internal.core.search.DLTKSearchDocument;
 import org.eclipse.dltk.internal.core.search.IndexSelector;
-import org.eclipse.dltk.internal.core.util.Util;
+import org.eclipse.dltk.internal.core.search.LazyDLTKSearchDocument;
 
 /**
  * A search participant describes a particular extension to a generic search
@@ -64,8 +59,7 @@
 	}
 
 	public SearchDocument getDocument(String documentPath) {
-		return new DLTKSearchDocument(documentPath,
-				getDocumentContents(documentPath), this,
+		return new LazyDLTKSearchDocument(documentPath, this,
 				isExternal(documentPath));
 	}
 
@@ -79,24 +73,6 @@
 
 	}
 
-	private char[] getDocumentContents(String documentPath) {
-		Object target = Model.getTarget(ResourcesPlugin.getWorkspace()
-				.getRoot(), new Path(documentPath), true);
-		try {
-			if (target instanceof IFile) {
-				return Util.getResourceContentsAsCharArray((IFile) target);
-			} else if (target instanceof IFileHandle) {
-				return Util
-						.getResourceContentsAsCharArray((IFileHandle) target);
-			}
-		} catch (ModelException e) {
-			if (DLTKCore.DEBUG) {
-				e.printStackTrace();
-			}
-		}
-		return new char[0];
-	}
-
 	public void indexDocument(SearchDocument document, IPath indexPath) {
 		// TODO must verify that the document + indexPath match, when this is
 		// not called from scheduleDocumentIndexing
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/LazyDLTKSearchDocument.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/LazyDLTKSearchDocument.java
new file mode 100644
index 0000000..f6ba376
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/LazyDLTKSearchDocument.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * 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
+ *
+ *******************************************************************************/
+package org.eclipse.dltk.internal.core.search;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.core.environment.IFileHandle;
+import org.eclipse.dltk.core.search.SearchParticipant;
+import org.eclipse.dltk.internal.core.Model;
+import org.eclipse.dltk.internal.core.util.Util;
+
+/**
+ * This search document differs from {@link DLTKSearchDocument} with that it
+ * only loads document contents when needed. This may be useful when adding
+ * search documents into queue for further processing.
+ * 
+ * Loading of document is not thread safe.
+ * 
+ * @author michael
+ */
+public class LazyDLTKSearchDocument extends DLTKSearchDocument {
+
+	public LazyDLTKSearchDocument(String path, SearchParticipant participant,
+			boolean external) {
+		super(path, null, participant, external);
+	}
+
+	public LazyDLTKSearchDocument(String path, IPath containerPath,
+			char[] contents, SearchParticipant participant, boolean external) {
+		super(path, containerPath, contents, participant, external);
+	}
+
+	private void loadContents() {
+		if (charContents == null) {
+			charContents = getDocumentContents(getPath());
+		}
+	}
+
+	private char[] getDocumentContents(String documentPath) {
+		Object target = Model.getTarget(ResourcesPlugin.getWorkspace()
+				.getRoot(), new Path(documentPath), true);
+		try {
+			if (target instanceof IFile) {
+				return Util.getResourceContentsAsCharArray((IFile) target);
+			} else if (target instanceof IFileHandle) {
+				return Util
+						.getResourceContentsAsCharArray((IFileHandle) target);
+			}
+		} catch (ModelException e) {
+			if (DLTKCore.DEBUG) {
+				e.printStackTrace();
+			}
+		}
+		return new char[0];
+	}
+
+	public String getContents() {
+		loadContents();
+		return new String(charContents);
+	}
+
+	public char[] getCharContents() {
+		loadContents();
+		return charContents;
+	}
+}