package org.eclipse.jdt.internal.formatter;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.formatter.impl.*;
import java.util.*;

/** <h2>How to format a piece of code ?</h2>
 * <ul><li>Create an instance of <code>CodeFormatter</code>
 * <li>Use the method <code>void format(aString)</code>
 * on this instance to format <code>aString</code>.
 * It will return the formatted string.</ul>
*/

public class CodeFormatter implements TerminalSymbols {

	public FormatterOptions options;

	/** 
	 * Represents a block in the <code>constructions</code> stack.
	 */
	public static final int BLOCK = TerminalSymbols.TokenNameLBRACE;
	/** 
	 * Represents a block following a control statement in the <code>constructions</code> stack.
	 */
	public static final int NONINDENT_BLOCK = -100;
	/** 
	 * Contains the formatted output.
	 */
	StringBuffer formattedSource;
	/** 
	 * Contains the current line.<br>
	 * Will be dumped at the next "newline"
	 */
	StringBuffer currentLineBuffer;

	/** 
	 * Used during the formatting to get each token.
	 */
	Scanner scanner;

	/** 
	 * Contains the tokens responsible for the current indentation level
	 * and the blocks not closed yet.
	 */
	private int[] constructions;
	/** 
	 * Index in the <code>constructions</code> array.
	 */
	private int constructionsCount;
	/** 
	 * Level of indentation of the current token (number of tab char put in front of it).
	 */
	private int indentationLevel;

	/** 
	 * Regular level of indentation of all the lines
	 */
	private int initialIndentationLevel;

	/** 
	 * Used to split a line.
	 */
	Scanner splitScanner;
	/** 
	 * To remember the offset between the beginning of the line and the
	 * beginning of the comment.
	 */
	int currentCommentOffset;
	int currentLineIndentationLevel;
	int maxLineSize = 30;
	private boolean containsOpenCloseBraces;
	private int indentationLevelForOpenCloseBraces;

	/**
	 * Collections of positions to map
	 */
	private int[] positionsToMap;
	
	/**
	 * Collections of mapped positions
	 */
	private int[] mappedPositions;

	private int indexToMap;

	private int indexInMap;
	
	private int globalDelta;

	private int lineDelta;

	private int splitDelta;

	private int beginningOfLineIndex;
/** 
 * Creates a new instance of Code Formatter using the FormattingOptions object
 * given as argument
 * @deprecated Use CodeFormatter(ConfigurableOption[]) instead
 */
public CodeFormatter() {
	this(null);
}
/** 
 * Creates a new instance of Code Formatter using the given settings.
 */
public CodeFormatter(ConfigurableOption[] settings) {

	// initialize internal state
	constructionsCount = 0;
	constructions = new int[10];
	currentLineIndentationLevel = indentationLevel = initialIndentationLevel;
	currentCommentOffset = -1;
	
	// initialize primary and secondary scanners
	scanner = new Scanner(true,true);		// regular scanner for forming lines
	scanner.recordLineSeparator = true;		// to remind of the position of the beginning of the line.
	splitScanner = new Scanner(true,true);	// secondary scanner to split long lines formed by primary scanning

	// initialize current line buffer
	currentLineBuffer = new StringBuffer();
	this.options = new FormatterOptions(settings);
}
/** 
 * Sets the behaviour of the formatter about the braces using the given flag.<br>
 * <ul>
 * <li>if true, the formatter add new line & indent before the opening brace.
 * <li>if false, the formatter leaves the brace on the same line.
 * </ul>
 * @deprecated backward compatibility with VAJ
 */

