Fix archive indexing support
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/DiskIndex.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/DiskIndex.java
index 310e22c..c860906 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/DiskIndex.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/DiskIndex.java
@@ -61,8 +61,9 @@
 	// offset if not read yet
 
 	private char[] cachedCategoryName;
+	char separator = Index.DEFAULT_SEPARATOR;
 
-	public static final String SIGNATURE = "DLTK INDEX VERSION 1.013"; //$NON-NLS-1$
+	public static final String SIGNATURE = "DLTK INDEX VERSION 1.014"; //$NON-NLS-1$
 
 	public final static boolean DEBUG = false;
 
@@ -542,6 +543,7 @@
 				: diskIndex.categoryOffsets.elementSize;
 		this.categoryOffsets = new HashtableOfIntValues(size);
 		this.categoryTables = new HashtableOfObject(size);
+		this.separator = diskIndex.separator;
 	}
 
 	private void mergeCategories(DiskIndex onDisk, int[] positions,
@@ -961,6 +963,7 @@
 		this.numberOfChunks = file.readInt();
 		this.sizeOfLastChunk = file.readUnsignedByte();
 		this.documentReferenceSize = file.readUnsignedByte();
+		this.separator = (char) file.readUnsignedByte();
 
 		this.chunkOffsets = new int[this.numberOfChunks];
 		for (int i = 0; i < this.numberOfChunks; i++)
@@ -1171,6 +1174,7 @@
 		stream.writeInt(this.numberOfChunks);
 		stream.writeByte(this.sizeOfLastChunk);
 		stream.writeByte(this.documentReferenceSize);
+		stream.writeByte(this.separator);
 
 		// apend the file with chunk offsets
 		for (int i = 0; i < this.numberOfChunks; i++)
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/Index.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/Index.java
index 5b6da3f..7517205 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/Index.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/index/Index.java
@@ -17,10 +17,10 @@
 import org.eclipse.dltk.compiler.util.HashtableOfObject;
 import org.eclipse.dltk.compiler.util.SimpleSet;
 import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.search.IDLTKSearchScope;
 import org.eclipse.dltk.core.search.SearchPattern;
 import org.eclipse.dltk.core.search.indexing.ReadWriteMonitor;
 
-
 /**
  * An <code>Index</code> maps document names to their referenced words in
  * various categories.
@@ -37,6 +37,12 @@
 
 	public ReadWriteMonitor monitor;
 
+	// Separator to use after the container path
+	static final char DEFAULT_SEPARATOR = '/';
+	public char separator = DEFAULT_SEPARATOR;
+	public static final char JAR_SEPARATOR = IDLTKSearchScope.FILE_ENTRY_SEPARATOR
+			.charAt(0);
+
 	protected DiskIndex diskIndex;
 
 	protected MemoryIndex memoryIndex;
@@ -104,16 +110,18 @@
 		this.memoryIndex = new MemoryIndex();
 		this.diskIndex = new DiskIndex(fileName);
 		this.diskIndex.initialize(reuseExistingFile);
+		if (reuseExistingFile)
+			this.separator = this.diskIndex.separator;
 	}
-	
-	protected Index (String fileName, String containerPath) {
+
+	protected Index(String fileName, String containerPath) {
 		this.containerPath = containerPath;
 		this.monitor = new ReadWriteMonitor();
 	}
-	
+
 	public void addIndexEntry(char[] category, char[] key,
 			String containerRelativePath) {
-		if( DLTKCore.DEBUG_INDEX ) {
+		if (DLTKCore.DEBUG_INDEX) {
 			System.out.println("DEBUG INDEX: Add Index Entry:" + new String( category ) + " " + new String( key ) + " path:" + containerRelativePath ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		}
 		this.memoryIndex.addIndexEntry(category, key, containerRelativePath);
@@ -209,10 +217,11 @@
 			System.out.println("Index for " + this.containerPath + " (" + new Path(diskIndex.fileName).lastSegment() + ") saved"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$		
 		}
 		// int numberOfChanges = this.memoryIndex.docsToReferences.elementSize;
+		this.diskIndex.separator = this.separator;
 		this.diskIndex = this.diskIndex.mergeWith(this.memoryIndex);
 		this.memoryIndex = new MemoryIndex();
-//		if (numberOfChanges > 1000)
-//			System.gc(); // reclaim space if the MemoryIndex was very BIG
+		// if (numberOfChanges > 1000)
+		// System.gc(); // reclaim space if the MemoryIndex was very BIG
 	}
 
 	public void startQuery() {
@@ -232,7 +241,7 @@
 	public boolean isRebuildable() {
 		return true;
 	}
-	
+
 	/**
 	 * Returns the containerPath of this index without any additional prefixes.
 	 * 
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/AbstractIndexer.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/AbstractIndexer.java
index 1d9fd4a..9ed68e2 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/AbstractIndexer.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/AbstractIndexer.java
@@ -93,7 +93,10 @@
 		addNameReference(fieldName);
 	}
 
+	private int entryCount = 0;
+
 	protected void addIndexEntry(char[] category, char[] key) {
+		++entryCount;
 		this.document.addIndexEntry(category, key);
 	}
 
@@ -131,4 +134,14 @@
 
 	public abstract void indexDocument();
 
+	/**
+	 * Make sure document was added to the index. If no entries were added then
+	 * just add one.
+	 */
+	protected void ensureDocumentAdded() {
+		if (entryCount == 0) {
+			addIndexEntry(STAMP, CharOperation.NO_CHAR);
+		}
+	}
+
 }
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IIndexConstants.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IIndexConstants.java
index 14e4385..5c2805a 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IIndexConstants.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/IIndexConstants.java
@@ -12,6 +12,7 @@
 public interface IIndexConstants {
 
 	/* index encoding */
+	char[] STAMP = "STAMP".toCharArray(); //$NON-NLS-1$
 	char[] REF = "ref".toCharArray(); //$NON-NLS-1$
 	char[] METHOD_REF = "methodRef".toCharArray(); //$NON-NLS-1$
 	char[] CONSTRUCTOR_REF = "constructorRef".toCharArray(); //$NON-NLS-1$
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/SourceIndexerRequestor.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/SourceIndexerRequestor.java
index 9ca10cf..3b31c2b 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/SourceIndexerRequestor.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/SourceIndexerRequestor.java
@@ -259,6 +259,7 @@
 	}
 
 	public void exitModule(int declarationEnd) {
+		indexer.ensureDocumentAdded();
 	}
 
 	/**
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ArchiveProjectFragmentRequest.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ArchiveProjectFragmentRequest.java
new file mode 100644
index 0000000..ac07cdb
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ArchiveProjectFragmentRequest.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2008 xored software, Inc.
+ *
+ * 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:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.core.search.indexing.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IExternalSourceModule;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IModelElementVisitor;
+import org.eclipse.dltk.core.IProjectFragment;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.core.environment.EnvironmentManager;
+import org.eclipse.dltk.core.environment.IEnvironment;
+import org.eclipse.dltk.core.search.index.Index;
+import org.eclipse.dltk.core.search.indexing.IProjectIndexer;
+import org.eclipse.dltk.core.search.indexing.ReadWriteMonitor;
+import org.eclipse.dltk.internal.core.BuiltinSourceModule;
+
+public class ArchiveProjectFragmentRequest extends IndexRequest {
+
+	protected final IProjectFragment fragment;
+	protected final IDLTKLanguageToolkit toolkit;
+
+	public ArchiveProjectFragmentRequest(IProjectIndexer indexer,
+			IProjectFragment fragment, IDLTKLanguageToolkit toolkit) {
+		super(indexer);
+		this.fragment = fragment;
+		this.toolkit = toolkit;
+	}
+
+	protected String getName() {
+		return fragment.getElementName();
+	}
+
+	protected void run() throws CoreException, IOException {
+		IEnvironment environment = EnvironmentManager.getEnvironment(fragment
+				.getScriptProject());
+		if (environment == null || !environment.connect()) {
+			return;
+		}
+		final Set<ISourceModule> modules = getExternalSourceModules();
+		final Index index = getIndexer().getProjectFragmentIndex(fragment);
+		if (index == null) {
+			return;
+		}
+		final IPath containerPath = fragment.getPath();
+		final List<Object> changes = checkChanges(index, modules, containerPath);
+		if (DEBUG) {
+			log("changes.size=" + changes.size()); //$NON-NLS-1$
+		}
+		if (changes.isEmpty()) {
+			return;
+		}
+		final ReadWriteMonitor imon = index.monitor;
+		imon.enterWrite();
+		try {
+			index.separator = Index.JAR_SEPARATOR;
+			for (Iterator<Object> i = changes.iterator(); !isCancelled
+					&& i.hasNext();) {
+				final Object change = i.next();
+				if (change instanceof String) {
+					index.remove((String) change);
+				} else if (change instanceof ISourceModule) {
+					ISourceModule module = (ISourceModule) change;
+					getIndexer().indexSourceModule(index, toolkit, module,
+							containerPath);
+				}
+			}
+
+		} catch (Throwable e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				index.save();
+			} catch (IOException e) {
+				DLTKCore.error("error saving index", e); //$NON-NLS-1$
+			} finally {
+				imon.exitWrite();
+			}
+		}
+	}
+
+	protected List<Object> checkChanges(Index index,
+			Collection<ISourceModule> modules, IPath containerPath)
+			throws ModelException, IOException {
+		final String[] documents = queryDocumentNames(index);
+		if (documents != null && documents.length != 0) {
+			// final long indexLastModified =
+			// index.getIndexFile().lastModified();
+			final List<Object> changes = new ArrayList<Object>();
+			final Map<String, ISourceModule> m = collectSourceModulePaths(
+					modules, containerPath);
+			if (DEBUG) {
+				log("documents.length=" + documents.length); //$NON-NLS-1$
+				log("modules.size=" + modules.size()); //$NON-NLS-1$
+				log("map.size=" + m.size()); //$NON-NLS-1$
+			}
+			for (int i = 0; i < documents.length; ++i) {
+				final String document = documents[i];
+				final ISourceModule module = m.remove(document);
+				if (module == null) {
+					changes.add(document);
+				} else {
+					// TODO (alex) compare dates somehow
+					changes.add(module);
+				}
+			}
+			if (!m.isEmpty()) {
+				changes.addAll(m.values());
+			}
+			return changes;
+		} else {
+			return new ArrayList<Object>(modules);
+		}
+	}
+
+	static class ExternalModuleVisitor implements IModelElementVisitor {
+		final Set<ISourceModule> modules = new HashSet<ISourceModule>();
+
+		public boolean visit(IModelElement element) {
+			if (element.getElementType() == IModelElement.SOURCE_MODULE) {
+				if (element instanceof IExternalSourceModule
+						|| element instanceof BuiltinSourceModule
+						|| ((ISourceModule) element).isBinary()) {
+					modules.add((ISourceModule) element);
+				}
+				return false;
+			}
+			return true;
+		}
+	}
+
+	private Set<ISourceModule> getExternalSourceModules() throws ModelException {
+		final ExternalModuleVisitor visitor = new ExternalModuleVisitor();
+		fragment.accept(visitor);
+		return visitor.modules;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((fragment == null) ? 0 : fragment.hashCode());
+		return result;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!super.equals(obj))
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ArchiveProjectFragmentRequest other = (ArchiveProjectFragmentRequest) obj;
+		if (fragment == null) {
+			if (other.fragment != null)
+				return false;
+		} else if (!fragment.equals(other.fragment))
+			return false;
+		return true;
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/IndexRequest.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/IndexRequest.java
index cad12f2..e4dbbd9 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/IndexRequest.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/IndexRequest.java
@@ -49,9 +49,7 @@
 	}
 
 	/**
-	 * Returns the document names that starts with the given substring, if
-	 * <code>null</code> then returns all of them. Read lock is acquired
-	 * automatically.
+	 * Returns all the document names. Read lock is acquired automatically.
 	 * 
 	 * @param index
 	 * @return
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ProjectRequest.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ProjectRequest.java
index 21260ab..4e474aa 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ProjectRequest.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/ProjectRequest.java
@@ -79,6 +79,9 @@
 				indexer.requestIfNotWaiting(new BuiltinProjectFragmentRequest(
 						indexer, fragment, toolkit,
 						((BuiltinProjectFragment) fragment).lastModified()));
+			} else if (fragment.isArchive()) {
+				indexer.requestIfNotWaiting(new ArchiveProjectFragmentRequest(
+						indexer, fragment, toolkit));
 			} else if (fragment.isExternal()) {
 				indexer.requestIfNotWaiting(new ExternalProjectFragmentRequest(
 						indexer, fragment, toolkit));
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/SourceIndexUtil.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/SourceIndexUtil.java
index f866523..a5fbb64 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/SourceIndexUtil.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/core/search/indexing/core/SourceIndexUtil.java
@@ -21,15 +21,13 @@
 				.getAncestor(IModelElement.PROJECT_FRAGMENT);
 		if (fragment.isArchive()) {
 			if (module instanceof IExternalSourceModule) {
-				IExternalSourceModule ext = (IExternalSourceModule) module;
-				IPath fullPath = ext.getFullPath();
-				return fullPath.toString();
+				final IExternalSourceModule ext = (IExternalSourceModule) module;
+				// archive related path
+				return ext.getFullPath().toString();
 			}
 			if (module.isBinary()) {
-				IPath modulePath = module.getPath();
-				return modulePath.removeFirstSegments(
-						containerPath.segmentCount()).setDevice(null)
-						.toString();
+				return path.removeFirstSegments(containerPath.segmentCount())
+						.setDevice(null).toString();
 			}
 		}
 		if (module instanceof ExternalSourceModule
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/TypeNameMatchRequestorWrapper.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/TypeNameMatchRequestorWrapper.java
index 1b22e75..566ed53 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/TypeNameMatchRequestorWrapper.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/TypeNameMatchRequestorWrapper.java
@@ -105,8 +105,8 @@
 						.indexOf(IDLTKSearchScope.FILE_ENTRY_SEPARATOR);
 				type = separatorIndex == -1 ? createTypeFromPath(path,
 						new String(simpleTypeName), enclosingTypeNames)
-						: createTypeFromZip(path, new String(simpleTypeName),
-								enclosingTypeNames);
+						: createTypeFromZip(path, separatorIndex, new String(
+								simpleTypeName), enclosingTypeNames);
 				// if (DLTKCore.DEBUG) {
 				// System.err.println("TO DO: Add types from zips..."); //$NON-NLS-1$
 				// }
@@ -120,18 +120,19 @@
 		}
 	}
 
-	private IType createTypeFromZip(String resourcePath, String simpleTypeName,
-			char[][] enclosingTypeNames) throws ModelException {
+	private IType createTypeFromZip(String resourcePath, int separatorIndex,
+			String simpleTypeName, char[][] enclosingTypeNames)
+			throws ModelException {
 		// path to a class file inside a jar
 		// Optimization: cache package fragment root handle and package handles
-		int separatorIndex = resourcePath
-				.indexOf(IDLTKSearchScope.FILE_ENTRY_SEPARATOR);
 		if (this.lastPkgFragmentRootPath == null
 				|| this.lastPkgFragmentRootPath.length() > resourcePath
 						.length()
 				|| !resourcePath.startsWith(this.lastPkgFragmentRootPath)) {
-			IProjectFragment root = ((DLTKSearchScope) this.scope)
-					.projectFragment(resourcePath);
+			final String archivePath = resourcePath
+					.substring(0, separatorIndex);
+			final IProjectFragment root = ((DLTKSearchScope) this.scope)
+					.projectFragment(archivePath);
 			if (root == null)
 				return null;
 			this.lastPkgFragmentRootPath = resourcePath.substring(0,
@@ -158,6 +159,11 @@
 			this.packageHandles.put(pkgName, pkgFragment);
 		}
 		ISourceModule unit = pkgFragment.getSourceModule(simpleNames[length]);
+		if (enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+			final TypeFinder finder = new TypeFinder(simpleTypeName);
+			unit.accept(finder);
+			return finder.type;
+		}
 		int etnLength = enclosingTypeNames == null ? 0
 				: enclosingTypeNames.length;
 		String containerTypeName = (etnLength == 0) ? simpleTypeName
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/AndPattern.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/AndPattern.java
index 050f1c9..dc27032 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/AndPattern.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/AndPattern.java
@@ -79,13 +79,15 @@
 			index.stopQuery();
 		}
 
-		String containerPath = index.getContainerPath();
+		final String containerPath = index.getContainerPath();
+		final char separator = index.separator;
 		Object[] names = intersectedNames.values;
 		for (int i = 0, l = names.length; i < l; i++)
 			if (names[i] != null)
 				((InternalSearchPattern) this).acceptMatch((String) names[i],
-						containerPath, null/* no pattern */, requestor,
-						participant, scope); // AndPatterns cannot provide
+						containerPath, separator, null/* no pattern */,
+						requestor, participant, scope); // AndPatterns cannot
+														// provide
 		// the decoded result
 	}
 
