Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2011 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 Contributors: IBM Corporation - initial API and implementation daolaf@gmail.com - Contribution for bug 3292227 /
  
  package org.eclipse.jdt.internal.compiler.util;
  
  import java.io.File;
  import java.util.HashSet;
  import java.util.List;
  
  
  public class Util implements SuffixConstants {

Character constant indicating the primitive type boolean in a signature. Value is 'Z'.
  
  	public static final char C_BOOLEAN 		= 'Z';

Character constant indicating the primitive type byte in a signature. Value is 'B'.
  
  	public static final char C_BYTE 		= 'B';

Character constant indicating the primitive type char in a signature. Value is 'C'.
  
  	public static final char C_CHAR 		= 'C';

Character constant indicating the primitive type double in a signature. Value is 'D'.
  
  	public static final char C_DOUBLE 		= 'D';

Character constant indicating the primitive type float in a signature. Value is 'F'.
  
  	public static final char C_FLOAT 		= 'F';

Character constant indicating the primitive type int in a signature. Value is 'I'.
  
  	public static final char C_INT 			= 'I';

Character constant indicating the semicolon in a signature. Value is ';'.
  
  	public static final char C_SEMICOLON 			= ';';

Character constant indicating the colon in a signature. Value is ':'.

Since:
3.0
  
  	public static final char C_COLON 			= ':';

Character constant indicating the primitive type long in a signature. Value is 'J'.
 
 	public static final char C_LONG'J';

Character constant indicating the primitive type short in a signature. Value is 'S'.
 
 	public static final char C_SHORT'S';

Character constant indicating result type void in a signature. Value is 'V'.
 
 	public static final char C_VOID'V';

Character constant indicating the start of a resolved type variable in a signature. Value is 'T'.

Since:
3.0
 
 	public static final char C_TYPE_VARIABLE'T';

Character constant indicating an unbound wildcard type argument in a signature. Value is '*'.

Since:
3.0
 
 	public static final char C_STAR'*';

Character constant indicating an exception in a signature. Value is '^'.

Since:
3.1
 
 	public static final char C_EXCEPTION_START'^';

Character constant indicating a bound wildcard type argument in a signature with extends clause. Value is '+'.

Since:
3.1
 
 	public static final char C_EXTENDS'+';

Character constant indicating a bound wildcard type argument in a signature with super clause. Value is '-'.

Since:
3.1
 
 	public static final char C_SUPER'-';

Character constant indicating the dot in a signature. Value is '.'.
 
 	public static final char C_DOT'.';

Character constant indicating the dollar in a signature. Value is '$'.
 
 	public static final char C_DOLLAR'$';

Character constant indicating an array type in a signature. Value is '['.
 
 	public static final char C_ARRAY'[';

Character constant indicating the start of a resolved, named type in a signature. Value is 'L'.
 
 	public static final char C_RESOLVED'L';

Character constant indicating the start of an unresolved, named type in a signature. Value is 'Q'.
 
 	public static final char C_UNRESOLVED'Q';

Character constant indicating the end of a named type in a signature. Value is ';'.
 
 	public static final char C_NAME_END';';

Character constant indicating the start of a parameter type list in a signature. Value is '('.
 
 	public static final char C_PARAM_START'(';

Character constant indicating the end of a parameter type list in a signature. Value is ')'.
 
 	public static final char C_PARAM_END')';

Character constant indicating the start of a formal type parameter (or type argument) list in a signature. Value is '<'.

Since:
3.0
 
 	public static final char C_GENERIC_START'<';

Character constant indicating the end of a generic type list in a signature. Value is '>'.

Since:
3.0
 
 	public static final char C_GENERIC_END'>';

Character constant indicating a capture of a wildcard type in a signature. Value is '!'.

Since:
3.1
 
 	public static final char C_CAPTURE'!';
 
 	public interface Displayable {
 	}
 
 	private static final int DEFAULT_READING_SIZE = 8192;
 	private static final int DEFAULT_WRITING_SIZE = 1024;
 	public final static String UTF_8 = "UTF-8";	//$NON-NLS-1$
 	public static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
 
 	public static final String EMPTY_STRING = new String(.);
 	public static final int[] EMPTY_INT_ARRAYnew int[0];

Build all the directories and subdirectories corresponding to the packages names into the directory specified in parameters. outputPath is formed like: c:\temp\ the last character is a file separator relativeFileName is formed like: java\lang\String.class *

Parameters:
outputPath java.lang.String
relativeFileName java.lang.String
Returns:
java.lang.String
 
 	public static String buildAllDirectoriesInto(String outputPathString relativeFileNamethrows IOException {
 		char fileSeparatorChar = .;
 		String fileSeparator = .;
 		File f;
 		outputPath = outputPath.replace('/'fileSeparatorChar);
 			// these could be optimized out if we normalized paths once and for
 			// all
 		relativeFileName = relativeFileName.replace('/'fileSeparatorChar);
 		String outputDirPathfileName;
 		int separatorIndex = relativeFileName.lastIndexOf(fileSeparatorChar);
 		if (separatorIndex == -1) {
 			if (outputPath.endsWith(fileSeparator)) {
 				outputDirPath = outputPath.substring(0, outputPath.length() - 1);
 				fileName = outputPath + relativeFileName;
 			} else {
 				outputDirPath = outputPath;
 				fileName = outputPath + fileSeparator + relativeFileName;
 			}
 		} else {
 			if (outputPath.endsWith(fileSeparator)) {
 				outputDirPath = outputPath +
 					relativeFileName.substring(0, separatorIndex);
 				fileName = outputPath + relativeFileName;
 			} else {
 				outputDirPath = outputPath + fileSeparator +
 					relativeFileName.substring(0, separatorIndex);
 				fileName = outputPath + fileSeparator + relativeFileName;
 			}
 		}
 		f = new File(outputDirPath);
 		f.mkdirs();
 		if (f.isDirectory()) {
 			return fileName;
 		} else {
 			// the directory creation failed for some reason - retry using
 			// a slower algorithm so as to refine the diagnostic
 			if (outputPath.endsWith(fileSeparator)) {
 				outputPath = outputPath.substring(0, outputPath.length() - 1);
 			}
 			f = new File(outputPath);
 			boolean checkFileType = false;
 			if (f.exists()) {
 				  checkFileType = true// pre-existed
 			} else {
 				// we have to create that directory
 				if (!f.mkdirs()) {
 					  if (f.exists()) {
 							// someone else created f -- need to check its type
 							checkFileType = true;
 					  } else {
 							// no one could create f -- complain
 						throw new IOException(Messages.bind(
 					  }
 				}
 			}
 			if (checkFileType) {
 				  if (!f.isDirectory()) {
 					throw new IOException(Messages.bind(
 				  }
 			}
 			StringBuffer outDir = new StringBuffer(outputPath);
 			outDir.append(fileSeparator);
 			StringTokenizer tokenizer =
 				new StringTokenizer(relativeFileNamefileSeparator);
 			String token = tokenizer.nextToken();
 			while (tokenizer.hasMoreTokens()) {
 				f = new File(outDir.append(token).append(fileSeparator).toString());
 				  checkFileType = false// reset
 				if (f.exists()) {
 					  checkFileType = true// this is suboptimal, but it catches corner cases
 											// in which a regular file pre-exists
 				} else {
 				// we have to create that directory
 					if (!f.mkdir()) {
 						  if (f.exists()) {
 								// someone else created f -- need to check its type
 								checkFileType = true;
 						  } else {
 								// no one could create f -- complain
 							throw new IOException(Messages.bind(
 									outDir.substring(outputPath.length() + 1,
 										outDir.length() - 1),
 									outputPath));
 						  }
 					}
 				}
 				if (checkFileType) {
 					  if (!f.isDirectory()) {
 						throw new IOException(Messages.bind(
 					  }
 				}
 				token = tokenizer.nextToken();
 			}
 			// token contains the last one
 			return outDir.append(token).toString();
 		}
 	}

Returns the given bytes as a char array using a given encoding (null means platform default).
 
 	public static char[] bytesToChar(byte[] bytesString encodingthrows IOException {
 
 		return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.lengthencoding);
 
 	}

Returns the outer most enclosing type's visibility for the given TypeDeclaration and visibility based on compiler options.
 
 	public static int computeOuterMostVisibility(TypeDeclaration typeDeclarationint visibility) {
 		while (typeDeclaration != null) {
 			switch (typeDeclaration.modifiers & .) {
 					break;
 					if (visibility != .) {
 					}
 					break;
 					if (visibility == .) {
 					}
 					break;
 			}
 			typeDeclaration = typeDeclaration.enclosingType;
 		}
 		return visibility;
 	}
Returns the contents of the given file as a byte array.

Throws:
java.io.IOException if a problem occured reading the file.
 
 	public static byte[] getFileByteContent(File filethrows IOException {
 		InputStream stream = null;
 		try {
 			stream = new BufferedInputStream(new FileInputStream(file));
 			return getInputStreamAsByteArray(stream, (intfile.length());
 		} finally {
 			if (stream != null) {
 				try {
 					stream.close();
 				} catch (IOException e) {
 					// ignore
 				}
 			}
 		}
 	}
Returns the contents of the given file as a char array. When encoding is null, then the platform default one is used

Throws:
java.io.IOException if a problem occured reading the file.
 
 	public static char[] getFileCharContent(File fileString encodingthrows IOException {
 		InputStream stream = null;
 		try {
 			stream = new FileInputStream(file);
 			return getInputStreamAsCharArray(stream, (intfile.length(), encoding);
 		} finally {
 			if (stream != null) {
 				try {
 					stream.close();
 				} catch (IOException e) {
 					// ignore
 				}
 			}
 		}
 	}
 	private static FileOutputStream getFileOutputStream(boolean generatePackagesStructureString outputPathString relativeFileNamethrows IOException {
 		if (generatePackagesStructure) {
 			return new FileOutputStream(new File(buildAllDirectoriesInto(outputPathrelativeFileName)));
 		} else {
 			String fileName = null;
 			char fileSeparatorChar = .;
 			String fileSeparator = .;
 			// First we ensure that the outputPath exists
 			outputPath = outputPath.replace('/'fileSeparatorChar);
 			// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
 			int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
 			if (indexOfPackageSeparator == -1) {
 				if (outputPath.endsWith(fileSeparator)) {
 					fileName = outputPath + relativeFileName;
 				} else {
 					fileName = outputPath + fileSeparator + relativeFileName;
 				}
 			} else {
 				int length = relativeFileName.length();
 				if (outputPath.endsWith(fileSeparator)) {
 					fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
 				} else {
 					fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
 				}
 			}
 			return new FileOutputStream(new File(fileName));
 		}
 	}
 
 	/*
 	 * NIO support to get input stream as byte array.
 	 * Not used as with JDK 1.4.2 this support is slower than standard IO one...
 	 * Keep it as comment for future in case of next JDK versions improve performance
 	 * in this area...
 	 *
 	public static byte[] getInputStreamAsByteArray(FileInputStream stream, int length)
 		throws IOException {
 
 		FileChannel channel = stream.getChannel();
 		int size = (int)channel.size();
 		if (length >= 0 && length < size) size = length;
 		byte[] contents = new byte[size];
 		ByteBuffer buffer = ByteBuffer.wrap(contents);
 		channel.read(buffer);
 		return contents;
 	}
 	*/
Returns the given input stream's contents as a byte array. If a length is specified (i.e. if length != -1), only length bytes are returned. Otherwise all bytes in the stream are returned. Note this doesn't close the stream.

Throws:
java.io.IOException if a problem occured reading the stream.
 
 	public static byte[] getInputStreamAsByteArray(InputStream streamint length)
 			throws IOException {
 		byte[] contents;
 		if (length == -1) {
 			contents = new byte[0];
 			int contentsLength = 0;
 			int amountRead = -1;
 			do {
 				int amountRequested = Math.max(stream.available(), );  // read at least 8K
 
 				// resize contents if needed
 				if (contentsLength + amountRequested > contents.length) {
 					System.arraycopy(
 						contents,
 						0,
 						contents = new byte[contentsLength + amountRequested],
 						0,
 						contentsLength);
 				}
 
 				// read as many bytes as possible
 				amountRead = stream.read(contentscontentsLengthamountRequested);
 
 				if (amountRead > 0) {
 					// remember length of contents
 					contentsLength += amountRead;
 				}
 			} while (amountRead != -1);
 
 			// resize contents if necessary
 			if (contentsLength < contents.length) {
 				System.arraycopy(
 					contents,
 					0,
 					contents = new byte[contentsLength],
 					0,
 					contentsLength);
 			}
 		} else {
 			contents = new byte[length];
 			int len = 0;
 			int readSize = 0;
 			while ((readSize != -1) && (len != length)) {
 				// See PR 1FMS89U
 				// We record first the read size. In this case len is the actual read size.
 				len += readSize;
 				readSize = stream.read(contentslenlength - len);
 			}
 		}
 
 		return contents;
 	}
 
 	/*
 	 * NIO support to get input stream as char array.
 	 * Not used as with JDK 1.4.2 this support is slower than standard IO one...
 	 * Keep it as comment for future in case of next JDK versions improve performance
 	 * in this area...
 	public static char[] getInputStreamAsCharArray(FileInputStream stream, int length, String encoding)
 		throws IOException {
 
 		FileChannel channel = stream.getChannel();
 		int size = (int)channel.size();
 		if (length >= 0 && length < size) size = length;
 		Charset charset = encoding==null?systemCharset:Charset.forName(encoding);
 		if (charset != null) {
 			MappedByteBuffer bbuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
 		    CharsetDecoder decoder = charset.newDecoder();
 		    CharBuffer buffer = decoder.decode(bbuffer);
 		    char[] contents = new char[buffer.limit()];
 		    buffer.get(contents);
 		    return contents;
 		}
 		throw new UnsupportedCharsetException(SYSTEM_FILE_ENCODING);
 	}
 	*/
Returns the given input stream's contents as a character array. If a length is specified (i.e. if length != -1), this represents the number of bytes in the stream. Note this doesn't close the stream.

Throws:
java.io.IOException if a problem occured reading the stream.
 
 	public static char[] getInputStreamAsCharArray(InputStream streamint lengthString encoding)
 			throws IOException {
 		BufferedReader reader = null;
 		try {
 			reader = encoding == null
 						? new BufferedReader(new InputStreamReader(stream))
 						: new BufferedReader(new InputStreamReader(streamencoding));
 		} catch (UnsupportedEncodingException e) {
 			// encoding is not supported
 			reader =  new BufferedReader(new InputStreamReader(stream));
 		}
 		char[] contents;
 		int totalRead = 0;
 		if (length == -1) {
 			contents = .;
 		} else {
 			// length is a good guess when the encoding produces less or the same amount of characters than the file length
 			contents = new char[length]; // best guess
 		}
 
 		while (true) {
 			int amountRequested;
 			if (totalRead < length) {
 				// until known length is met, reuse same array sized eagerly
 				amountRequested = length - totalRead;
 			} else {
 				// reading beyond known length
 				int current = reader.read();
 				if (current < 0) break;
 
 				amountRequested = Math.max(stream.available(), );  // read at least 8K
 
 				// resize contents if needed
 				if (totalRead + 1 + amountRequested > contents.length)
 					System.arraycopy(contents, 	0, 	contents = new char[totalRead + 1 + amountRequested], 0, totalRead);
 
 				// add current character
 				contents[totalRead++] = (charcurrent// coming from totalRead==length
 			}
 			// read as many chars as possible
 			int amountRead = reader.read(contentstotalReadamountRequested);
 			if (amountRead < 0) break;
 			totalRead += amountRead;
 		}
 
 		// Do not keep first character for UTF-8 BOM encoding
 		int start = 0;
 		if (totalRead > 0 && .equals(encoding)) {
 			if (contents[0] == 0xFEFF) { // if BOM char then skip
 				totalRead--;
 				start = 1;
 			}
 		}
 
 		// resize contents if necessary
 		if (totalRead < contents.length)
 			System.arraycopy(contentsstartcontents = new char[totalRead], 	0, 	totalRead);
 
 		return contents;
 	}

Returns a one line summary for an exception (extracted from its stacktrace: name + first frame)

Parameters:
exception
Returns:
one line summary for an exception
 
 	public static String getExceptionSummary(Throwable exception) {
 		StringWriter stringWriter = new StringWriter();
 		exception.printStackTrace(new PrintWriter(stringWriter));
 		StringBuffer buffer = stringWriter.getBuffer();		
 		StringBuffer exceptionBuffer = new StringBuffer(50);
 		exceptionBuffer.append(exception.toString());
 		// only keep leading frame portion of the trace (i.e. line no. 2 from the stacktrace)
 		lookupLine2: for (int i = 0, lineSep = 0, max = buffer.length(), line2Start = 0; i < maxi++) {
 			switch (buffer.charAt(i)) {
 				case '\n':
 				case '\r' :
 					if (line2Start > 0) {
 						exceptionBuffer.append(' ').append(buffer.substring(line2Starti));
 						break lookupLine2;
 					}						
 					lineSep++;
 					break;
 				case ' ' :
 				case '\t' :
 					break;
 				default :
 					if (lineSep > 0) {
 						line2Start = i;
 						lineSep = 0;
 					}
 					break;
 			}
 		}
 		return exceptionBuffer.toString();
 	}
 	
 	public static int getLineNumber(int positionint[] lineEndsint gint d) {
 		if (lineEnds == null)
 			return 1;
 		if (d == -1)
 			return 1;
 		int m = gstart;
 		while (g <= d) {
 			m = g + (d - g) /2;
 			if (position < (start = lineEnds[m])) {
 				d = m-1;
 			} else if (position > start) {
 				g = m+1;
 			} else {
 				return m + 1;
 			}
 		}
 		if (position < lineEnds[m]) {
 			return m+1;
 		}
 		return m+2;
 	}
Returns the contents of the given zip entry as a byte array.

Throws:
java.io.IOException if a problem occured reading the zip entry.
 
 	public static byte[] getZipEntryByteContent(ZipEntry zeZipFile zip)
 		throws IOException {
 
 		InputStream stream = null;
 		try {
 			InputStream inputStream = zip.getInputStream(ze);
 			if (inputStream == nullthrow new IOException("Invalid zip entry name : " + ze.getName()); //$NON-NLS-1$
 			stream = new BufferedInputStream(inputStream);
 			return getInputStreamAsByteArray(stream, (intze.getSize());
 		} finally {
 			if (stream != null) {
 				try {
 					stream.close();
 				} catch (IOException e) {
 					// ignore
 				}
 			}
 		}
 	}
 	public static int hashCode(Object[] array) {
 		int prime = 31;
 		if (array == null) {
 			return 0;
 		}
 		int result = 1;
 		for (int index = 0; index < array.lengthindex++) {
 			result = prime * result + (array[index] == null ? 0 : array[index].hashCode());
 		}
 		return result;
 	}
Returns whether the given name is potentially a zip archive file name (it has a file extension and it is not ".java" nor ".class")
 
 	public final static boolean isPotentialZipArchive(String name) {
 		int lastDot = name.lastIndexOf('.');
 		if (lastDot == -1)
 			return false// no file extension, it cannot be a zip archive name
 		if (name.lastIndexOf(.) > lastDot)
 			return false// dot was before the last file separator, it cannot be a zip archive name
 		int length = name.length();
 		int extensionLength = length - lastDot - 1;
 		if (extensionLength == .length()) {
 			for (int i = extensionLength-1; i >=0; i--) {
 				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != .charAt(i)) {
 					break// not a ".java" file, check ".class" file case below
 				}
 				if (i == 0) {
 					return false// it is a ".java" file, it cannot be a zip archive name
 				}
 			}
 		}
 		if (extensionLength == .length()) {
 			for (int i = extensionLength-1; i >=0; i--) {
 				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != .charAt(i)) {
 					return true// not a ".class" file, so this is a potential archive name
 				}
 			}
 			return false// it is a ".class" file, it cannot be a zip archive name
 		}
 		return true// it is neither a ".java" file nor a ".class" file, so this is a potential archive name
 	}

Returns true iff str.toLowerCase().endsWith(".class") implementation is not creating extra strings.
 
 	public final static boolean isClassFileName(char[] name) {
 		int nameLength = name == null ? 0 : name.length;
 		int suffixLength = .;
 		if (nameLength < suffixLengthreturn false;
 
 		for (int i = 0, offset = nameLength - suffixLengthi < suffixLengthi++) {
 			char c = name[offset + i];
 			if (c != [i] && c != [i]) return false;
 		}
 		return true;
 	}
Returns true iff str.toLowerCase().endsWith(".class") implementation is not creating extra strings.
 
 	public final static boolean isClassFileName(String name) {
 		int nameLength = name == null ? 0 : name.length();
 		int suffixLength = .;
 		if (nameLength < suffixLengthreturn false;
 
 		for (int i = 0; i < suffixLengthi++) {
 			char c = name.charAt(nameLength - i - 1);
 			int suffixIndex = suffixLength - i - 1;
 			if (c != [suffixIndex] && c != [suffixIndex]) return false;
 		}
 		return true;
 	}
 	/* TODO (philippe) should consider promoting it to CharOperation
 	 * Returns whether the given resource path matches one of the inclusion/exclusion
 	 * patterns.
 	 * NOTE: should not be asked directly using pkg root pathes
 	 * @see IClasspathEntry#getInclusionPatterns
 	 * @see IClasspathEntry#getExclusionPatterns
 	 */
 	public final static boolean isExcluded(char[] pathchar[][] inclusionPatternschar[][] exclusionPatternsboolean isFolderPath) {
 		if (inclusionPatterns == null && exclusionPatterns == nullreturn false;
 
 		inclusionCheck: if (inclusionPatterns != null) {
 			for (int i = 0, length = inclusionPatterns.lengthi < lengthi++) {
 				char[] pattern = inclusionPatterns[i];
 				char[] folderPattern = pattern;
 				if (isFolderPath) {
 					int lastSlash = CharOperation.lastIndexOf('/'pattern);
 					if (lastSlash != -1 && lastSlash != pattern.length-1){ // trailing slash -> adds '**' for free (see http://ant.apache.org/manual/dirtasks.html)
 						int star = CharOperation.indexOf('*'patternlastSlash);
 						if ((star == -1
 								|| star >= pattern.length-1
 								|| pattern[star+1] != '*')) {
 							folderPattern = CharOperation.subarray(pattern, 0, lastSlash);
 						}
 					}
 				}
 				if (CharOperation.pathMatch(folderPatternpathtrue'/')) {
 					break inclusionCheck;
 				}
 			}
 			return true// never included
 		}
 		if (isFolderPath) {
 			path = CharOperation.concat(pathnew char[] {'*'}, '/');
 		}
 		if (exclusionPatterns != null) {
 			for (int i = 0, length = exclusionPatterns.lengthi < lengthi++) {
 				if (CharOperation.pathMatch(exclusionPatterns[i], pathtrue'/')) {
 					return true;
 				}
 			}
 		}
 		return false;
 	}

Returns true iff str.toLowerCase().endsWith(".java") implementation is not creating extra strings.
 
 	public final static boolean isJavaFileName(char[] name) {
 		int nameLength = name == null ? 0 : name.length;
 		int suffixLength = .;
 		if (nameLength < suffixLengthreturn false;
 
 		for (int i = 0, offset = nameLength - suffixLengthi < suffixLengthi++) {
 			char c = name[offset + i];
 			if (c != [i] && c != [i]) return false;
 		}
 		return true;
 	}

Returns true iff str.toLowerCase().endsWith(".java") implementation is not creating extra strings.
 
 	public final static boolean isJavaFileName(String name) {
 		int nameLength = name == null ? 0 : name.length();
 		int suffixLength = .;
 		if (nameLength < suffixLengthreturn false;
 
 		for (int i = 0; i < suffixLengthi++) {
 			char c = name.charAt(nameLength - i - 1);
 			int suffixIndex = suffixLength - i - 1;
 			if (c != [suffixIndex] && c != [suffixIndex]) return false;
 		}
 		return true;
 	}
 
 	public static void reverseQuickSort(char[][] listint leftint right) {
 		int original_leftleft;
 		int original_rightright;
 		char[] midlist[left + ((right-left)/2)];
 		do {
 			while (CharOperation.compareTo(list[left], mid) > 0) {
 				left++;
 			}
 			while (CharOperation.compareTo(midlist[right]) > 0) {
 				right--;
 			}
 			if (left <= right) {
 				char[] tmplist[left];
 				list[left]= list[right];
 				list[right]= tmp;
 				left++;
 				right--;
 			}
 		} while (left <= right);
 		if (original_left < right) {
 			reverseQuickSort(listoriginal_leftright);
 		}
 		if (left < original_right) {
 			reverseQuickSort(listleftoriginal_right);
 		}
 	}
 	public static void reverseQuickSort(char[][] listint leftint rightint[] result) {
 		int original_leftleft;
 		int original_rightright;
 		char[] midlist[left + ((right-left)/2)];
 		do {
 			while (CharOperation.compareTo(list[left], mid) > 0) {
 				left++;
 			}
 			while (CharOperation.compareTo(midlist[right]) > 0) {
 				right--;
 			}
 			if (left <= right) {
 				char[] tmplist[left];
 				list[left]= list[right];
 				list[right]= tmp;
 				int temp = result[left];
 				result[left] = result[right];
 				result[right] = temp;
 				left++;
 				right--;
 			}
 		} while (left <= right);
 		if (original_left < right) {
 			reverseQuickSort(listoriginal_leftrightresult);
 		}
 		if (left < original_right) {
 			reverseQuickSort(listleftoriginal_rightresult);
 		}
 	}
INTERNAL USE-ONLY Search the column number corresponding to a specific position
 
 	public static final int searchColumnNumber(int[] startLineIndexesint lineNumberint position) {
 		switch(lineNumber) {
 			case 1 :
 				return position + 1;
 			case 2:
 				return position - startLineIndexes[0];
 			default:
 				int line = lineNumber - 2;
 	    		int length = startLineIndexes.length;
 	    		if (line >= length) {
 	    			return position - startLineIndexes[length - 1];
 	    		}
 	    		return position - startLineIndexes[line];
 		}
 	}

Converts a boolean value into Boolean.

Parameters:
bool The boolean to convert
Returns:
The corresponding Boolean object (TRUE or FALSE).
 
 	public static Boolean toBoolean(boolean bool) {
 		if (bool) {
 			return .;
 		} else {
 			return .;
 		}
 	}
Converts an array of Objects into String.
 
 	public static String toString(Object[] objects) {
 		return toString(objects,
 			new Displayable(){
 				public String displayString(Object o) {
 					if (o == nullreturn "null"//$NON-NLS-1$
 					return o.toString();
 				}
 			});
 	}

Converts an array of Objects into String.
 
 	public static String toString(Object[] objectsDisplayable renderer) {
 		if (objects == nullreturn ""//$NON-NLS-1$
 		StringBuffer buffer = new StringBuffer(10);
 		for (int i = 0; i < objects.lengthi++){
 			if (i > 0) buffer.append(", "); //$NON-NLS-1$
 			buffer.append(renderer.displayString(objects[i]));
 		}
 		return buffer.toString();
 	}

outputPath is formed like: c:\temp\ the last character is a file separator relativeFileName is formed like: java\lang\String.class

Parameters:
generatePackagesStructure a flag to know if the packages structure has to be generated.
outputPath the given output directory
relativeFileName the given relative file name
classFile the given classFile to write
 
 	public static void writeToDisk(boolean generatePackagesStructureString outputPathString relativeFileNameClassFile classFilethrows IOException {
 		FileOutputStream file = getFileOutputStream(generatePackagesStructureoutputPathrelativeFileName);
 		/* use java.nio to write
 		if (true) {
 			FileChannel ch = file.getChannel();
 			try {
 				ByteBuffer buffer = ByteBuffer.allocate(classFile.headerOffset + classFile.contentsOffset);
 				buffer.put(classFile.header, 0, classFile.headerOffset);
 				buffer.put(classFile.contents, 0, classFile.contentsOffset);
 				buffer.flip();
 				while (true) {
 					if (ch.write(buffer) == 0) break;
 				}
 			} finally {
 				ch.close();
 			}
 			return;
 		}
 		*/
 //		BufferedOutputStream output = new BufferedOutputStream(file);
 		try {
 			// if no IOException occured, output cannot be null
 			output.write(classFile.header, 0, classFile.headerOffset);
			output.write(classFile.contents, 0, classFile.contentsOffset);
			output.flush();
catch(IOException e) {
			throw e;
finally {
			output.close();
	public static void recordNestedType(ClassFile classFileTypeBinding typeBinding) {
		if (classFile.visitedTypes == null) {
			classFile.visitedTypes = new HashSet(3);
else if (classFile.visitedTypes.contains(typeBinding)) {
			// type is already visited
			return;
		classFile.visitedTypes.add(typeBinding);
		if (typeBinding.isParameterizedType()
				&& ((typeBinding.tagBits & .) != 0)) {
			ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBindingtypeBinding;
			ReferenceBinding genericType = parameterizedTypeBinding.genericType();
			if ((genericType.tagBits & .) != 0) {
				recordNestedType(classFilegenericType);
			TypeBinding[] arguments = parameterizedTypeBinding.arguments;
			if (arguments != null) {
				for (int j = 0, max2 = arguments.lengthj < max2j++) {
					TypeBinding argument = arguments[j];
					if (argument.isWildcard()) {
						WildcardBinding wildcardBinding = (WildcardBindingargument;
						TypeBinding bound = wildcardBinding.bound;
						if (bound != null
								&& ((bound.tagBits & .) != 0)) {
							recordNestedType(classFilebound);
						ReferenceBinding superclass = wildcardBinding.superclass();
						if (superclass != null
								&& ((superclass.tagBits & .) != 0)) {
							recordNestedType(classFilesuperclass);
						ReferenceBinding[] superInterfaces = wildcardBinding.superInterfaces();
						if (superInterfaces != null) {
							for (int k = 0, max3 =  superInterfaces.lengthk < max3k++) {
								ReferenceBinding superInterface = superInterfaces[k];
								if ((superInterface.tagBits & .) != 0) {
									recordNestedType(classFilesuperInterface);
else if ((argument.tagBits & .) != 0) {
						recordNestedType(classFileargument);
else if (typeBinding.isTypeVariable()
				&& ((typeBinding.tagBits & .) != 0)) {
			TypeVariableBinding typeVariableBinding = (TypeVariableBindingtypeBinding;
			TypeBinding upperBound = typeVariableBinding.upperBound();
			if (upperBound != null && ((upperBound.tagBits & .) != 0)) {
				recordNestedType(classFileupperBound);
			TypeBinding[] upperBounds = typeVariableBinding.otherUpperBounds();
			if (upperBounds != null) {
				for (int k = 0, max3 =  upperBounds.lengthk < max3k++) {
					TypeBinding otherUpperBound = upperBounds[k];
					if ((otherUpperBound.tagBits & .) != 0) {
						recordNestedType(classFileotherUpperBound);
else if (typeBinding.isNestedType()) {
			classFile.recordInnerClasses(typeBinding);
	/*
	 * External API
	 */
	public static File getJavaHome() {
		String javaHome = System.getProperty("java.home");//$NON-NLS-1$
		if (javaHome != null) {
			File javaHomeFile = new File(javaHome);
			if (javaHomeFile.exists()) {
				return javaHomeFile;
		return null;
	public static void collectRunningVMBootclasspath(List bootclasspaths) {
		/* no bootclasspath specified
		 * we can try to retrieve the default librairies of the VM used to run
		 * the batch compiler
		 */
		String javaversion = System.getProperty("java.version");//$NON-NLS-1$
		if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
		/*
		 * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath
		 */
		// check bootclasspath properties for Sun, JRockit and Harmony VMs
		String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
		if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
			// IBM J9 VMs
			bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$
			if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
				// Harmony using IBM VME
				bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$
		if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) {
			StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty.);
			String token;
			while (tokenizer.hasMoreTokens()) {
				token = tokenizer.nextToken();
				FileSystem.Classpath currentClasspath = FileSystem.getClasspath(tokennullnull);
				if (currentClasspath != null) {
					bootclasspaths.add(currentClasspath);
else {
			// try to get all jars inside the lib folder of the java home
			final File javaHome = getJavaHome();
			if (javaHome != null) {
				File[] directoriesToCheck = null;
				if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
					directoriesToCheck = new File[] {
						new File(javaHome"../Classes"), //$NON-NLS-1$
					};
else {
					// fall back to try to retrieve them out of the lib directory
					directoriesToCheck = new File[] {
						new File(javaHome"lib"//$NON-NLS-1$
					};
				File[][] systemLibrariesJars = Main.getLibrariesFiles(directoriesToCheck);
				if (systemLibrariesJars != null) {
					for (int i = 0, max = systemLibrariesJars.lengthi < maxi++) {
						File[] current = systemLibrariesJars[i];
						if (current != null) {
							for (int j = 0, max2 = current.lengthj < max2j++) {
								FileSystem.Classpath classpath =
									FileSystem.getClasspath(current[j].getAbsolutePath(),
										nullfalsenullnull);
								if (classpath != null) {
									bootclasspaths.add(classpath);
	public static int getParameterCount(char[] methodSignature) {
		try {
			int count = 0;
			int i = CharOperation.indexOf(methodSignature);
			if (i < 0) {
else {
				i++;
			for (;;) {
				if (methodSignature[i] == ) {
					return count;
				int e= Util.scanTypeSignature(methodSignaturei);
				if (e < 0) {
else {
					i = e + 1;
				count++;
	}

Scans the given string for a type signature starting at the given index and returns the index of the last character.
 TypeSignature:
  |  BaseTypeSignature
  |  ArrayTypeSignature
  |  ClassTypeSignature
  |  TypeVariableSignature
 

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a type signature
	public static int scanTypeSignature(char[] stringint start) {
		// need a minimum 1 char
		if (start >= string.length) {
		char c = string[start];
		switch (c) {
			case  :
				return scanArrayTypeSignature(stringstart);
			case  :
				return scanClassTypeSignature(stringstart);
				return scanTypeVariableSignature(stringstart);
			case  :
			case  :
			case  :
			case  :
			case  :
			case  :
			case  :
			case  :
			case  :
				return scanBaseTypeSignature(stringstart);
			case  :
				return scanCaptureTypeSignature(stringstart);
			case :
			case :
				return scanTypeBoundSignature(stringstart);
			default :
	}

Scans the given string for a base type signature starting at the given index and returns the index of the last character.
 BaseTypeSignature:
     B | C | D | F | I
   | J | S | V | Z
 
Note that although the base type "V" is only allowed in method return types, there is no syntactic ambiguity. This method will accept them anywhere without complaint.

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a base type signature
	public static int scanBaseTypeSignature(char[] stringint start) {
		// need a minimum 1 char
		if (start >= string.length) {
		char c = string[start];
		if ("BCDFIJSVZ".indexOf(c) >= 0) { //$NON-NLS-1$
			return start;
else {
	}

Scans the given string for an array type signature starting at the given index and returns the index of the last character.
 ArrayTypeSignature:
     [ TypeSignature
 

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not an array type signature
	public static int scanArrayTypeSignature(char[] stringint start) {
		int length = string.length;
		// need a minimum 2 char
		if (start >= length - 1) {
		char c = string[start];
		if (c != ) {
		c = string[++start];
		while(c == ) {
			// need a minimum 2 char
			if (start >= length - 1) {
			c = string[++start];
		return scanTypeSignature(stringstart);
	}

Scans the given string for a capture of a wildcard type signature starting at the given index and returns the index of the last character.
 CaptureTypeSignature:
     ! TypeBoundSignature
 

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a capture type signature
	public static int scanCaptureTypeSignature(char[] stringint start) {
		// need a minimum 2 char
		if (start >= string.length - 1) {
		char c = string[start];
		if (c != ) {
		return scanTypeBoundSignature(stringstart + 1);
	}

Scans the given string for a type variable signature starting at the given index and returns the index of the last character.
 TypeVariableSignature:
     T Identifier ;
 

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a type variable signature
	public static int scanTypeVariableSignature(char[] stringint start) {
		// need a minimum 3 chars "Tx;"
		if (start >= string.length - 2) {
		// must start in "T"
		char c = string[start];
		if (c != ) {
		int id = scanIdentifier(stringstart + 1);
		c = string[id + 1];
		if (c == ) {
			return id + 1;
else {
	}

Scans the given string for an identifier starting at the given index and returns the index of the last character. Stop characters are: ";", ":", "<", ">", "/", ".".

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not an identifier
	public static int scanIdentifier(char[] stringint start) {
		// need a minimum 1 char
		if (start >= string.length) {
		int p = start;
		while (true) {
			char c = string[p];
			if (c == '<' || c == '>' || c == ':' || c == ';' || c == '.' || c == '/') {
				return p - 1;
			p++;
			if (p == string.length) {
				return p - 1;
	}

Scans the given string for a class type signature starting at the given index and returns the index of the last character.
 ClassTypeSignature:
     { L | Q } Identifier
           { { / | . Identifier [ < TypeArgumentSignature* > ] }
           ;
 
Note that although all "/"-identifiers most come before "."-identifiers, there is no syntactic ambiguity. This method will accept them without complaint.

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a class type signature
	public static int scanClassTypeSignature(char[] stringint start) {
		// need a minimum 3 chars "Lx;"
		if (start >= string.length - 2) {
		// must start in "L" or "Q"
		char c = string[start];
		if (c !=  && c != ) {
			return -1;
		int p = start + 1;
		while (true) {
			if (p >= string.length) {
			c = string[p];
			if (c == ) {
				// all done
				return p;
else if (c == ) {
				int e = scanTypeArgumentSignatures(stringp);
				p = e;
else if (c ==  || c == '/') {
				int id = scanIdentifier(stringp + 1);
				p = id;
			p++;
	}

Scans the given string for a type bound signature starting at the given index and returns the index of the last character.
 TypeBoundSignature:
     [-+] TypeSignature ;
     *
 

Parameters:
string the signature string
start the 0-based character index of the first character
Returns:
the 0-based character index of the last character
Throws:
java.lang.IllegalArgumentException if this is not a type variable signature
	public static int scanTypeBoundSignature(char[] stringint start) {
		// need a minimum 1 char for wildcard
		if (start >= string.length) {