 /**  */
public void addNewLineOnOpeningBrace(boolean flag) {
	options.setNewLineBeforeOpeningBraceMode(flag);
}
/**
 * Returns true if a lineSeparator has to be inserted before <code>operator</code>
 * false otherwise.
 */
private static boolean breakLineBeforeOperator(int operator) {
	switch (operator) {
		case TokenNameCOMMA :
		case TokenNameSEMICOLON :
		case TokenNameEQUAL :
			return false;
		default :
			return true;
	}
}
/** 
 * Returns the end of the source code.
 */
private final String copyRemainingSource() {
	char str[] = scanner.source;
	int startPosition = scanner.startPosition;
	int length = str.length - startPosition;
	StringBuffer bufr = new StringBuffer(length);
	if (startPosition < str.length) {
		bufr.append(str, startPosition, length);
	}
	return (bufr.toString());
}
/**
 * Inserts <code>tabCount</code> tab character or their equivalent number of spaces.
 */
private void dumpTab(int tabCount) {
	if (options.indentWithTab) {
		for (int j = 0; j < tabCount; j++) {
			formattedSource.append('\t');
			increaseSplitDelta(1);
		}
	} else {
		for (int i = 0, max = options.tabSize * tabCount; i < max; i++) {
			formattedSource.append(' ');
			increaseSplitDelta(1);
		}
	}
}
/**
 * Dumps <code>currentLineBuffer</code> into the formatted string.
 */
private void flushBuffer() {
	String currentString = currentLineBuffer.toString();
	splitDelta = 0;
	beginningOfLineIndex = formattedSource.length();	
	if (options.maxLineLength!=0){
		if (containsOpenCloseBraces) {
			containsOpenCloseBraces = false;
			outputLine(currentString,
				false,
				indentationLevelForOpenCloseBraces,
				0,
				-1,
				null,
				0);
				indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
		} else {
			outputLine(currentString,
				false,
				currentLineIndentationLevel,
				0,
				-1,
				null,
				0);
		}		
	} else {
		formattedSource.append(currentString);
	}
}
/** 
 * Formats the input string.
 */
private void format() {
	int token = 0;
	int previousToken = 0;
	int previousCompilableToken = 0;

	int indentationOffset = 0;

	int newLinesInWhitespace = 0;
	// number of new lines in the previous whitespace token
	// (used to leave blank lines before comments)
	int pendingNewLines = 0;
	boolean expectingOpenBrace = false;
	boolean clearNonBlockIndents = false;
	// true if all indentations till the 1st { (usefull after } or ;)
	boolean pendingSpace = true;
	boolean pendingNewlineAfterParen = false;
	// true when a cr is to be put after a ) (in conditional statements)
	boolean inAssignment = false;
	boolean inArrayAssignment = false;
	boolean inThrowsClause = false;
	boolean inClassOrInterfaceHeader = false;

	// openBracketCount is used to count the number of open brackets not closed yet.
	int openBracketCount = 0;
	
	int unarySignModifier = 0;

	// openParenthesis[0] is used to count the parenthesis not belonging to a condition
	// (eg foo();). parenthesis in for (...) are count elsewhere in the array.
	int openParenthesisCount = 1;
	int[] openParenthesis = new int[10];

	// tokenBeforeColon is used to know what token goes along with the current :
	// it can be case or ?
	int tokenBeforeColonCount = 0;
	int[] tokenBeforeColon = new int[10];

	constructionsCount = 0; // initializes the constructions count.

	// contains DO if in a DO..WHILE statement, UNITIALIZED otherwise.
	int nlicsToken = 0;

	// fix for 1FF17XY: LFCOM:ALL - Format problem on not matching } and else 
	boolean specialElse = false;

	// OPTION (IndentationLevel): initial indentation level may be non-zero.
	currentLineIndentationLevel += constructionsCount;

	
	// An InvalidInputException exception might cause the termination of this loop.
	try {
		while (true) {
			// Get the next token.  Catch invalid input and output it
			// with minimal formatting, also catch end of input and
			// exit the loop.
			try {
				token = scanner.getNextToken();
			} catch (InvalidInputException e) {
				if (!handleInvalidToken(e)) {
					throw e;
				}
				token = 0;
			}
			if (token == Scanner.TokenNameEOF)
				break;

			/* ## MODIFYING the indentation level before generating new lines
			and indentation in the output string
			*/

			// Removes all the indentations made by statements not followed by a block
			// except if the current token is ELSE, CATCH or if we are in a switch/case

			if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) {

				switch (token) {
					case TokenNameelse :
						if (constructionsCount > 0 && constructions[constructionsCount-1] == TokenNameelse){
							pendingNewLines = 1;
							specialElse = true;
						}
						indentationLevel += popInclusiveUntil(TokenNameif);
						break;
					case TokenNamecatch :
						indentationLevel += popInclusiveUntil(TokenNamecatch);
						break;
					case TokenNamefinally :
						indentationLevel += popInclusiveUntil(TokenNamecatch);
						break;
					case TokenNamewhile :
						if (nlicsToken == TokenNamedo) {
							indentationLevel += pop(TokenNamedo);
							break;
						}
					default :
						indentationLevel += popExclusiveUntilBlockOrCase();
						// clear until a CASE, DEFAULT or BLOCK is encountered.
						// Thus, the indentationLevel is correctly cleared either
						// in a switch/case statement or in any other situation.
				}
				clearNonBlockIndents = false;
			}

			// returns to the indentation level created by the SWITCH keyword
			// if the current token is a CASE or a DEFAULT

			if (token == TokenNamecase || token == TokenNamedefault) {
				indentationLevel += pop(TokenNamecase);
			}

			if (token == Scanner.TokenNamethrows) {
				inThrowsClause = true;
			}

			if (token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface) {
				inClassOrInterfaceHeader = true;
			}
			/* ## APPEND newlines and indentations to the output string
			*/

			// Do not add a new line between ELSE and IF, if the option elseIfOnSameLine is true.
			// Fix for 1ETLWPZ: IVJCOM:ALL - incorrect "else if" formatting
			if (pendingNewlineAfterParen && previousCompilableToken == TokenNameelse && token == TokenNameif && options.compactElseIfMode){
				pendingNewlineAfterParen = false;
				pendingNewLines = 0;
				indentationLevel += pop(TokenNameelse);
				// because else if is now one single statement,
				// the indentation level after it is increased by one and not by 2
				// (else = 1 indent, if = 1 indent, but else if = 1 indent, not 2).
			}
			
			// Add a newline & indent to the formatted source string if
			// a for/if-else/while statement was scanned and there is no block
			// following it.
			
			pendingNewlineAfterParen = pendingNewlineAfterParen || (previousCompilableToken == TokenNameRPAREN && token == TokenNameLBRACE);
			if (pendingNewlineAfterParen && token != Scanner.TokenNameWHITESPACE) {
				pendingNewlineAfterParen = false;

				// Do to add a newline & indent sequence if the current token is an
				// open brace or a period or if the current token is a semi-colon and the
				// previous token is a close paren.
				// add a new line if a parenthesis belonging to a for() statement
				// has been closed and the current token is not an opening brace

				if (token != TokenNameLBRACE && !isComment(token)
				// to avoid adding new line between else and a comment
						&& token != TokenNameDOT
						&& ! (previousCompilableToken == TokenNameRPAREN
							&& token == TokenNameSEMICOLON)) {
					newLine(1);
					currentLineIndentationLevel += indentationLevel;
					pendingNewLines = 0;
					pendingSpace = false;
				} else {
					if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) {
						newLine(1);
						currentLineIndentationLevel = indentationLevel;
						pendingNewLines = 0;
						pendingSpace = false;
					}
				}
			}

			// see PR 1G5G8EC
			if (token == TokenNameLBRACE && inThrowsClause) {
				inThrowsClause = false;      
				if (options.newLineBeforeOpeningBraceMode) {
					newLine(1);
					currentLineIndentationLevel = indentationLevel;
					pendingNewLines = 0;
					pendingSpace = false;
				}
			}
			
			// see PR 1G5G82G
			if (token == TokenNameLBRACE && inClassOrInterfaceHeader) {
				inClassOrInterfaceHeader = false;
				if (options.newLineBeforeOpeningBraceMode) {
					newLine(1);
					currentLineIndentationLevel = indentationLevel;
					pendingNewLines = 0;
					pendingSpace = false;
				}
			}            
			// Add pending new lines to the formatted source string.
			// Note: pending new lines are not added if the current token
			// is a single line comment or whitespace.
			// if the comment is between parenthesis, there is no blank line preservation
			// (if it's a one-line comment, a blank line is added after it).

			if (((pendingNewLines > 0 && (!isComment(token)))
					|| (newLinesInWhitespace > 0
							&& (openParenthesisCount <= 1 && isComment(token)))
					|| (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE))
				&& token != Scanner.TokenNameWHITESPACE) {

				// Do not add newline & indent between an adjoining close brace and
				// close paren.  Anonymous inner classes may use this form.

				boolean closeBraceAndCloseParen = 
						previousToken == TokenNameRBRACE && token == TokenNameRPAREN; 

				// OPTION (NewLineInCompoundStatement): do not add newline & indent
				// between close brace and else, (do) while, catch, and finally if
				// newlineInCompoundStatement is true.

				boolean nlicsOption = 
						previousToken == TokenNameRBRACE
							&& !options.newlineInControlStatementMode
							&& (token == TokenNameelse
								|| (token == TokenNamewhile && nlicsToken == TokenNamedo)
								|| token == TokenNamecatch
								|| token == TokenNamefinally);

				// Do not add a newline & indent between a close brace and semi-colon.

				boolean semiColonAndCloseBrace = 
						previousToken == TokenNameRBRACE && token == TokenNameSEMICOLON; 

				// Do not add a new line & indent between a multiline comment and a opening brace

				boolean commentAndOpenBrace = previousToken == Scanner.TokenNameCOMMENT_BLOCK && token == TokenNameLBRACE;
				
				// Do not add a newline & indent between a close brace and a colon (in array assignments, for example).
				
				boolean commaAndCloseBrace =
						previousToken == TokenNameRBRACE && token == TokenNameCOMMA; 

				// Add a newline and indent, if appropriate.

				if (specialElse || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
					// if clearAllBlankLinesMode=false, leaves the blank lines
					// inserted by the user
					// if clearAllBlankLinesMode=true, removes all of then
					// and insert only blank lines required by the formatting.
					if (!options.clearAllBlankLinesMode) {
						pendingNewLines = 
								(pendingNewLines < newLinesInWhitespace)
//                              (isComment(token))
									? newLinesInWhitespace 
									: pendingNewLines;
						pendingNewLines = (pendingNewLines > 2) ? 2 : pendingNewLines;
					}

					if (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE) {
						containsOpenCloseBraces = true;
						indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
						if (isComment(previousToken)) {
							newLine(pendingNewLines);
						} else {
/*                          if (!(constructionsCount > 1
								&& constructions[constructionsCount-1] == NONINDENT_BLOCK
								&& (constructions[constructionsCount-2] == TokenNamefor 
									|| constructions[constructionsCount-2] == TokenNamewhile))) {*/
							if (options.newLineInEmptyBlockMode) {
								if (inArrayAssignment) {
									newLine(1); // array assigment with an empty block
								} else {
									newLine(pendingNewLines);
								}
							}
//                          }
						}
					} else {
						// see PR 1FKKC3U: LFCOM:WINNT - Format problem with a comment before the ';'
						if (!((previousToken == Scanner.TokenNameCOMMENT_BLOCK || previousToken == Scanner.TokenNameCOMMENT_JAVADOC) && token == TokenNameSEMICOLON)) {
							newLine(pendingNewLines);                       
						}
					}
					if (((previousCompilableToken == TokenNameSEMICOLON)
							|| (previousCompilableToken == TokenNameLBRACE)
							|| (previousCompilableToken == TokenNameRBRACE)
							|| (isComment(previousToken)))
						&& (token == TokenNameRBRACE)) {
						indentationOffset = -1;
						indentationLevel += popExclusiveUntilBlock();
					}

					if (previousToken == Scanner.TokenNameCOMMENT_LINE && inAssignment) {
						// PR 1FI5IPO
						currentLineIndentationLevel++;
					} else {
						currentLineIndentationLevel = indentationLevel + indentationOffset;
					}

					pendingSpace = false;
					indentationOffset = 0;
				}
				pendingNewLines = 0;
				newLinesInWhitespace = 0;
				specialElse = false;

				if (nlicsToken == TokenNamedo && token == TokenNamewhile) {
					nlicsToken = 0;
				}
			}

			switch (token) {
				case TokenNameelse :
				case TokenNamefinally :
					expectingOpenBrace = true;
					pendingNewlineAfterParen = true;
					indentationLevel += pushControlStatement(token);
					break;
				case TokenNamecase :
				case TokenNamedefault :
					if (tokenBeforeColonCount == tokenBeforeColon.length) {
						System.arraycopy(
								tokenBeforeColon, 
								0, 
								(tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 
								0, 
								tokenBeforeColonCount); 
					}
					tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase;
					indentationLevel += pushControlStatement(TokenNamecase);
					break;
				case TokenNameQUESTION :
					if (tokenBeforeColonCount == tokenBeforeColon.length) {
						System.arraycopy(
								tokenBeforeColon, 
								0, 
								(tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 
								0, 
								tokenBeforeColonCount); 
					}
					tokenBeforeColon[tokenBeforeColonCount++] = token;
					break;
				case TokenNameswitch :
				case TokenNamefor :
				case TokenNameif :
				case TokenNamewhile :
					if (openParenthesisCount == openParenthesis.length) {
						System.arraycopy(
								openParenthesis, 
								0, 
								(openParenthesis = new int[openParenthesisCount * 2]), 
								0, 
								openParenthesisCount); 
					}
					openParenthesis[openParenthesisCount++] = 0;
					expectingOpenBrace = true;
					
					indentationLevel += pushControlStatement(token);
					break;
				case TokenNametry :
					pendingNewlineAfterParen = true;
				case TokenNamecatch :
					// several CATCH statements can be contiguous.
					// a CATCH is encountered pop until first CATCH (if a CATCH follows a TRY it works the same way,
					// as CATCH and TRY are the same token in the stack).
					expectingOpenBrace = true;
					indentationLevel += pushControlStatement(TokenNamecatch);
					break;

				case TokenNamedo :
					expectingOpenBrace = true;
					indentationLevel += pushControlStatement(token);
					nlicsToken = token;
					break;
				case TokenNamenew :

					// The flag inAssigment is used to properly format
					// array assignments, and if a non-array assignment
					// statement is in progress, it is no longer
					// beneficial to know this, so set the flag to false.

/*                  if (!inArrayAssignment) {
						inAssignment = false;
					}*/
					break;
				case TokenNameLPAREN :

					// Put a space between the previous and current token if the
					// previous token was not a keyword, open paren, logical
					// compliment (eg: !), semi-colon, open brace, close brace,
					// super, or this.

					if (previousCompilableToken != TokenNameLBRACKET
						&& previousToken != TokenNameIdentifier
						&& previousToken != 0
						&& previousToken != TokenNameNOT
						&& previousToken != TokenNameLPAREN
						&& previousToken != TokenNameTWIDDLE
						&& previousToken != TokenNameSEMICOLON
						&& previousToken != TokenNameLBRACE
						&& previousToken != TokenNameRBRACE
						&& previousToken != TokenNamesuper
						&& previousToken != TokenNamethis) {
						space();
					}

					// If in a for/if/while statement, increase the parenthesis count
					// for the current openParenthesisCount
					// else increase the count for stand alone parenthesis.
					if (openParenthesisCount > 0)
						openParenthesis[openParenthesisCount - 1]++;
					else
						openParenthesis[0]++;

					pendingSpace = false;
					break;
				case TokenNameRPAREN :

					// Decrease the parenthesis count
					// if there is no more unclosed parenthesis,
					// a new line and indent may be append (depending on the next token).

					if ((openParenthesisCount > 1)
						&& (openParenthesis[openParenthesisCount - 1] > 0)) {
						openParenthesis[openParenthesisCount - 1]--;
						if (openParenthesis[openParenthesisCount - 1] <= 0) {
							pendingNewlineAfterParen = true;
							inAssignment = false;
							openParenthesisCount--;

						}
					} else {
						openParenthesis[0]--;
					}

					pendingSpace = false;
					break;
				case TokenNameLBRACE :
					if ((previousCompilableToken == TokenNameRBRACKET) || (previousCompilableToken == TokenNameEQUAL)) {
//                  if (previousCompilableToken == TokenNameRBRACKET) {
						inArrayAssignment = true;
						inAssignment = false;
					}
					if (inArrayAssignment) {
						indentationLevel += pushBlock();
					} else {
						// Add new line and increase indentation level after open brace.
						pendingNewLines = 1;
						indentationLevel += pushBlock();
					}
					break;
				case TokenNameRBRACE :
					if (previousCompilableToken == TokenNameRPAREN) {
						pendingSpace = false;
					}
					if (inArrayAssignment) {
						inArrayAssignment = false;
						pendingNewLines = 1;
						indentationLevel += popInclusiveUntilBlock();
					} else {
						pendingNewLines = 1;
						indentationLevel += popInclusiveUntilBlock();

						if (previousCompilableToken == TokenNameRPAREN){
							// fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression
							currentLineBuffer.append(options.lineSeparatorSequence);
							increaseLineDelta(options.lineSeparatorSequence.length);                            
						}

						if (constructionsCount > 0) {
							switch (constructions[constructionsCount - 1]) {
								case TokenNamefor :
									//indentationLevel += popExclusiveUntilBlock();
									//break;
								case TokenNameswitch :
								case TokenNameif :
								case TokenNameelse :
								case TokenNametry :
								case TokenNamecatch :
								case TokenNamefinally :
								case TokenNamewhile :
								case TokenNamedo :
									clearNonBlockIndents = true;
								default :
									break;
							}
						}

					}
					break;
				case TokenNameLBRACKET :
					openBracketCount++;
					pendingSpace = false;
					break;
				case TokenNameRBRACKET :
					openBracketCount-=(openBracketCount>0)?1:0;
					// if there is no left bracket to close, the right bracket is ignored.
					pendingSpace = false;
					break;
				case TokenNameCOMMA :
				case TokenNameDOT :
					pendingSpace = false;
					break;
				case TokenNameSEMICOLON :

					// Do not generate line terminators in the definition of
					// the for statement.
					// if not in this case, jump a line and reduce indentation after the brace
					// if the block it closes belongs to a conditional statement (if, while, do...).

					if (openParenthesisCount <= 1) {
						pendingNewLines = 1;
						if (expectingOpenBrace) {
							clearNonBlockIndents = true;
							expectingOpenBrace = false;
						}
					}
					inAssignment = false;
					pendingSpace = false;
					break;
				case TokenNamePLUS_PLUS :
				case TokenNameMINUS_MINUS :

					// Do not put a space between a post-increment/decrement
					// and the identifier being modified.

					if (previousToken == TokenNameIdentifier
						|| previousToken == TokenNameRBRACKET) {
						pendingSpace = false;
					}
					break;
				case TokenNamePLUS : // previously ADDITION
				case TokenNameMINUS :

					// Handle the unary operators plus and minus via a 3-state flag.

					if (!isLiteralToken(previousToken)
						&& previousToken != TokenNameIdentifier
						&& previousToken != TokenNameRPAREN
						&& previousToken != TokenNameRBRACKET) {
						unarySignModifier = 2;
					}
					break;
				case TokenNameCOLON :

					// In a switch/case statement, add a newline & indent
					// when a colon is encountered.
					if (tokenBeforeColonCount > 0) {
						if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) {
							pendingNewLines = 1;
						}
						tokenBeforeColonCount--;
					}
					break;
				case TokenNameEQUAL :
					inAssignment = true;
					break;
				case Scanner.TokenNameCOMMENT_LINE :
					pendingNewLines = 1;
					if (inAssignment) {
						currentLineIndentationLevel++;
					}
					break; // a line is always inserted after a one-line comment
				case Scanner.TokenNameCOMMENT_JAVADOC :
				case Scanner.TokenNameCOMMENT_BLOCK :
					currentCommentOffset = getCurrentCommentOffset();
					if (openParenthesis[0]==0 && openBracketCount < 1){
						pendingNewLines = 1;
						// a new line is inserted only if the comment is not between parenthesis.
					}
					break;
				case Scanner.TokenNameWHITESPACE :

					// Count the number of line terminators in the whitespace so
					// line spacing can be preserved near comments.

					char[] source = scanner.source;
					newLinesInWhitespace = 0;
					for (
						int i = scanner.startPosition, max = scanner.currentPosition; 
						i < max; 
						i++) {
						if (source[i] == '\n') {
							newLinesInWhitespace++;
						}
					}
					increaseLineDelta(scanner.startPosition - scanner.currentPosition);
					break;
				default :
					if ((token == TokenNameIdentifier)
						|| isLiteralToken(token)
						|| token == TokenNamesuper
						|| token == TokenNamethis) {

						// Do not put a space between a unary operator
						// (eg: ++, --, +, -) and the identifier being modified.

						unarySignModifier -= (unarySignModifier > 0) ? 1 : 0;
						if (previousToken == TokenNamePLUS_PLUS
							|| previousToken == TokenNameMINUS_MINUS
							|| (unarySignModifier > 0)) {
							pendingSpace = false;
						}
					}
					break;
			}

			// Do not output whitespace tokens.

			if (token != Scanner.TokenNameWHITESPACE) {

				/* Add pending space to the formatted source string.
				Do not output a space under the following circumstances:
				1) this is the first pass
				2) previous token is an open paren
				3) previous token is a period
				4) previous token is the logical compliment (eg: !)
				5) previous token is the bitwise compliment (eg: ~)
				6) previous token is the open bracket (eg: [)
				7) in an assignment statement, if the previous token is an 
				open brace or the current token is a close brace
				8) previous token is a single line comment
				*/

				boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE;

				// to be replaced by a nicer condition.
			
				if (pendingSpace
					&& insertSpaceAfter(previousToken)
					&& ! (inAssignment
						&& (previousToken == TokenNameLBRACE || token == TokenNameRBRACE))
					&& previousToken != Scanner.TokenNameCOMMENT_LINE) {
					if ((! (options.compactAssignmentMode && token == TokenNameEQUAL)) && !openAndCloseBrace)
						space();
				}

				// Add the next token to the formatted source string.

				outputCurrentToken(token);
				if (token == Scanner.TokenNameCOMMENT_LINE && openParenthesisCount > 1){
					pendingNewLines = 0;
					currentLineBuffer.append(options.lineSeparatorSequence);
					increaseLineDelta(options.lineSeparatorSequence.length);                    
				}
				pendingSpace = true;
			}

			// Whitespace tokens do not need to be remembered.

			if (token != Scanner.TokenNameWHITESPACE) {
				previousToken = token;
				if (token != Scanner.TokenNameCOMMENT_BLOCK
					&& token != Scanner.TokenNameCOMMENT_LINE
					&& token != Scanner.TokenNameCOMMENT_JAVADOC) {
					previousCompilableToken = token;
				}
			}

		}
		output(copyRemainingSource());
		flushBuffer(); // dump the last token of the source in the formatted output.
	} catch (InvalidInputException e) {
		output(copyRemainingSource());
		flushBuffer(); // dump the last token of the source in the formatted output.
	}
}
/** 
 * Formats a given source string, starting indenting it at depth 0
 * using default options.
 */