diff --git a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/InternalSearchPattern.java b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/InternalSearchPattern.java
index c17c755..7d488ca 100644
--- a/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/InternalSearchPattern.java
+++ b/core/plugins/org.eclipse.dltk.core/search/org/eclipse/dltk/internal/core/search/matching/InternalSearchPattern.java
@@ -13,8 +13,6 @@
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.dltk.compiler.util.Util;
-import org.eclipse.dltk.core.IDLTKLanguageToolkit;
 import org.eclipse.dltk.core.IModelElement;
 import org.eclipse.dltk.core.search.IDLTKSearchScope;
 import org.eclipse.dltk.core.search.SearchParticipant;
@@ -38,8 +36,9 @@
 	public int kind;
 
 	public void acceptMatch(String relativePath, String containerPath,
-			SearchPattern pattern, IndexQueryRequestor requestor,
-			SearchParticipant participant, IDLTKSearchScope scope) {
+			char separator, SearchPattern pattern,
+			IndexQueryRequestor requestor, SearchParticipant participant,
+			IDLTKSearchScope scope) {
 
 		if (scope instanceof DLTKSearchScope) {
 			DLTKSearchScope javaSearchScope = (DLTKSearchScope) scope;
@@ -50,15 +49,15 @@
 					relativePath, containerPath);
 			if (access != DLTKSearchScope.NOT_ENCLOSED) { // scope encloses
 				// the document path
-				String documentPath = documentPath(scope.getLanguageToolkit(),
-						containerPath, relativePath);
+				String documentPath = documentPath(containerPath, separator,
+						relativePath);
 				if (!requestor.acceptIndexMatch(documentPath, pattern,
 						participant, access))
 					throw new OperationCanceledException();
 			}
 		} else {
-			String documentPath = documentPath(scope.getLanguageToolkit(),
-					containerPath, relativePath);
+			String documentPath = documentPath(containerPath, separator,
+					relativePath);
 			if (scope.encloses(documentPath))
 				if (!requestor.acceptIndexMatch(documentPath, pattern,
 						participant, null))
@@ -71,26 +70,10 @@
 		return (SearchPattern) this;
 	}
 