public static String format(String sourceString) {
	return format(sourceString, 0, null);
}
/** 
 * Formats a given source string, starting indenting it at a particular 
 * depth and using the given options
 */
public static String format(String sourceString, int initialIndentationLevel, ConfigurableOption[] options) {
	CodeFormatter formatter = new CodeFormatter(options);
	formatter.setInitialIndentationLevel(initialIndentationLevel);
	return formatter.formatSourceString(sourceString);
}
/** 
 * Formats the char array <code>sourceString</code>,
 * and returns a string containing the formatted version.
 * @return the formatted ouput.
 */
public String formatSourceString(String sourceString) {
	char[] sourceChars = sourceString.toCharArray();
	formattedSource = new StringBuffer(sourceChars.length);
	scanner.setSourceBuffer(sourceChars);
	format();
	return formattedSource.toString();
}
/**
 * Returns the number of characters and tab char between the beginning of the line
 * and the beginning of the comment.
 */
private int getCurrentCommentOffset() {
	int linePtr = scanner.linePtr;
	// if there is no beginning of line, return 0.
	if (linePtr < 0)
		return 0;
	int offset = 0;
	int beginningOfLine = scanner.lineEnds[linePtr];
	int currentStartPosition = scanner.startPosition;
	char[] source = scanner.source;
	
	// find the position of the beginning of the line containing the comment
	while (beginningOfLine > currentStartPosition) {
		if (linePtr > 0) {
			beginningOfLine = scanner.lineEnds[--linePtr];
		} else {
			beginningOfLine = 0;
			break;
		}
	}

	for (int i = beginningOfLine ; i < currentStartPosition ; i++){
		char currentCharacter = source[i];
		switch(currentCharacter){
			case '\t':
				offset += options.tabSize;
			case '\n':
			case '\r':
				break;
			default:
				offset++;
		}
	}
	
	return offset;
}
/**
 * Returns an array of descriptions for the configurable options.
 * The descriptions may be changed and passed back to a different
 * compiler.
 */
public static ConfigurableOption[] getDefaultOptions(Locale locale) {
	return new FormatterOptions().getConfigurableOptions(locale);
}
/**
 * Returns the array of mapped positions.
 * Returns null is no positions have been set.
 * @return int[]
 */
public int[] getMappedPositions() {
	return mappedPositions;
}
/**
 * Returns the priority of the token given as argument<br>
 * The most prioritary the token is, the smallest the return value is.
 * @return the priority of <code>token</code>
 * @param token the token of which the priority is requested
 */
private static int getTokenPriority(int token) {
	switch (token) {
		case TokenNameextends:
		case TokenNameimplements:
		case TokenNamethrows:
			return 10;
		case TokenNameSEMICOLON : // ;
			return 20; 
		case TokenNameCOMMA : // ,
			return 25;
		case TokenNameEQUAL : // =
			return 30; 
		case TokenNameAND_AND : // && 
		case TokenNameOR_OR : // || 
			return 40;
		case TokenNameQUESTION : // ? 
		case TokenNameCOLON : // :
			return 50; // it's better cutting on ?: than on ;
		case TokenNameEQUAL_EQUAL : // == 
		case TokenNameNOT_EQUAL : // != 
			return 60;
		case TokenNameLESS : // < 
		case TokenNameLESS_EQUAL : // <= 
		case TokenNameGREATER : // > 
		case TokenNameGREATER_EQUAL : // >= 
		case TokenNameinstanceof : // instanceof
			return 70;
		case TokenNamePLUS : // + 
		case TokenNameMINUS : // - 
			return 80;
		case TokenNameMULTIPLY : // * 
		case TokenNameDIVIDE : // / 
		case TokenNameREMAINDER : // % 
			return 90;
		case TokenNameLEFT_SHIFT : // << 
		case TokenNameRIGHT_SHIFT : // >> 
		case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> 
			return 100;
		case TokenNameAND : // &
		case TokenNameOR : // | 
		case TokenNameXOR : // ^ 
			return 110;
		case TokenNameMULTIPLY_EQUAL : // *= 
		case TokenNameDIVIDE_EQUAL : // /= 
		case TokenNameREMAINDER_EQUAL : // %= 
		case TokenNamePLUS_EQUAL : // += 
		case TokenNameMINUS_EQUAL : // -= 
		case TokenNameLEFT_SHIFT_EQUAL : // <<= 
		case TokenNameRIGHT_SHIFT_EQUAL : // >>= 
		case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>=
		case TokenNameAND_EQUAL : // &= 
		case TokenNameXOR_EQUAL : // ^= 
		case TokenNameOR_EQUAL : // |= 
			return 120;
		case TokenNameDOT : // .
			return 130;
		default :
			return Integer.MAX_VALUE;
	}
}
/**
 * Handles the exception raised when an invalid token is encountered.
 * Returns true if the exception has been handled, false otherwise.
 */
private boolean handleInvalidToken(Exception e) {
	if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT)
		|| e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING)
		|| e.getMessage().equals(Scanner.INVALID_ESCAPE)) {
		return true;
	}
		return false;
}
private final void increaseGlobalDelta(int offset) {
	globalDelta += offset;
}
private final void increaseLineDelta(int offset) {
	lineDelta += offset;
}
private final void increaseSplitDelta(int offset) {
	splitDelta += offset;
}
/**
 * Returns true if a space has to be inserted after <code>operator</code>
 * false otherwise.
 */
private boolean insertSpaceAfter(int token) {
	switch (token){
		case TokenNameLPAREN:
		case TokenNameNOT:
		case TokenNameTWIDDLE:
		case TokenNameDOT :
		case 0: // no token
		case TokenNameLBRACKET:
		case Scanner.TokenNameCOMMENT_LINE:
			return false;
		default:
			return true;
	}
		
}
/**
 * Returns true if a space has to be inserted before <code>operator</code>
 * false otherwise.<br>
 * Cannot be static as it uses the code formatter options
 * (to know if the compact assignment mode is on).
 */
private boolean insertSpaceBefore(int token) {
	switch (token) {
		case TokenNameEQUAL:
			return (!options.compactAssignmentMode);
		default :
			return false;
	}
}
private static boolean isComment(int token) {
	boolean result =
	token == Scanner.TokenNameCOMMENT_BLOCK ||
	token == Scanner.TokenNameCOMMENT_LINE ||
	token == Scanner.TokenNameCOMMENT_JAVADOC;
	return result;
}
private static boolean isLiteralToken(int token) {
	boolean result =
		  token == TokenNameIntegerLiteral ||
		  token == TokenNameLongLiteral ||
		  token == TokenNameFloatingPointLiteral ||
		  token == TokenNameDoubleLiteral ||
		  token == TokenNameCharacterLiteral ||
		  token == TokenNameStringLiteral;
	return result;
}
/**
 * If the length of <code>oneLineBuffer</code> exceeds <code>maxLineLength</code>,
 * it is split and the result is dumped in <code>formattedSource</code>
 * @param newLineCount the number of new lines to append
 */
private void newLine(int newLineCount) {

	// format current line
	splitDelta = 0;
	beginningOfLineIndex = formattedSource.length();
	String currentLine = currentLineBuffer.toString();
	if (containsOpenCloseBraces) {
		containsOpenCloseBraces = false;
		outputLine(currentLine,
			false,
			indentationLevelForOpenCloseBraces,
			0,
			-1,
			null,
			0);
		indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
	} else {
		outputLine(currentLine,
			false,
			currentLineIndentationLevel,
			0,
			-1,
			null,
			0);
	}
	// dump line break(s)
	for (int i = 0; i < newLineCount; i++) {
		formattedSource.append(options.lineSeparatorSequence);
		increaseSplitDelta(options.lineSeparatorSequence.length);
	}
	// reset formatter for next line
	int currentLength = currentLine.length();
	currentLineBuffer = new StringBuffer(
							currentLength > maxLineSize
								? maxLineSize = currentLength
								: maxLineSize);
	
	increaseGlobalDelta(splitDelta);
	increaseGlobalDelta(lineDelta);
	lineDelta = 0;
	currentLineIndentationLevel = initialIndentationLevel;
}
private String operatorString(int operator) {
	switch (operator) {
		case TokenNameextends :
			return "extends"/*nonNLS*/;

		case TokenNameimplements :
			return "implements"/*nonNLS*/;

		case TokenNamethrows :
			return "throws"/*nonNLS*/;

		case TokenNameSEMICOLON : // ;
			return ";"/*nonNLS*/;

		case TokenNameCOMMA : // ,
			return ","/*nonNLS*/;

		case TokenNameEQUAL : // =
			return "="/*nonNLS*/;

		case TokenNameAND_AND : // && (15.22)
			return "&&"/*nonNLS*/;

		case TokenNameOR_OR : // || (15.23)
			return "||"/*nonNLS*/;

		case TokenNameQUESTION : // ? (15.24)
			return "?"/*nonNLS*/;

		case TokenNameCOLON : // : (15.24)
			return ":"/*nonNLS*/;

		case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
			return "=="/*nonNLS*/;

		case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
			return "!="/*nonNLS*/;

		case TokenNameLESS : // < (15.19.1)
			return "<"/*nonNLS*/;

		case TokenNameLESS_EQUAL : // <= (15.19.1)
			return "<="/*nonNLS*/;

		case TokenNameGREATER : // > (15.19.1)
			return ">"/*nonNLS*/;

		case TokenNameGREATER_EQUAL : // >= (15.19.1)
			return ">="/*nonNLS*/;

		case TokenNameinstanceof : // instanceof
			return "instanceof"/*nonNLS*/;

		case TokenNamePLUS : // + (15.17, 15.17.2)
			return "+"/*nonNLS*/;

		case TokenNameMINUS : // - (15.17.2)
			return "-"/*nonNLS*/;

		case TokenNameMULTIPLY : // * (15.16.1)
			return "*"/*nonNLS*/;

		case TokenNameDIVIDE : // / (15.16.2)
			return "/"/*nonNLS*/;

		case TokenNameREMAINDER : // % (15.16.3)
			return "%"/*nonNLS*/;

		case TokenNameLEFT_SHIFT : // << (15.18)
			return "<<"/*nonNLS*/;

		case TokenNameRIGHT_SHIFT : // >> (15.18)
			return ">>"/*nonNLS*/;

		case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
			return ">>>"/*nonNLS*/;

		case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
			return "&"/*nonNLS*/;

		case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
			return "|"/*nonNLS*/;

		case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
			return "^"/*nonNLS*/;

		case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
			return "*="/*nonNLS*/;

		case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
			return "/="/*nonNLS*/;

		case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
			return "%="/*nonNLS*/;

		case TokenNamePLUS_EQUAL : // += (15.25.2)
			return "+="/*nonNLS*/;

		case TokenNameMINUS_EQUAL : // -= (15.25.2)
			return "-="/*nonNLS*/;

		case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
			return "<<="/*nonNLS*/;

		case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
			return ">>="/*nonNLS*/;

		case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
			return ">>>="/*nonNLS*/;

		case TokenNameAND_EQUAL : // &= (15.25.2)
			return "&="/*nonNLS*/;

		case TokenNameXOR_EQUAL : // ^= (15.25.2)
			return "^="/*nonNLS*/;

		case TokenNameOR_EQUAL : // |= (15.25.2)
			return "|="/*nonNLS*/;

		case TokenNameDOT : // .
			return "."/*nonNLS*/;

		default :
			return ""/*nonNLS*/;
	}
}
/** 
 * Appends <code>stringToOutput</code> to the formatted output.<br>
 * If it contains \n, append a LINE_SEPARATOR and indent after it.
 */