-	/**
-	 * @deprecated
-	 */
-	public String documentPath(String containerPath, String relativePath) {
-		String separator = Util.isArchiveFileName(containerPath) ? IDLTKSearchScope.FILE_ENTRY_SEPARATOR
-				: "/"; //$NON-NLS-1$
-		StringBuffer buffer = new StringBuffer(containerPath.length()
-				+ separator.length() + relativePath.length());
-		buffer.append(containerPath);
-		buffer.append(separator);
-		buffer.append(relativePath);
-		return buffer.toString();
-	}
-
-	public String documentPath(IDLTKLanguageToolkit toolkit,
-			String containerPath, String relativePath) {
-		String separator = Util.isArchiveFileName(toolkit, containerPath) ? IDLTKSearchScope.FILE_ENTRY_SEPARATOR
-				: "/"; //$NON-NLS-1$
-		StringBuffer buffer = new StringBuffer(containerPath.length()
-				+ separator.length() + relativePath.length());
+	public String documentPath(String containerPath, char separator,
+			String relativePath) {
+		StringBuffer buffer = new StringBuffer(containerPath.length() + 1
+				+ relativePath.length());
 		buffer.append(containerPath);
 		buffer.append(separator);
 		buffer.append(relativePath);
@@ -117,8 +100,9 @@
 			if (entries == null)
 				return;
 
-			SearchPattern decodedResult = pattern.getBlankPattern();
-			String containerPath = index.getContainerPath();
+			final SearchPattern decodedResult = pattern.getBlankPattern();
+			final String containerPath = index.getContainerPath();
+			final char separator = index.separator;
 			for (int i = 0, l = entries.length; i < l; i++) {
 				if (monitor != null && monitor.isCanceled())
 					throw new OperationCanceledException();
@@ -129,8 +113,8 @@
 					// TODO (kent) some clients may not need the document names
 					String[] names = entry.getDocumentNames(index);
 					for (int j = 0, n = names.length; j < n; j++)
-						acceptMatch(names[j], containerPath, decodedResult,
-								requestor, participant, scope);
+						acceptMatch(names[j], containerPath, separator,
+								decodedResult, requestor, participant, scope);
 				}
 			}
 		} finally {