private void output(String stringToOutput) {
	char currentCharacter;
	for (int i = 0, max = stringToOutput.length(); i < max; i++) {
		currentCharacter = stringToOutput.charAt(i);
		if (currentCharacter != '\t') {
			currentLineBuffer.append(currentCharacter);
		}
	}
	updateMappedPositions(scanner.startPosition);
}
/** 
 * Appends <code>token</code> to the formatted output.<br>
 * If it contains <code>\n</code>, append a LINE_SEPARATOR and indent after it.
 */
private void outputCurrentToken(int token) {
	char[] source = scanner.source;
	int startPosition = scanner.startPosition;

	switch(token) {
		case Scanner.TokenNameCOMMENT_JAVADOC :
		case Scanner.TokenNameCOMMENT_BLOCK :
		case Scanner.TokenNameCOMMENT_LINE :
			boolean endOfLine = false;
			int currentCommentOffset = getCurrentCommentOffset();
			int beginningOfLineSpaces = 0;
			for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
				char currentCharacter = source[i];
				switch(currentCharacter) {
					case '\r' :
					case '\n' :
						 endOfLine = true;
						 currentLineBuffer.append(currentCharacter);
						 beginningOfLineSpaces = 0;
						 break;
					case '\t' :
						if (endOfLine) {
							// we remove a maximum of currentCommentOffset characters (tabs are converted to space numbers).
							beginningOfLineSpaces+=options.tabSize;
							if (beginningOfLineSpaces > currentCommentOffset)
								currentLineBuffer.append(currentCharacter);						
						} else {
							currentLineBuffer.append(currentCharacter);
						}
						break;
					case ' ' :
						if (endOfLine) {
							// we remove a maximum of currentCommentOffset characters (tabs are converted to space numbers).
							beginningOfLineSpaces++;
							if (beginningOfLineSpaces > currentCommentOffset)
								currentLineBuffer.append(currentCharacter);						
						} else {
							currentLineBuffer.append(currentCharacter);
						}
						break;
					default:
						beginningOfLineSpaces = 0;
						currentLineBuffer.append(currentCharacter);
						endOfLine = false;
				}
			}
			break;
		default:
			currentLineBuffer.append(source, startPosition, scanner.currentPosition - startPosition);
	}
	updateMappedPositions(startPosition);
}
/**
 * Outputs <code>currentString</code>:<br>
 * <ul><li>If its length is < maxLineLength, output
 * <li>Otherwise it is split.</ul>
 * @param currentString string to output
 * @param preIndented whether the string to output was pre-indented
 * @param depth number of indentation to put in front of <code>currentString</code>
 * @param operator value of the operator belonging to <code>currentString</code>.
 */
private void outputLine(
	String currentString, 
	boolean preIndented, 
	int depth, 
	int operator, 
	int substringIndex, 
	int[] startSubstringIndexes, 
	int offsetInGlobalLine) {

	boolean emptyFirstSubString = false;
	String operatorString = operatorString(operator);
	boolean placeOperatorBehind = !breakLineBeforeOperator(operator);
	boolean placeOperatorAhead = !placeOperatorBehind;

	// dump prefix operator?
	if (placeOperatorAhead) {
		if (!preIndented) {
			dumpTab(depth);
			preIndented = true;
		}
		if (operator != 0) {
			if (insertSpaceBefore(operator)) {
				formattedSource.append(' ');
				increaseSplitDelta(1);
			}
			formattedSource.append(operatorString);
			increaseSplitDelta(operatorString.length());

			if (insertSpaceAfter(operator)
				&& operator != TokenNameimplements
				&& operator != TokenNameextends
				&& operator != TokenNamethrows) {
				formattedSource.append(' ');
				increaseSplitDelta(1);
			}
		}
	}
	SplitLine splitLine = null;
	if (options.maxLineLength == 0
		|| currentString.length() < options.maxLineLength
		|| (splitLine = split(currentString, offsetInGlobalLine)) == null) {
		// depending on the type of operator, outputs new line before of after dumping it
		// indent before postfix operator
		// indent also when the line cannot be split

		if (operator == TokenNameextends
			|| operator == TokenNameimplements
			|| operator == TokenNamethrows) {
			formattedSource.append(' ');
			increaseSplitDelta(1);
		}

		if (placeOperatorBehind) {
			if (!preIndented) {
				dumpTab(depth);
			}
		}

		boolean containsMultiLineComment = currentString.lastIndexOf("/*"/*nonNLS*/) != -1;
		int numberOfSpaces = 0;
		int max = currentString.length();
		updateMappedPositionsWhileSplitting(
			beginningOfLineIndex, 
			beginningOfLineIndex + max); 
		for (int i = 0; i < max; i++) {
			char currentChar = currentString.charAt(i);
			switch (currentChar) {
				case '\r' :
					break;
				case '\n' :
					if (i != max - 1) {
						// fix for 1FFYL5C: LFCOM:ALL - Incorrect indentation when split with a comment inside a condition
						// a substring cannot end with a lineSeparatorSequence,
						// except if it has been added by format() after a one-line comment
						formattedSource.append(options.lineSeparatorSequence);
						increaseSplitDelta(options.lineSeparatorSequence.length);

						if (containsMultiLineComment) {
							// fix for 1FGGQCN: LFCOM:ALL - Space management in comments for the formatter
							dumpTab(currentLineIndentationLevel);
						} else {
							// 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression
							dumpTab(depth - 1);
						}
					}
					break;
				default :
					formattedSource.append(currentChar);
			}
		}

		// update positions inside the mappedPositions table
		if (substringIndex != -1) {
			int startPosition = 
				beginningOfLineIndex + startSubstringIndexes[substringIndex]; 
			updateMappedPositionsWhileSplitting(startPosition, startPosition + max);

			// compute the splitDelta resulting with the operator and blank removal
			if (substringIndex + 1 != startSubstringIndexes.length) {
				increaseSplitDelta(
					startSubstringIndexes[substringIndex]
						+ max
						- startSubstringIndexes[substringIndex
						+ 1]); 
			}
		}
		// dump postfix operator?
		if (placeOperatorBehind) {
			if (insertSpaceBefore(operator)) {
				formattedSource.append(' ');
				if (operator != 0) {
					increaseSplitDelta(1);
				}
			}
			formattedSource.append(operatorString);
			if (operator != 0) {
				increaseSplitDelta(operatorString.length());
			}
		}
		return;
	}

	// fix for 1FG0BA3: LFCOM:WIN98 - Weird splitting on interfaces
	// extends has to stand alone on a line when currentString has been split.
	if (options.maxLineLength != 0
		&& splitLine != null
		&& (operator == TokenNameextends
			|| operator == TokenNameimplements
			|| operator == TokenNamethrows)) {
		formattedSource.append(options.lineSeparatorSequence);
		increaseSplitDelta(options.lineSeparatorSequence.length);

		dumpTab(depth + 1);
	} else {
		if (operator == TokenNameextends
			|| operator == TokenNameimplements
			|| operator == TokenNamethrows) {
			formattedSource.append(' ');
			increaseSplitDelta(1);
		}
	}

	// perform actual splitting
	String result[] = splitLine.substrings;
	int[] splitOperators = splitLine.operators;
	int[] splitLineStartIndexes = splitLine.startSubstringsIndexes;

	if (result[0].length() == 0) {
		// when the substring 0 is null, the substring 1 is correctly indented.
		depth--;
		emptyFirstSubString = true;
	}
	// the operator going in front of the result[0] string is the operator parameter

	for (int i = 0, max = result.length; i < max; i++) {
		// the new depth is the current one if this is the first substring,
		// the current one + 1 otherwise.

		// if the substring is a comment, use the current indentation Level instead of the depth
		// (-1 because the ouputline increases depth).
		// (fix for 1FFC72R: LFCOM:ALL - Incorrect line split in presence of line comments)
		String currentResult = result[i];

		if (currentResult.length() != 0 || splitOperators[i] != 0) {
			int newDepth = 
				(currentResult.startsWith("/*"/*nonNLS*/) || currentResult.startsWith("//"/*nonNLS*/))
					? indentationLevel - 1
					: depth; 
			outputLine(
				currentResult, 
				i == 0 || (i == 1 && emptyFirstSubString) ? preIndented : false, 
				i == 0 ? newDepth : newDepth + 1, 
				splitOperators[i], 
				i, 
				splitLine.startSubstringsIndexes, 
				currentString.indexOf(currentResult)); 
			if (i != max - 1) {
				formattedSource.append(options.lineSeparatorSequence);
				increaseSplitDelta(options.lineSeparatorSequence.length);
			}
		}
	}
	if (result.length == splitOperators.length - 1) {
	    int lastOperator = splitOperators[result.length];
	    String lastOperatorString = operatorString(lastOperator);
		formattedSource.append(options.lineSeparatorSequence);
		increaseSplitDelta(options.lineSeparatorSequence.length);

		if (breakLineBeforeOperator(lastOperator)) {
			dumpTab(depth + 1);
			if (lastOperator != 0) {
				if (insertSpaceBefore(lastOperator)) {
					formattedSource.append(' ');
					increaseSplitDelta(1);
				}
				formattedSource.append(lastOperatorString);
				increaseSplitDelta(lastOperatorString.length());

				if (insertSpaceAfter(lastOperator)
					&& lastOperator != TokenNameimplements
					&& lastOperator != TokenNameextends
					&& lastOperator != TokenNamethrows) {
					formattedSource.append(' ');
					increaseSplitDelta(1);
				}
			}
		}
	}
	if (placeOperatorBehind) {
		if (insertSpaceBefore(operator)) {
			formattedSource.append(' ');
			increaseSplitDelta(1);
		}
		formattedSource.append(operatorString);
		//increaseSplitDelta(operatorString.length());
	}
}
/**
 * Pops the top statement of the stack if it is <code>token</code>
 */
private int pop(int token) {
	int delta=0;
	if ((constructionsCount>0) && (constructions[constructionsCount-1]==token)){
		delta--;
		constructionsCount--;
	}
	return delta;
}
/**
 * Pops the top statement of the stack if it is a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.
 */
private int popBlock() {
	int delta=0;
	if ((constructionsCount>0) && ((constructions[constructionsCount-1]==BLOCK) || (constructions[constructionsCount-1]==NONINDENT_BLOCK))){
		if (constructions[constructionsCount-1]==BLOCK)
			delta--;
		constructionsCount--;
	}
	return delta;
}
/**
 * Pops elements until the stack is empty or the top element is <code>token</code>.<br>
 * Does not remove <code>token</code> from the stack.
 * @param token the token to be left as the top of the stack
 */
private int popExclusiveUntil(int token) {
	int delta=0;
	int startCount=constructionsCount;
	for (int i = startCount-1; i >= 0 && constructions[i] != token; i--){
		if (constructions[i]!=NONINDENT_BLOCK)
			delta--;
		constructionsCount--;
	}
	return delta;
}
/**
 * Pops elements until the stack is empty or the top element is
 * a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
 * Does not remove it from the stack.
 */
private int popExclusiveUntilBlock(){
	int startCount=constructionsCount;
	int delta=0;
	for (int i = startCount-1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK; i--){
		constructionsCount--;
		delta--;
	}
	return delta;
}
/**
 * Pops elements until the stack is empty or the top element is
 * a <code>BLOCK</code>, a <code>NONINDENT_BLOCK</code> or a <code>CASE</code>.<br>
 * Does not remove it from the stack.
 */
private int popExclusiveUntilBlockOrCase(){
	int startCount=constructionsCount;
	int delta=0;
	for (int i = startCount-1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK && constructions[i]!=TokenNamecase; i--){
		constructionsCount--;
		delta--;
	}
	return delta;
}
/**
 * Pops elements until the stack is empty or the top element is <code>token</code>.<br>
 * Removes <code>token</code> from the stack too.
 * @param token the token to remove from the stack
 */
private int popInclusiveUntil(int token) {
	int startCount=constructionsCount;
	int delta=0;
	for (int i = startCount-1; i >= 0 && constructions[i] != token; i--){
		if (constructions[i]!=NONINDENT_BLOCK)
			delta--;
		constructionsCount--;
	}
	if (constructionsCount>0){
		if (constructions[constructionsCount-1]!=NONINDENT_BLOCK)
			delta--;
		constructionsCount--;
	}
	return delta;
}
/**
 * Pops elements until the stack is empty or the top element is
 * a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
 * Does not remove it from the stack.
 */
private int popInclusiveUntilBlock() {
	int startCount=constructionsCount;
	int delta=0;
	for (int i = startCount-1; i >= 0 && (constructions[i] != BLOCK && constructions[i]!=NONINDENT_BLOCK); i--){
		delta--;
		constructionsCount--;
	}
	if (constructionsCount>0){
		if (constructions[constructionsCount-1]==BLOCK)
			delta--;
		constructionsCount--;
	}
	return delta;
}
/** 
 * Pushes a block in the stack.<br>
 * Pushes a <code>BLOCK</code> if the stack is empty or if the top element is a <code>BLOCK</code>,
 * pushes <code>NONINDENT_BLOCK</code> otherwise.
 * Creates a new bigger array if the current one is full.
 */
private int pushBlock() {
	int delta = 0;
	if (constructionsCount == constructions.length)
		System
				.arraycopy(constructions, 
					0, 
					(constructions = new int[constructionsCount * 2]), 
					0, 
					constructionsCount); 

	if ((constructionsCount == 0)
		|| (constructions[constructionsCount - 1] == BLOCK)
		|| (constructions[constructionsCount - 1] == NONINDENT_BLOCK)
		|| (constructions[constructionsCount - 1] == TokenNamecase)) {
		delta++;
		constructions[constructionsCount++] = BLOCK;
	}
	else {
		constructions[constructionsCount++] = NONINDENT_BLOCK;
	}
	return delta;
}
/** 
 * Pushes <code>token</code>.<br>
 * Creates a new bigger array if the current one is full.
 */
private int pushControlStatement(int token) {
	if (constructionsCount == constructions.length)
		System.arraycopy(constructions, 0, (constructions = new int[constructionsCount * 2]), 0, constructionsCount);
	constructions[constructionsCount++] = token;
	return 1;
}
private static boolean separateFirstArgumentOn(int currentToken) {
	//return (currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON);
	return currentToken != TokenNameif
		&& currentToken != TokenNameLPAREN
		&& currentToken != TokenNameNOT
		&& currentToken != TokenNamewhile
		&& currentToken != TokenNamefor
		&& currentToken != TokenNameswitch; 
}
/** 
 * Sets the behaviour of the formatter about the braces
 * using <coe>newBraceIndentationLevel</code><br>
 * <ul>
 * <li>if 0, the formatter add new line & indent
 * when current token is open brace,
 * remove extra indentation when current token is close brace.
 * <li>if -1, the formatter does not add a new line before the brace.</ul>
 *
 * @deprecated backward compatibility with VAJ APIs,
 * use addNewLineOnOpeningBrace(boolean) instead
 * @see addNewLineOnOpeningBrace(boolean)
 */
public void setBraceIndentationLevel(int newBraceIndentationLevel) {
	options.setNewLineBeforeOpeningBraceMode(newBraceIndentationLevel==0);
}
/**
 * Sets the behaviour of the formatter regarding the whitespaces
 * in the string to format.
 * @param newClearBlankLines true if the blank lines can be wiped out
 * false otherwise.
 *
 * @deprecated backward compatibility with VAJ
 */
public void setClearBlankLines(boolean newClearBlankLines) {
	options.setClearAllBlankLinesMode(newClearBlankLines);
}
/** 
 * Sets the number of consecutive spaces used to replace the tab char
 * if <code>newIndentationLength</code> is greater than one.<br>
 * @param newIndentationLength 1 if 1 indent = 1 tab char, n>1 if 1 indent = n consecutive spaces.
 * 
 * @deprecated backward compatibility with VAJ
 */
public void setIndentationLength(int newIndentationLength) {
	options.setTabSize(newIndentationLength);
}
/** 
 * Sets the initial indentation level
 * @param indentationLevel new indentation level
 * 
 * @deprecated
 */
public void setInitialIndentationLevel(int newIndentationLevel) {
	this.initialIndentationLevel = currentLineIndentationLevel = indentationLevel = newIndentationLevel;
}
/** 
 * Sets the behaviour of the scanner.<br>
 * if <code>flag</code> is true, newline & indent won't be added
 * between close brace and else, (do) while, catch, and finally.
 * @param flag must be true if newline & indent must NOT
 * be added between close brace and else, (do) while,
 * catch, and finally, false otherwise.
 *
 * @deprecated backward compatibility with VAJ
 */
public void setNewlineInCompoundStatement(boolean flag) {
	options.setNewlineInControlStatementMode(flag);
}
/**
 * Set the positions to map. The mapped positions should be retrieved using the
 * getMappedPositions() method.
 * @see getMappedPositions()
 * @param positions int[]
 */
public void setPositionsToMap(int[] positions) {
	positionsToMap = positions;
	lineDelta = 0;
	globalDelta = 0;
	mappedPositions = new int[positions.length];
}
/** 
 * Appends a space character to the current line buffer.
 */
private void space() {
	currentLineBuffer.append(' ');
	increaseLineDelta(1);
}
/**
 * Splits <code>stringToSplit</code> on the top level token<br>
 * If there are several identical token at the same level,
 * the string is cut into many pieces.
 * @return an object containing the operator and all the substrings
 * or null if the string cannot be split
 */
public SplitLine split(String stringToSplit) {
	return split(stringToSplit, 0);
}
/**
 * Splits <code>stringToSplit</code> on the top level token<br>
 * If there are several identical token at the same level,
 * the string is cut into many pieces.
 * @return an object containing the operator and all the substrings
 * or null if the string cannot be split
 */
public SplitLine split(String stringToSplit, int offsetInGlobalLine) {
	// local variables
	int currentToken = 0;
	int splitTokenType = 0;
	int splitTokenDepth = Integer.MAX_VALUE;
	int splitTokenPriority = Integer.MAX_VALUE;

	int[] substringsStartPositions = new int[10];
	// contains the start position of substrings
	int[] substringsEndPositions = new int[10];
	// contains the start position of substrings
	int substringsCount = 1; // index in the substringsStartPosition array
	int[] splitOperators = new int[10];
	// contains the start position of substrings
	int splitOperatorsCount = 0; // index in the substringsStartPosition array
	int[] openParenthesisPosition = new int[10];
	int openParenthesisPositionCount = 0;
	int position = 0;
	int lastOpenParenthesisPosition = -1;
	// used to remember the position of the 1st open parenthesis
	// needed for a pattern like: A.B(C); we want formatted like A.B( split C);
	// setup the scanner with a new source
	int lastCommentStartPosition = -1;
	// to remember the start position of the last comment
	int firstTokenOnLine = -1;
	// to remember the first token of the line
	int previousToken = -1;
	// to remember the previous token.
	splitScanner.setSourceBuffer(stringToSplit.toCharArray());

	try {
		// start the loop
		while (true) {
			// takes the next token
			try {
				if (currentToken != Scanner.TokenNameWHITESPACE)
					previousToken = currentToken;
				currentToken = splitScanner.getNextToken();
			} catch (InvalidInputException e) {
				if (!handleInvalidToken(e))
					throw e;
				currentToken = 0; // this value is not modify when an exception is raised.
			}
			if (currentToken == TokenNameEOF)
				break;
				
			if (firstTokenOnLine == -1){
				firstTokenOnLine = currentToken;
			}
			
				
			switch (currentToken) {
				case TokenNameRBRACE:
				case TokenNameRPAREN :
					if (openParenthesisPositionCount > 0) {
						if (openParenthesisPositionCount == 1 && lastOpenParenthesisPosition < openParenthesisPosition[0]) {
							lastOpenParenthesisPosition = openParenthesisPosition[0];
						} else
							if ((splitTokenDepth == Integer.MAX_VALUE)
								|| (splitTokenDepth > openParenthesisPositionCount
									&& openParenthesisPositionCount == 1)) {
								splitTokenType = 0;
								splitTokenDepth = openParenthesisPositionCount;
								splitTokenPriority = Integer.MAX_VALUE;
								substringsStartPositions[0] = 0;
								// better token means the whole line until now is the first substring
								substringsCount = 1; // resets the count of substrings

								substringsEndPositions[0] = openParenthesisPosition[0];
								// substring ends on operator start
								position = openParenthesisPosition[0];
								// the string mustn't be cut before the closing parenthesis but after the opening one.
								splitOperatorsCount = 1; // resets the count of split operators
								splitOperators[0] = 0;
							}
						openParenthesisPositionCount--;
					}
					break;
				case TokenNameLBRACE:
				case TokenNameLPAREN :
					if (openParenthesisPositionCount == openParenthesisPosition.length) {
						System.arraycopy(
								openParenthesisPosition, 
								0, 
								(openParenthesisPosition = new int[openParenthesisPositionCount * 2]), 
								0, 
								openParenthesisPositionCount); 
					}
					openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition;
					if (currentToken == TokenNameLPAREN && previousToken == TokenNameRPAREN){
						openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition;
					}
					break;
				case TokenNameSEMICOLON : // ;
				case TokenNameCOMMA : // ,
				case TokenNameEQUAL : // =
					if (openParenthesisPositionCount < splitTokenDepth
						|| (openParenthesisPositionCount == splitTokenDepth
							&& splitTokenPriority > getTokenPriority(currentToken))) {
						// the current token is better than the one we currently have
						// (in level or in priority if same level)
						// reset the substringsCount
						splitTokenDepth = openParenthesisPositionCount;
						splitTokenType = currentToken;
						splitTokenPriority = getTokenPriority(currentToken);
						substringsStartPositions[0] = 0;
						// better token means the whole line until now is the first substring

						if (separateFirstArgumentOn(firstTokenOnLine)
							&& openParenthesisPositionCount > 0) {
							substringsCount = 2; // resets the count of substrings

							substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
							substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
							substringsEndPositions[1] = splitScanner.startPosition;
							splitOperatorsCount = 2; // resets the count of split operators
							splitOperators[0] = 0;
							splitOperators[1] = currentToken;
							position = splitScanner.currentPosition;
							// next substring will start from operator end
						} else {
							substringsCount = 1; // resets the count of substrings

							substringsEndPositions[0] = splitScanner.startPosition;
							// substring ends on operator start
							position = splitScanner.currentPosition;
							// next substring will start from operator end
							splitOperatorsCount = 1; // resets the count of split operators
							splitOperators[0] = currentToken;
						}
					} else {
						if ((openParenthesisPositionCount == splitTokenDepth
								&& splitTokenPriority == getTokenPriority(currentToken))
							&& splitTokenType!=TokenNameEQUAL && currentToken != TokenNameEQUAL) {
							// fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after split
							// take only the 1st = into account.
							// if another token with the same priority is found,
							// push the start position of the substring and
							// push the token into the stack.
							// create a new array object if the current one is full.
							if (substringsCount == substringsStartPositions.length) {
								System.arraycopy(
										substringsStartPositions, 
										0, 
										(substringsStartPositions = new int[substringsCount * 2]), 
										0, 
										substringsCount); 
								System.arraycopy(
										substringsEndPositions, 
										0, 
										(substringsEndPositions = new int[substringsCount * 2]), 
										0, 
										substringsCount); 
							}
							if (splitOperatorsCount == splitOperators.length) {
								System.arraycopy(
										splitOperators, 
										0, 
										(splitOperators = new int[splitOperatorsCount * 2]), 
										0, 
										splitOperatorsCount); 
							}
							substringsStartPositions[substringsCount] = position;
							substringsEndPositions[substringsCount++] = splitScanner.startPosition;
							// substring ends on operator start
							position = splitScanner.currentPosition;
							// next substring will start from operator end
							splitOperators[splitOperatorsCount++] = currentToken;
						}
					}
					break;
					
				case TokenNameCOLON : // : (15.24)
					// see 1FK7C5R, we only split on a colon, when it is associated with a question-mark.
					// indeed it might appear also behind a case statement, and we do not to break at this point.
					if ((splitOperatorsCount == 0) || splitOperators[splitOperatorsCount-1] != TokenNameQUESTION){
						break;
					}
				case TokenNameextends :
				case TokenNameimplements :
				case TokenNamethrows :

				case TokenNameDOT : // .
				case TokenNameMULTIPLY : // * (15.16.1)
				case TokenNameDIVIDE : // / (15.16.2)
				case TokenNameREMAINDER : // % (15.16.3)
				case TokenNamePLUS : // + (15.17, 15.17.2)
				case TokenNameMINUS : // - (15.17.2)
				case TokenNameLEFT_SHIFT : // << (15.18)
				case TokenNameRIGHT_SHIFT : // >> (15.18)
				case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
				case TokenNameLESS : // < (15.19.1)
				case TokenNameLESS_EQUAL : // <= (15.19.1)
				case TokenNameGREATER : // > (15.19.1)
				case TokenNameGREATER_EQUAL : // >= (15.19.1)
				case TokenNameinstanceof : // instanceof
				case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
				case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
				case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
				case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
				case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
				case TokenNameAND_AND : // && (15.22)
				case TokenNameOR_OR : // || (15.23)
				case TokenNameQUESTION : // ? (15.24)
				case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
				case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
				case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
				case TokenNamePLUS_EQUAL : // += (15.25.2)
				case TokenNameMINUS_EQUAL : // -= (15.25.2)
				case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
				case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
				case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
				case TokenNameAND_EQUAL : // &= (15.25.2)
				case TokenNameXOR_EQUAL : // ^= (15.25.2)
				case TokenNameOR_EQUAL : // |= (15.25.2)

					if ((openParenthesisPositionCount < splitTokenDepth
						|| (openParenthesisPositionCount == splitTokenDepth
							&& splitTokenPriority > getTokenPriority(currentToken)))
						&&
							!((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS)
								&& (previousToken == TokenNameLBRACE || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))){
						// the current token is better than the one we currently have
						// (in level or in priority if same level)
						// reset the substringsCount
						splitTokenDepth = openParenthesisPositionCount;
						splitTokenType = currentToken;
						splitTokenPriority = getTokenPriority(currentToken);
						substringsStartPositions[0] = 0;
						// better token means the whole line until now is the first substring

						if (separateFirstArgumentOn(firstTokenOnLine)
							&& openParenthesisPositionCount > 0) {
							substringsCount = 2; // resets the count of substrings

							substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
							substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
							substringsEndPositions[1] = splitScanner.startPosition;
							splitOperatorsCount = 3; // resets the count of split operators
							splitOperators[0] = 0;
							splitOperators[1] = 0;
							splitOperators[2] = currentToken;
							position = splitScanner.currentPosition;
							// next substring will start from operator end
						} else {
							substringsCount = 1; // resets the count of substrings

							substringsEndPositions[0] = splitScanner.startPosition;
							// substring ends on operator start
							position = splitScanner.currentPosition;
							// next substring will start from operator end
							splitOperatorsCount = 2; // resets the count of split operators
							splitOperators[0] = 0;
							// nothing for first operand since operator will be inserted in front of the second operand
							splitOperators[1] = currentToken;

						}
					} else {
						if (openParenthesisPositionCount == splitTokenDepth
							&& splitTokenPriority == getTokenPriority(currentToken)) {
							// if another token with the same priority is found,
							// push the start position of the substring and
							// push the token into the stack.
							// create a new array object if the current one is full.
							if (substringsCount == substringsStartPositions.length) {
								System.arraycopy(
										substringsStartPositions, 
										0, 
										(substringsStartPositions = new int[substringsCount * 2]), 
										0, 
										substringsCount); 
								System.arraycopy(
										substringsEndPositions, 
										0, 
										(substringsEndPositions = new int[substringsCount * 2]), 
										0, 
										substringsCount); 
							}
							if (splitOperatorsCount == splitOperators.length) {
								System.arraycopy(
										splitOperators, 
										0, 
										(splitOperators = new int[splitOperatorsCount * 2]), 
										0, 
										splitOperatorsCount); 
							}
							substringsStartPositions[substringsCount] = position;
							substringsEndPositions[substringsCount++] = splitScanner.startPosition;
							// substring ends on operator start
							position = splitScanner.currentPosition;
							// next substring will start from operator end
							splitOperators[splitOperatorsCount++] = currentToken;
						}
					}
					default :
						break;
			}
			if (isComment(currentToken)) {
				lastCommentStartPosition = splitScanner.startPosition;
			} else {
				lastCommentStartPosition = -1;
			}
		}
	} catch (InvalidInputException e) {
		return null;
	}
	// if the string cannot be split, return null.
	if (splitOperatorsCount == 0)
		return null;

	// ## SPECIAL CASES BEGIN
	if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1)
			|| (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength)
			|| (separateFirstArgumentOn(firstTokenOnLine) && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1))
		&& (lastOpenParenthesisPosition<splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition]!=')')){
			// fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should not be broken on two lines
		// only one split on a top level .
		// or more than one split on . and substring before open parenthesis fits one line.
		// or split inside parenthesis and first token is not a for/while/if
		SplitLine sl = split(stringToSplit.substring(lastOpenParenthesisPosition), lastOpenParenthesisPosition);
		if (sl == null || sl.operators[0] != TokenNameCOMMA) {
			// trim() is used to remove the extra blanks at the end of the substring. See PR 1FGYPI1
			return new SplitLine(
					new int[] {0, 0}, 
					new String[] {
						stringToSplit.substring(0, lastOpenParenthesisPosition).trim(), 
						stringToSplit.substring(lastOpenParenthesisPosition)},
					new int[] {offsetInGlobalLine, lastOpenParenthesisPosition + offsetInGlobalLine}); 
		} else {
			
			// right substring can be split and is split on comma
			// copy substrings and operators
			// except if the 1st string is empty.

			int startIndex = (sl.substrings[0].length()==0)?1:0;

			int subStringsLength = sl.substrings.length + 1 - startIndex;
			String[] result = new String[subStringsLength];
			int[] startIndexes = new int[subStringsLength];
			int operatorsLength = sl.operators.length + 1 - startIndex;
			int[] operators = new int[operatorsLength];

			result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition);
			operators[0] = 0;

			System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes, 1, subStringsLength - 1);
			for (int i = subStringsLength - 1; i >= 0; i--) {
				startIndexes[i] += offsetInGlobalLine;
			}
			System.arraycopy(sl.substrings, startIndex, result, 1, subStringsLength - 1);
			System.arraycopy(sl.operators, startIndex, operators, 1, operatorsLength - 1);

			return new SplitLine(operators, result, startIndexes);
		}
	}

	// if the last token is a comment and the substring before the comment fits on a line,
	// split before the comment and return the result.
	if (lastCommentStartPosition > -1
		&& lastCommentStartPosition < options.maxLineLength
		&& splitTokenPriority > 50) {
		int end = lastCommentStartPosition;
		int start = lastCommentStartPosition;
		if (stringToSplit.charAt(end - 1) == ' ') {
			end--;
		}
		if (start != end && stringToSplit.charAt(start) == ' ') {
			start++;
		}
		return new SplitLine(
				new int[] {0, 0}, 
				new String[] {
					stringToSplit.substring(0, end), 
					stringToSplit.substring(start)},
				new int[] {0, start}); 
	}

	if (position != stringToSplit.length()) {
		
		if (substringsCount == substringsStartPositions.length) {
			System.arraycopy(
					substringsStartPositions, 
					0, 
					(substringsStartPositions = new int[substringsCount * 2]), 
					0, 
					substringsCount); 
			System.arraycopy(
					substringsEndPositions, 
					0, 
					(substringsEndPositions = new int[substringsCount * 2]), 
					0, 
					substringsCount); 
		}
		// avoid empty extra substring, e.g. line terminated with a semi-colon
		substringsStartPositions[substringsCount] = position;
		substringsEndPositions[substringsCount++] = stringToSplit.length();
	}
	
	if (splitOperatorsCount == splitOperators.length) {
		System.arraycopy(
				splitOperators, 
				0, 
				(splitOperators = new int[splitOperatorsCount * 2]), 
				0, 
				splitOperatorsCount); 
	}

	splitOperators[splitOperatorsCount] = 0;

	// the last element of the stack is the position of the end of StringToSPlit
	// +1 because the substring method excludes the last character
	String[] result = new String[substringsCount];
	for (int i = 0; i < substringsCount; i++) {
		int start = substringsStartPositions[i];
		int end = substringsEndPositions[i];
		if (stringToSplit.charAt(start) == ' ') {
			start++;
			substringsStartPositions[i]++;
		}
		if (end != start && stringToSplit.charAt(end - 1) == ' ') {
			end--;
		}

		result[i] = stringToSplit.substring(start, end);
		substringsStartPositions[i] += offsetInGlobalLine;
	}
	if (splitOperatorsCount > substringsCount) {
		System.arraycopy(substringsStartPositions, 0, (substringsStartPositions = new int[splitOperatorsCount]), 0, substringsCount);
		System.arraycopy(substringsEndPositions, 0, (substringsEndPositions = new int[splitOperatorsCount]), 0, substringsCount);
		for (int i = substringsCount; i < splitOperatorsCount; i++) {
			substringsStartPositions[i] = position;
			substringsEndPositions[i] = position;
		}
		System.arraycopy(splitOperators, 0, (splitOperators = new int[splitOperatorsCount]), 0, splitOperatorsCount);
	} else {
		System.arraycopy(substringsStartPositions, 0, (substringsStartPositions = new int[substringsCount]), 0, substringsCount);
		System.arraycopy(substringsEndPositions, 0, (substringsEndPositions = new int[substringsCount]), 0, substringsCount);	
		System.arraycopy(splitOperators, 0, (splitOperators = new int[substringsCount]), 0, substringsCount);
	}
	
	SplitLine splitLine = new SplitLine(splitOperators, result, substringsStartPositions);
	return splitLine;

}
private void updateMappedPositions(int startPosition) {
	if (positionsToMap == null)	return;
	char[] source = scanner.source;
	int sourceLength = source.length;
	while (indexToMap < positionsToMap.length && positionsToMap[indexToMap] <= startPosition) {
		int posToMap = positionsToMap[indexToMap];
		if (posToMap < 0 || posToMap >= sourceLength){ // protection against out of bounds position
			indexToMap = positionsToMap.length; // no more mapping
			return;
		}
		if (Character.isWhitespace(source[posToMap])) {
			mappedPositions[indexToMap] = startPosition + globalDelta + lineDelta;
		} else {
			mappedPositions[indexToMap] = posToMap + globalDelta + lineDelta;
		}
		indexToMap++;
	}
}
private void updateMappedPositionsWhileSplitting(int startPosition, int endPosition) {
	if (mappedPositions == null || mappedPositions.length == indexInMap) return;

	while(indexInMap < mappedPositions.length
		&& startPosition <= mappedPositions[indexInMap]
		&& mappedPositions[indexInMap] < endPosition
		&& indexInMap < indexToMap) {
			mappedPositions[indexInMap]+= splitDelta;
			indexInMap++;
	}
}
}
