/*******************************************************************************
 * Copyright (c) 2000, 2004 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
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser.diagnose;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;

public class DiagnoseParser implements ParserBasicInformation, TerminalTokens {
	private static final boolean DEBUG = false;
	private boolean DEBUG_PARSECHECK = false;
	
	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
	private static final int STACK_INCREMENT = 256;
	
//	private static final int ERROR_CODE = 1;
	private static final int BEFORE_CODE = 2;
	private static final int INSERTION_CODE = 3;
	private static final int INVALID_CODE = 4;
	private static final int SUBSTITUTION_CODE = 5;
	private static final int DELETION_CODE = 6;
	private static final int MERGE_CODE = 7;
	private static final int MISPLACED_CODE = 8;
	private static final int SCOPE_CODE = 9;
	private static final int SECONDARY_CODE = 10;
	private static final int EOF_CODE = 11;

	private static final int BUFF_UBOUND  = 31;
	private static final int BUFF_SIZE    = 32;
	private static final int MAX_DISTANCE = 30;
	private static final int MIN_DISTANCE = 3;
	
	private CompilerOptions options;
	
	private LexStream lexStream;
	private int errorToken;
	private int errorTokenStart;
	
	private int currentToken = 0;
	
	private int stackLength;
	private int stateStackTop;
	private int[] stack;
	
	private int[] locationStack;
	private int[] locationStartStack;
	
	private int tempStackTop;
	private int[] tempStack;
	
	private int prevStackTop;
	private int[] prevStack;
	private int nextStackTop;
	private int[] nextStack;
	
	private int scopeStackTop;
    private int[] scopeIndex;
    private int[] scopePosition;
	
	int[] list = new int[NUM_SYMBOLS + 1];
	int[] buffer = new int[BUFF_SIZE];
	
	private static final int NIL = -1;
	int[] stateSeen;
	
	int statePoolTop;
	StateInfo[] statePool;
	
	private Parser parser;
	
	private class RepairCandidate {
		public int symbol;
		public int location;
		
		public RepairCandidate(){
			this.symbol = 0;
			this.location = 0;
		}
	}
	
	private class PrimaryRepairInfo {
		public int distance;
		public int misspellIndex;
		public int code;
		public int bufferPosition;
		public int symbol;
		
		public PrimaryRepairInfo(){
			this.distance = 0;
			this.misspellIndex = 0;
			this.code = 0;
			this.bufferPosition = 0;
			this.symbol = 0;
		}
		
		public PrimaryRepairInfo copy(){
			PrimaryRepairInfo c = new PrimaryRepairInfo();
			c.distance = this.distance;
			c.misspellIndex = this.misspellIndex;
			c.code = this.code;
			c.bufferPosition = this .bufferPosition;
			c.symbol = this.symbol;
			return c;
			
		}
	}
	
	private class SecondaryRepairInfo {
		public int code;
		public int distance;
		public int bufferPosition;
		public int stackPosition;
		public int numDeletions;
		public int symbol;

		boolean recoveryOnNextStack;
	} 
	
	private class StateInfo {
	    int state;
	    int next;
	    
	    public StateInfo(int state, int next){
	    	this.state = state;
	    	this.next = next;
	    }
	}

	public DiagnoseParser(Parser parser, int firstToken, int start, int end, CompilerOptions options) {
		this(parser, firstToken, start, end, new int[0], new int[0], new int[0], options);
	}

	public DiagnoseParser(Parser parser, int firstToken, int start, int end, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, CompilerOptions options) {
		this.parser = parser;
		this.options = options;
		this.lexStream = new LexStream(BUFF_SIZE, parser.scanner, intervalStartToSkip, intervalEndToSkip, intervalFlagsToSkip, firstToken, start, end);
	}
	
	private ProblemReporter problemReporter(){
		return parser.problemReporter();
	}

	private void reallocateStacks()	{
		int old_stack_length = stackLength;

		stackLength += STACK_INCREMENT;

		if(old_stack_length == 0){
			stack = new int[stackLength];
			locationStack = new int[stackLength];
			locationStartStack = new int[stackLength];
			tempStack = new int[stackLength];
			prevStack = new int[stackLength];
			nextStack = new int[stackLength];
			scopeIndex = new int[stackLength];
			scopePosition = new int[stackLength];
		} else {
			System.arraycopy(stack, 0, stack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(locationStack, 0, locationStack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(locationStartStack, 0, locationStartStack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(tempStack, 0, tempStack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(prevStack, 0, prevStack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(nextStack, 0, nextStack = new int[stackLength], 0, old_stack_length);
			System.arraycopy(scopeIndex, 0, scopeIndex = new int[stackLength], 0, old_stack_length);
			System.arraycopy(scopePosition, 0, scopePosition = new int[stackLength], 0, old_stack_length);
		}
		return;
	}


	public void diagnoseParse() {
		lexStream.reset();

		currentToken = lexStream.getToken();

		int prev_pos;
		int pos;
		int next_pos;
		int act = START_STATE;

		reallocateStacks();

		//
		// Start parsing
		//
		stateStackTop = 0;
		stack[stateStackTop] = act;

		int tok = lexStream.kind(currentToken);
		locationStack[stateStackTop] = currentToken;
		locationStartStack[stateStackTop] = lexStream.start(currentToken);
		
		boolean forceRecoveryAfterLBracketMissing = false;
//		int forceRecoveryToken = -1;

		//
		// Process a terminal
		//
		do {
			//
			// Synchronize state stacks and update the location stack
			//
			prev_pos = -1;
			prevStackTop = -1;

			next_pos = -1;
			nextStackTop = -1;

			pos = stateStackTop;
			tempStackTop = stateStackTop - 1;
			for (int i = 0; i <= stateStackTop; i++)
				tempStack[i] = stack[i];

			act = Parser.tAction(act, tok);
			//
			// When a reduce action is encountered, we compute all REDUCE
			// and associated goto actions induced by the current token.
			// Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
			// computed...
			//
			while (act <= NUM_RULES) {
				do {
					tempStackTop -= (Parser.rhs[act]-1);
					act = Parser.ntAction(tempStack[tempStackTop], Parser.lhs[act]);
				} while(act <= NUM_RULES);
				//
				// ... Update the maximum useful position of the
				// (STATE_)STACK, push goto state into stack, and
				// compute next action on current symbol ...
				//
				if (tempStackTop + 1 >= stackLength)
					reallocateStacks();
				pos = pos < tempStackTop ? pos : tempStackTop;
				tempStack[tempStackTop + 1] = act;
				act = Parser.tAction(act, tok);
			}

			//
			// At this point, we have a shift, shift-reduce, accept or error
			// action.  STACK contains the configuration of the state stack
			// prior to executing any action on curtok. next_stack contains
			// the configuration of the state stack after executing all
			// reduce actions induced by curtok.  The variable pos indicates
			// the highest position in STACK that is still useful after the
			// reductions are executed.
			//
			while(act > ERROR_ACTION || act < ACCEPT_ACTION) { // SHIFT-REDUCE action or SHIFT action ?
				nextStackTop = tempStackTop + 1;
				for (int i = next_pos + 1; i <= nextStackTop; i++)
					nextStack[i] = tempStack[i];

				for (int i = pos + 1; i <= nextStackTop; i++) {
					locationStack[i] = locationStack[stateStackTop];
					locationStartStack[i] = locationStartStack[stateStackTop];
				}

				//
				// If we have a shift-reduce, process it as well as
				// the goto-reduce actions that follow it.
				//
				if (act > ERROR_ACTION) {
					act -= ERROR_ACTION;
					do {
						nextStackTop -= (Parser.rhs[act]-1);
						act = Parser.ntAction(nextStack[nextStackTop], Parser.lhs[act]);
					} while(act <= NUM_RULES);
					pos = pos < nextStackTop ? pos : nextStackTop;
				}

				if (nextStackTop + 1 >= stackLength)
					reallocateStacks();

				tempStackTop = nextStackTop;
				nextStack[++nextStackTop] = act;
				next_pos = nextStackTop;

				//
				// Simulate the parser through the next token without
				// destroying STACK or next_stack.
				//
				currentToken = lexStream.getToken();
				tok = lexStream.kind(currentToken);
				act = Parser.tAction(act, tok);
				while(act <= NUM_RULES) {
					//
					// ... Process all goto-reduce actions following
					// reduction, until a goto action is computed ...
					//
					do {
						int lhs_symbol = Parser.lhs[act];
						if(DEBUG) {
							System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
						}
						tempStackTop -= (Parser.rhs[act]-1);
						act = (tempStackTop > next_pos
								   ? tempStack[tempStackTop]
								   : nextStack[tempStackTop]);
						act = Parser.ntAction(act, lhs_symbol);
					}   while(act <= NUM_RULES);

					//
					// ... Update the maximum useful position of the
					// (STATE_)STACK, push GOTO state into stack, and
					// compute next action on current symbol ...
					//
					if (tempStackTop + 1 >= stackLength)
						reallocateStacks();

					next_pos = next_pos < tempStackTop ? next_pos : tempStackTop;
					tempStack[tempStackTop + 1] = act;
					act = Parser.tAction(act, tok);
				}

//				if((tok != TokenNameRBRACE || (forceRecoveryToken != currentToken && (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0))
//					&& (lexStream.flags(currentToken) & LexStream.IS_AFTER_JUMP) !=0) {
//					act = ERROR_ACTION;
//					if(forceRecoveryToken != currentToken
//						&& (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0) {
//						forceRecoveryAfterLBracketMissing = true;
//						forceRecoveryToken = currentToken;
//					}
//				}
				
				//
				// No error was detected, Read next token into
				// PREVTOK element, advance CURTOK pointer and
				// update stacks.
				//
				if (act != ERROR_ACTION) {
					prevStackTop = stateStackTop;
					for (int i = prev_pos + 1; i <= prevStackTop; i++)
						prevStack[i] = stack[i];
					prev_pos = pos;

					stateStackTop = nextStackTop;
					for (int i = pos + 1; i <= stateStackTop; i++)
						stack[i] = nextStack[i];
					locationStack[stateStackTop] = currentToken;
					locationStartStack[stateStackTop] = lexStream.start(currentToken);
					pos = next_pos;
				}
			}

			//
			// At this stage, either we have an ACCEPT or an ERROR
			// action.
			//
			if (act == ERROR_ACTION) {
				//
				// An error was detected.
				//
				RepairCandidate candidate = errorRecovery(currentToken, forceRecoveryAfterLBracketMissing);
				
				forceRecoveryAfterLBracketMissing = false;
				
				if(parser.reportOnlyOneSyntaxError) {
					return;
				}
				
				if(this.parser.problemReporter().options.maxProblemsPerUnit < this.parser.compilationUnit.compilationResult.problemCount) {
					return;
				}

				act = stack[stateStackTop];

				//
				// If the recovery was successful on a nonterminal candidate,
				// parse through that candidate and "read" the next token.
				//
				if (candidate.symbol == 0) {
					break;
				} else if (candidate.symbol > NT_OFFSET) {
					int lhs_symbol = candidate.symbol - NT_OFFSET;
					if(DEBUG) {
						System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
					}
					act = Parser.ntAction(act, lhs_symbol);
					while(act <= NUM_RULES) {
						stateStackTop -= (Parser.rhs[act]-1);
						act = Parser.ntAction(stack[stateStackTop], Parser.lhs[act]);
					}
					stack[++stateStackTop] = act;
					currentToken = lexStream.getToken();
					tok = lexStream.kind(currentToken);
					locationStack[stateStackTop] = currentToken;
					locationStartStack[stateStackTop] = lexStream.start(currentToken);
				} else {
					tok = candidate.symbol;
					locationStack[stateStackTop] = candidate.location;
					locationStartStack[stateStackTop] = lexStream.start(candidate.location);
				}
			}
		} while (act != ACCEPT_ACTION);

		return;
	}

	//
//		This routine is invoked when an error is encountered.  It
//	   tries to diagnose the error and recover from it.  If it is
//	   successful, the state stack, the current token and the buffer
//	   are readjusted; i.e., after a successful recovery,
//	   state_stack_top points to the location in the state stack
//	   that contains the state on which to recover; curtok
//	   identifies the symbol on which to recover.
//
//	   Up to three configurations may be available when this routine
//	   is invoked. PREV_STACK may contain the sequence of states
//	   preceding any action on prevtok, STACK always contains the
//	   sequence of states preceding any action on curtok, and
//	   NEXT_STACK may contain the sequence of states preceding any
//	   action on the successor of curtok.
//
	private RepairCandidate errorRecovery(int error_token, boolean forcedError) {
		this.errorToken = error_token;
		this.errorTokenStart = lexStream.start(error_token);
		
		int prevtok = lexStream.previous(error_token);
		int prevtokKind = lexStream.kind(prevtok);
		
		if(forcedError) {
			int name_index = Parser.terminal_index[TokenNameLBRACE];

			reportError(INSERTION_CODE, name_index, prevtok, prevtok);
			
			RepairCandidate candidate = new RepairCandidate();
			candidate.symbol = TokenNameLBRACE;
			candidate.location = error_token;
			lexStream.reset(error_token);
			
			stateStackTop = nextStackTop;
			for (int j = 0; j <= stateStackTop; j++) {
				stack[j] = nextStack[j];
			}
			locationStack[stateStackTop] = error_token;
			locationStartStack[stateStackTop] = lexStream.start(error_token);
			
			return candidate;
		}

		//
		// Try primary phase recoveries. If not successful, try secondary
		// phase recoveries.  If not successful and we are at end of the
		// file, we issue the end-of-file error and quit. Otherwise, ...
		//
		RepairCandidate candidate = primaryPhase(error_token);
		if (candidate.symbol != 0) {
			return candidate;
		}

		candidate = secondaryPhase(error_token);
		if (candidate.symbol != 0) {
			return candidate;
		}

		if (lexStream.kind(error_token) == EOFT_SYMBOL) {
			reportError(EOF_CODE,
						Parser.terminal_index[EOFT_SYMBOL],
						prevtok,
						prevtok);
			candidate.symbol = 0;
			candidate.location = error_token;
			return candidate;
		}

		//
		// At this point, primary and (initial attempt at) secondary
		// recovery did not work.  We will now get into "panic mode" and
		// keep trying secondary phase recoveries until we either find
		// a successful recovery or have consumed the remaining input
		// tokens.
		//
		while(lexStream.kind(buffer[BUFF_UBOUND]) != EOFT_SYMBOL) {
			candidate = secondaryPhase(buffer[MAX_DISTANCE - MIN_DISTANCE + 2]);
			if (candidate.symbol != 0) {
				return candidate;
			}
		}

		//
		// We reached the end of the file while panicking. Delete all
		// remaining tokens in the input.
		//
		int i;
		for (i = BUFF_UBOUND; lexStream.kind(buffer[i]) == EOFT_SYMBOL; i--){/*empty*/}

		reportError(DELETION_CODE,
					Parser.terminal_index[prevtokKind],//Parser.terminal_index[lexStream.kind(prevtok)],
					error_token,
					buffer[i]);

		candidate.symbol = 0;
		candidate.location = buffer[i];

		return candidate;
	}

//
//	   This function tries primary and scope recovery on each
//	   available configuration.  If a successful recovery is found
//	   and no secondary phase recovery can do better, a diagnosis is
//	   issued, the configuration is updated and the function returns
//	   "true".  Otherwise, it returns "false".
//
	private RepairCandidate primaryPhase(int error_token) {
		PrimaryRepairInfo repair = new PrimaryRepairInfo();
		RepairCandidate candidate = new RepairCandidate();

		//
		// Initialize the buffer.
		//
		int i = (nextStackTop >= 0 ? 3 : 2);
		buffer[i] = error_token;

		for (int j = i; j > 0; j--)
			buffer[j - 1] = lexStream.previous(buffer[j]);

		for (int k = i + 1; k < BUFF_SIZE; k++)
			buffer[k] = lexStream.next(buffer[k - 1]);

		//
		// If NEXT_STACK_TOP > 0 then the parse was successful on CURTOK
		// and the error was detected on the successor of CURTOK. In
		// that case, first check whether or not primary recovery is
		// possible on next_stack ...
		//
		if (nextStackTop >= 0) {
			repair.bufferPosition = 3;
			repair = checkPrimaryDistance(nextStack, nextStackTop, repair);
		}

		//
		// ... Next, try primary recovery on the current token...
		//
		PrimaryRepairInfo new_repair = repair.copy();

		new_repair.bufferPosition = 2;
		new_repair = checkPrimaryDistance(stack, stateStackTop, new_repair);
		if (new_repair.distance > repair.distance || new_repair.misspellIndex > repair.misspellIndex) {
			repair = new_repair;
		}

		//
		// Finally, if prev_stack_top >= 0 then try primary recovery on
		// the prev_stack configuration.
		//
		
		if (prevStackTop >= 0) {
			new_repair = repair.copy();
			new_repair.bufferPosition = 1;
			new_repair = checkPrimaryDistance(prevStack,prevStackTop, new_repair);
			if (new_repair.distance > repair.distance || new_repair.misspellIndex > repair.misspellIndex) {
				repair = new_repair;
			}
		}

		//
		// Before accepting the best primary phase recovery obtained,
		// ensure that we cannot do better with a similar secondary
		// phase recovery.
		//
		if (nextStackTop >= 0) {// next_stack available
			if (secondaryCheck(nextStack,nextStackTop,3,repair.distance)) {
				return candidate;
			}
		}
		else if (secondaryCheck(stack, stateStackTop, 2, repair.distance)) {
			return candidate;
		}

		//
		// First, adjust distance if the recovery is on the error token;
		// it is important that the adjustment be made here and not at
		// each primary trial to prevent the distance tests from being
		// biased in favor of deferred recoveries which have access to
		// more input tokens...
		//
		repair.distance = repair.distance - repair.bufferPosition + 1;

		//
		// ...Next, adjust the distance if the recovery is a deletion or
		// (some form of) substitution...
		//
		if (repair.code == INVALID_CODE      ||
			repair.code == DELETION_CODE     ||
			repair.code == SUBSTITUTION_CODE ||
			repair.code == MERGE_CODE) {
			 repair.distance--;
		}

		//
		// ... After adjustment, check if the most successful primary
		// recovery can be applied.  If not, continue with more radical
		// recoveries...
		//
		if (repair.distance < MIN_DISTANCE) {
			return candidate;
		}

		//
		// When processing an insertion error, if the token preceeding
		// the error token is not available, we change the repair code
		// into a BEFORE_CODE to instruct the reporting routine that it
		// indicates that the repair symbol should be inserted before
		// the error token.
		//
		if (repair.code == INSERTION_CODE) {
			if (buffer[repair.bufferPosition - 1] == 0) {
				repair.code = BEFORE_CODE;
			}
		}

		//
		// Select the proper sequence of states on which to recover,
		// update stack accordingly and call diagnostic routine.
		//
		if (repair.bufferPosition == 1) {
			stateStackTop = prevStackTop;
			for (int j = 0; j <= stateStackTop; j++) {
				stack[j] = prevStack[j];
			}
		} else if (nextStackTop >= 0 && repair.bufferPosition >= 3) {
			stateStackTop = nextStackTop;
			for (int j = 0; j <= stateStackTop; j++) {
				stack[j] = nextStack[j];
			}
			locationStack[stateStackTop] = buffer[3];
			locationStartStack[stateStackTop] = lexStream.start(buffer[3]);
		}

		return primaryDiagnosis(repair);
	}


//
//		   This function checks whether or not a given state has a
//	   candidate, whose string representaion is a merging of the two
//	   tokens at positions buffer_position and buffer_position+1 in
//	   the buffer.  If so, it returns the candidate in question;
//	   otherwise it returns 0.
//
	private int mergeCandidate(int state, int buffer_position) {
		char[] name1 = lexStream.name(buffer[buffer_position]);
		char[] name2 = lexStream.name(buffer[buffer_position + 1]);
		
		int len  = name1.length + name2.length;

		char[] str = CharOperation.concat(name1, name2);

		for (int k = Parser.asi(state); Parser.asr[k] != 0; k++) {
			int l = Parser.terminal_index[Parser.asr[k]];

			if (len == Parser.name[l].length()) {
				char[] name = Parser.name[l].toCharArray();

				if (CharOperation.equals(str, name, false)) {
					return Parser.asr[k];
				}
			}
		}

		return 0;
	}


//
//	   This procedure takes as arguments a parsing configuration
//	   consisting of a state stack (stack and stack_top) and a fixed
//	   number of input tokens (starting at buffer_position) in the
//	   input BUFFER; and some reference arguments: repair_code,
//	   distance, misspell_index, candidate, and stack_position
//	   which it sets based on the best possible recovery that it
//	   finds in the given configuration.  The effectiveness of a
//	   a repair is judged based on two criteria:
//
//		 1) the number of tokens that can be parsed after the repair
//			is applied: distance.
//		 2) how close to perfection is the candidate that is chosen:
//			misspell_index.
//	   When this procedure is entered, distance, misspell_index and
//	   repair_code are assumed to be initialized.
//
	private PrimaryRepairInfo checkPrimaryDistance(int stck[], int stack_top, PrimaryRepairInfo repair) {
		int i, j, k, next_state, max_pos, act, root, symbol, tok;

		//
	    //  First, try scope and manual recovery.
	    //
	    PrimaryRepairInfo scope_repair = scopeTrial(stck, stack_top, repair.copy());
	    if (scope_repair.distance > repair.distance)
	        repair = scope_repair;
	        
		//
		//  Next, try merging the error token with its successor.
		//
	    if(buffer[repair.bufferPosition] != 0 && buffer[repair.bufferPosition + 1] != 0) {// do not merge the first token
			symbol = mergeCandidate(stck[stack_top], repair.bufferPosition);
			if (symbol != 0) {
				j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+2);
				if ((j > repair.distance) || (j == repair.distance && repair.misspellIndex < 10)) {
					repair.misspellIndex = 10;
					repair.symbol = symbol;
					repair.distance = j;
					repair.code = MERGE_CODE;
				}
			}
	    }

		//
		// Next, try deletion of the error token.
		//
		j = parseCheck(
				stck,
				stack_top,
				lexStream.kind(buffer[repair.bufferPosition + 1]),
				repair.bufferPosition + 2);
		if (lexStream.kind(buffer[repair.bufferPosition]) == EOLT_SYMBOL &&
			lexStream.afterEol(buffer[repair.bufferPosition+1])) {
			 k = 10;
		} else {
			k = 0;
		}
		if (j > repair.distance || (j == repair.distance && k > repair.misspellIndex)) {
			repair.misspellIndex = k;
			repair.code = DELETION_CODE;
			repair.distance = j;
		}

		//
		// Update the error configuration by simulating all reduce and
		// goto actions induced by the error token. Then assign the top
		// most state of the new configuration to next_state.
		//
		next_state = stck[stack_top];
		max_pos = stack_top;
		tempStackTop = stack_top - 1;

		tok = lexStream.kind(buffer[repair.bufferPosition]);
		lexStream.reset(buffer[repair.bufferPosition + 1]);
		act = Parser.tAction(next_state, tok);
		while(act <= NUM_RULES) {
			do {
				tempStackTop -= (Parser.rhs[act]-1);
				symbol = Parser.lhs[act];
				act = (tempStackTop > max_pos
									  ? tempStack[tempStackTop]
									  : stck[tempStackTop]);
				act = Parser.ntAction(act, symbol);
			} while(act <= NUM_RULES);
			max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
			tempStack[tempStackTop + 1] = act;
			next_state = act;
			act = Parser.tAction(next_state, tok);
		}

		//
		//  Next, place the list of candidates in proper order.
		//
		root = 0;
		for (i = Parser.asi(next_state); Parser.asr[i] != 0; i++) {
			symbol = Parser.asr[i];
			if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL) {
				if (root == 0) {
					list[symbol] = symbol;
				} else {
					list[symbol] = list[root];
					list[root] = symbol;
				}
				root = symbol;
			}
		}

		if (stck[stack_top] != next_state) {
			for (i = Parser.asi(stck[stack_top]); Parser.asr[i] != 0; i++) {
				symbol = Parser.asr[i];
				if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL && list[symbol] == 0) {
					if (root == 0) {
						list[symbol] = symbol;
					} else {
						list[symbol] = list[root];
						list[root] = symbol;
					}
					root = symbol;
				}
			}
		}

		i = list[root];
		list[root] = 0;
		root = i;

		//
		//  Next, try insertion for each possible candidate available in
		// the current state, except EOFT and ERROR_SYMBOL.
		//
		symbol = root;
		while(symbol != 0) {
			if (symbol == EOLT_SYMBOL && lexStream.afterEol(buffer[repair.bufferPosition])) {
				k = 10;
			} else {
				k = 0;
			}
			j = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
			if (j > repair.distance) {
				repair.misspellIndex = k;
				repair.distance = j;
				repair.symbol = symbol;
				repair.code = INSERTION_CODE;
			} else if (j == repair.distance && k > repair.misspellIndex) {
				repair.misspellIndex = k;
				repair.distance = j;
				repair.symbol = symbol;
				repair.code = INSERTION_CODE;
			} else if (j == repair.distance && k == repair.misspellIndex && isBetterSymbol(symbol, repair.symbol)) {
				repair.misspellIndex = k;
				repair.distance = j;
				repair.symbol = symbol;
				repair.code = INSERTION_CODE;
			}

			symbol = list[symbol];
		}

		//
		//  Next, Try substitution for each possible candidate available
		// in the current state, except EOFT and ERROR_SYMBOL.
		//
		symbol = root;
		
		if(buffer[repair.bufferPosition] != 0) {// do not replace the first token
			while(symbol != 0) {
				if (symbol == EOLT_SYMBOL && lexStream.afterEol(buffer[repair.bufferPosition+1])) {
					k = 10;
				} else {
					k = misspell(symbol, buffer[repair.bufferPosition]);
				}
				j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+1);
				if (j > repair.distance) {
					repair.misspellIndex = k;
					repair.distance = j;
					repair.symbol = symbol;
					repair.code = SUBSTITUTION_CODE;
				} else if (j == repair.distance && k > repair.misspellIndex) {
					repair.misspellIndex = k;
					repair.symbol = symbol;
					repair.code = SUBSTITUTION_CODE;
				} else if (j == repair.distance && k > repair.misspellIndex && isBetterSymbol(symbol, repair.symbol)) {
					repair.misspellIndex = k;
					repair.symbol = symbol;
					repair.code = SUBSTITUTION_CODE;
				}
				i = symbol;
				symbol = list[symbol];
				list[i] = 0;                             // reset element
			}
		}


		//
		// Next, we try to insert a nonterminal candidate in front of the
		// error token, or substituting a nonterminal candidate for the
		// error token. Precedence is given to insertion.
		//
		 for (i = Parser.nasi(stck[stack_top]); Parser.nasr[i] != 0; i++) {
			 symbol = Parser.nasr[i] + NT_OFFSET;
			 j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+1);
			 if (j > repair.distance) {
				 repair.misspellIndex = 0;
				 repair.distance = j;
				 repair.symbol = symbol;
				 repair.code = INVALID_CODE;
			 }

			 j = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
			 if ((j > repair.distance) || (j == repair.distance && repair.code == INVALID_CODE)) {
				 repair.misspellIndex = 0;
				 repair.distance = j;
				 repair.symbol = symbol;
				 repair.code = INSERTION_CODE;
			 }
		 }

		return repair;
	}


//
//	   This procedure is invoked to issue a diagnostic message and
//	   adjust the input buffer.  The recovery in question is either
//	   the insertion of one or more scopes, the merging of the error
//	   token with its successor, the deletion of the error token,
//	   the insertion of a single token in front of the error token
//	   or the substitution of another token for the error token.
//
	private RepairCandidate primaryDiagnosis(PrimaryRepairInfo repair) {
		int name_index;

		//
		//  Issue diagnostic.
		//
		int prevtok = buffer[repair.bufferPosition - 1];
		int	curtok  = buffer[repair.bufferPosition];

		switch(repair.code) {
			case INSERTION_CODE:
			case BEFORE_CODE: {
				if (repair.symbol > NT_OFFSET)
					 name_index = getNtermIndex(stack[stateStackTop],
												repair.symbol,
												repair.bufferPosition);
				else name_index = getTermIndex(stack,
											   stateStackTop,
											   repair.symbol,
											   repair.bufferPosition);

				int t = (repair.code == INSERTION_CODE ? prevtok : curtok);
				reportError(repair.code, name_index, t, t);
				break;
			}
			case INVALID_CODE: {
				name_index = getNtermIndex(stack[stateStackTop],
										   repair.symbol,
										   repair.bufferPosition + 1);
				reportError(repair.code, name_index, curtok, curtok);
				break;
			}
			case SUBSTITUTION_CODE: {
				if (repair.misspellIndex >= 6)
					name_index = Parser.terminal_index[repair.symbol];
				else
				{
					name_index = getTermIndex(stack, stateStackTop,
											  repair.symbol,
											  repair.bufferPosition + 1);
					if (name_index != Parser.terminal_index[repair.symbol])
						repair.code = INVALID_CODE;
				}
				reportError(repair.code, name_index, curtok, curtok);
				break;
			}
			case MERGE_CODE: {
				reportError(repair.code,
							 Parser.terminal_index[repair.symbol],
							 curtok,
							 lexStream.next(curtok));
				break;
			}
			case SCOPE_CODE: {
	            for (int i = 0; i < scopeStackTop; i++) {
	                reportError(repair.code,
	                            -scopeIndex[i],
	                            locationStack[scopePosition[i]],
	                            prevtok,
	                            Parser.non_terminal_index[Parser.scope_lhs[scopeIndex[i]]]);
	            }
	
	            repair.symbol = Parser.scope_lhs[scopeIndex[scopeStackTop]] + NT_OFFSET;
	            stateStackTop = scopePosition[scopeStackTop];
	            reportError(repair.code,
	                        -scopeIndex[scopeStackTop],
	                        locationStack[scopePosition[scopeStackTop]],
	                        prevtok,
	                        getNtermIndex(stack[stateStackTop],
	                                      repair.symbol,
	                                      repair.bufferPosition)
	                       );
	            break;
	        }
			default: {// deletion
				reportError(repair.code, Parser.terminal_index[ERROR_SYMBOL], curtok, curtok);
			}
		}

		//
		//  Update buffer.
		//
		RepairCandidate candidate = new RepairCandidate();
		switch (repair.code) {
			case INSERTION_CODE:
			case BEFORE_CODE:
			case SCOPE_CODE: {
				candidate.symbol = repair.symbol;
				candidate.location = buffer[repair.bufferPosition];
				lexStream.reset(buffer[repair.bufferPosition]);
				break;
			}
			case INVALID_CODE:
			case SUBSTITUTION_CODE: {
				candidate.symbol = repair.symbol;
				candidate.location = buffer[repair.bufferPosition];
				lexStream.reset(buffer[repair.bufferPosition + 1]);
				break;
			}
			case MERGE_CODE: {
				candidate.symbol = repair.symbol;
				candidate.location = buffer[repair.bufferPosition];
				lexStream.reset(buffer[repair.bufferPosition + 2]);
				break;
			}
			default: {// deletion
				candidate.location = buffer[repair.bufferPosition + 1];
				candidate.symbol =
						  lexStream.kind(buffer[repair.bufferPosition + 1]);
				lexStream.reset(buffer[repair.bufferPosition + 2]);
				break;
			}
		}

		return candidate;
	}


//
//	   This function takes as parameter an integer STACK_TOP that
//	   points to a STACK element containing the state on which a
//	   primary recovery will be made; the terminal candidate on which
//	   to recover; and an integer: buffer_position, which points to
//	   the position of the next input token in the BUFFER.  The
//	   parser is simulated until a shift (or shift-reduce) action
//	   is computed on the candidate.  Then we proceed to compute the
//	   the name index of the highest level nonterminal that can
//	   directly or indirectly produce the candidate.
//
	private int getTermIndex(int stck[], int stack_top, int tok, int buffer_position) {
		//
		// Initialize stack index of temp_stack and initialize maximum
		// position of state stack that is still useful.
		//
		int act = stck[stack_top],
			max_pos = stack_top,
			highest_symbol = tok;

		tempStackTop = stack_top - 1;

		//
		// Compute all reduce and associated actions induced by the
		// candidate until a SHIFT or SHIFT-REDUCE is computed. ERROR
		// and ACCEPT actions cannot be computed on the candidate in
		// this context, since we know that it is suitable for recovery.
		//
		lexStream.reset(buffer[buffer_position]);
		act = Parser.tAction(act, tok);
		while(act <= NUM_RULES) {
			//
			// Process all goto-reduce actions following reduction,
			// until a goto action is computed ...
			//
			do {
				tempStackTop -= (Parser.rhs[act]-1);
				int lhs_symbol = Parser.lhs[act];
				act = (tempStackTop > max_pos
									  ? tempStack[tempStackTop]
									  : stck[tempStackTop]);
				act = Parser.ntAction(act, lhs_symbol);
			} while(act <= NUM_RULES);

			//
			// Compute new maximum useful position of (STATE_)stack,
			// push goto state into the stack, and compute next
			// action on candidate ...
			//
			max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
			tempStack[tempStackTop + 1] = act;
			act = Parser.tAction(act, tok);
		}

		//
		// At this stage, we have simulated all actions induced by the
		// candidate and we are ready to shift or shift-reduce it. First,
		// set tok and next_ptr appropriately and identify the candidate
		// as the initial highest_symbol. If a shift action was computed
		// on the candidate, update the stack and compute the next
		// action. Next, simulate all actions possible on the next input
		// token until we either have to shift it or are about to reduce
		// below the initial starting point in the stack (indicated by
		// max_pos as computed in the previous loop).  At that point,
		// return the highest_symbol computed.
		//
		tempStackTop++; // adjust top of stack to reflect last goto
						  // next move is shift or shift-reduce.
		int threshold = tempStackTop;

		tok = lexStream.kind(buffer[buffer_position]);
		lexStream.reset(buffer[buffer_position + 1]);

		if (act > ERROR_ACTION) {  // shift-reduce on candidate?
			act -= ERROR_ACTION;
		} else {
			tempStack[tempStackTop + 1] = act;
			act = Parser.tAction(act, tok);
		}

		while(act <= NUM_RULES) {
			//
			// Process all goto-reduce actions following reduction,
			// until a goto action is computed ...
			//
			do {
				tempStackTop -= (Parser.rhs[act]-1);

				if (tempStackTop < threshold) {
					return (highest_symbol > NT_OFFSET
						 ? Parser.non_terminal_index[highest_symbol - NT_OFFSET]
						 : Parser.terminal_index[highest_symbol]);
				}

				int lhs_symbol = Parser.lhs[act];
				if (tempStackTop == threshold)
					highest_symbol = lhs_symbol + NT_OFFSET;
				act = (tempStackTop > max_pos
									  ? tempStack[tempStackTop]
									  : stck[tempStackTop]);
				act = Parser.ntAction(act, lhs_symbol);
			} while(act <= NUM_RULES);

			tempStack[tempStackTop + 1] = act;
			act = Parser.tAction(act, tok);
		}

		return (highest_symbol > NT_OFFSET
							 ? Parser.non_terminal_index[highest_symbol - NT_OFFSET]
							 : Parser.terminal_index[highest_symbol]);
	}

//
//	   This function takes as parameter a starting state number:
//	   start, a nonterminal symbol, A (candidate), and an integer,
//	   buffer_position,  which points to the position of the next
//	   input token in the BUFFER.
//	   It returns the highest level non-terminal B such that
//	   B =>*rm A.  I.e., there does not exists a nonterminal C such
//	   that C =>+rm B. (Recall that for an LALR(k) grammar if
//	   C =>+rm B, it cannot be the case that B =>+rm C)
//
	private int getNtermIndex(int start, int sym, int buffer_position) {
		int highest_symbol = sym - NT_OFFSET,
			tok = lexStream.kind(buffer[buffer_position]);
		lexStream.reset(buffer[buffer_position + 1]);

		//
		// Initialize stack index of temp_stack and initialize maximum
		// position of state stack that is still useful.
		//
		tempStackTop = 0;
		tempStack[tempStackTop] = start;

		int act = Parser.ntAction(start, highest_symbol);
		if (act > NUM_RULES) { // goto action?
			tempStack[tempStackTop + 1] = act;
			act = Parser.tAction(act, tok);
		}

		while(act <= NUM_RULES) {
			//
			// Process all goto-reduce actions following reduction,
			// until a goto action is computed ...
			//
			do {
				tempStackTop -= (Parser.rhs[act]-1);
				if (tempStackTop < 0)
					return Parser.non_terminal_index[highest_symbol];
				if (tempStackTop == 0)
					highest_symbol = Parser.lhs[act];
				act = Parser.ntAction(tempStack[tempStackTop], Parser.lhs[act]);
			} while(act <= NUM_RULES);
			tempStack[tempStackTop + 1] = act;
			act = Parser.tAction(act, tok);
		}

		return Parser.non_terminal_index[highest_symbol];
	}

	private boolean isBetterSymbol(int symbol, int actualSymbol) {
//		switch (actualSymbol) {
//			case TokenNameinterface :
//				if(symbol == TokenNameclass) {
//					return true;
//				}
//				break;
//		}
		return false;
	}

//
//		   Check whether or not there is a high probability that a
//	   given string is a misspelling of another.
//	   Certain singleton symbols (such as ":" and ";") are also
//	   considered to be misspelling of each other.
//
	private int misspell(int sym, int tok) {
		

		//
		//
		//
		char[] name = Parser.name[Parser.terminal_index[sym]].toCharArray();
		int n = name.length;
		char[] s1 = new char[n + 1];
		for (int k = 0; k < n; k++) {
			char c = name[k];
			s1[k] = Character.toLowerCase(c);
		}
		s1[n] = '\0';

		//
		//
		//
		char[] tokenName = lexStream.name(tok);
		int len = tokenName.length;
		int m = len < MAX_NAME_LENGTH ? len : MAX_NAME_LENGTH;
		char[] s2 = new char[m + 1];
		for (int k = 0; k < m; k++) {
			char c = tokenName[k];
			s2[k] = Character.toLowerCase(c);
		}
		s2[m] = '\0';

		//
		//  Singleton mispellings:
		//
		//  ;      <---->     ,
		//
		//  ;      <---->     :
		//
		//  .      <---->     ,
		//
		//  '      <---->     "
		//
		//
		if (n == 1  &&  m == 1) {
			if ((s1[0] == ';'  &&  s2[0] == ',')  ||
				(s1[0] == ','  &&  s2[0] == ';')  ||
				(s1[0] == ';'  &&  s2[0] == ':')  ||
				(s1[0] == ':'  &&  s2[0] == ';')  ||
				(s1[0] == '.'  &&  s2[0] == ',')  ||
				(s1[0] == ','  &&  s2[0] == '.')  ||
				(s1[0] == '\'' &&  s2[0] == '\"')  ||
				(s1[0] == '\"'  &&  s2[0] == '\'')) {
					return 3;
			}
		}

		//
		// Scan the two strings. Increment "match" count for each match.
		// When a transposition is encountered, increase "match" count
		// by two but count it as an error. When a typo is found, skip
		// it and count it as an error. Otherwise we have a mismatch; if
		// one of the strings is longer, increment its index, otherwise,
		// increment both indices and continue.
		//
		// This algorithm is an adaptation of a boolean misspelling
		// algorithm proposed by Juergen Uhl.
		//
		int count = 0;
		int prefix_length = 0;
		int num_errors = 0;

		int i = 0;
		int j = 0;
		while ((i < n)  &&  (j < m)) {
			if (s1[i] == s2[j]) {
				count++;
				i++;
				j++;
				if (num_errors == 0) {
					prefix_length++;
				}
			} else if (s1[i+1] == s2[j]  &&  s1[i] == s2[j+1]) {
				count += 2;
				i += 2;
				j += 2;
				num_errors++;
			} else if (s1[i+1] == s2[j+1]) {
				i++;
				j++;
				num_errors++;
			} else {
				if ((n - i) > (m - j)) {
					 i++;
				} else if ((m - j) > (n - i)) {
					 j++;
				} else {
					i++;
					j++;
				}
				num_errors++;
			}
		}

		if (i < n  ||  j < m)
			num_errors++;

		if (num_errors > ((n < m ? n : m) / 6 + 1))
			 count = prefix_length;

		return(count * 10 / ((n < len ? len : n) + num_errors));
	}
	
	private PrimaryRepairInfo scopeTrial(int stck[], int stack_top, PrimaryRepairInfo repair) {
	    stateSeen = new int[stackLength];
	    for (int i = 0; i < stackLength; i++)
	        stateSeen[i] = NIL;
	    
	    statePoolTop = 0;
	    statePool = new StateInfo[stackLength];
	
	    scopeTrialCheck(stck, stack_top, repair, 0);
	
	    stateSeen = null;
	    statePoolTop = 0;
	
	    repair.code = SCOPE_CODE;
	    repair.misspellIndex = 10;
	
	    return repair;
	}
	
	private void scopeTrialCheck(int stck[], int stack_top, PrimaryRepairInfo repair, int indx) {
		if(indx > 20) return; // avoid too much recursive call to improve performance
		
		int act = stck[stack_top];
	
	    for (int i = stateSeen[stack_top]; i != NIL; i = statePool[i].next) {
	        if (statePool[i].state == act) return;
	    }

	    int old_state_pool_top = statePoolTop++;
	    if(statePoolTop >= statePool.length) {
	    	System.arraycopy(statePool, 0, statePool = new StateInfo[statePoolTop * 2], 0, statePoolTop);
	    }
	    
	    statePool[old_state_pool_top] = new StateInfo(act, stateSeen[stack_top]);
	    stateSeen[stack_top] = old_state_pool_top;
	
	    for (int i = 0; i < SCOPE_SIZE; i++) {
	        //
	        // Use the scope lookahead symbol to force all reductions
	        // inducible by that symbol.
	        //
	        act = stck[stack_top];
	        tempStackTop = stack_top - 1;
	        int max_pos = stack_top;
	        int tok = Parser.scope_la[i];
	        lexStream.reset(buffer[repair.bufferPosition]);
	        act = Parser.tAction(act, tok);
	        while(act <= NUM_RULES) {
	            //
	            // ... Process all goto-reduce actions following
	            // reduction, until a goto action is computed ...
	            //
	            do  {
	                tempStackTop -= (Parser.rhs[act]-1);
	                int lhs_symbol = Parser.lhs[act];
	                act =  (tempStackTop > max_pos
	                            ?  tempStack[tempStackTop]
	                            :  stck[tempStackTop]);
	                act = Parser.ntAction(act, lhs_symbol);
	            }  while(act <= NUM_RULES);
	            if (tempStackTop + 1 >= stackLength)
	                return;
	            max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
	            tempStack[tempStackTop + 1] = act;
	            act = Parser.tAction(act, tok);
	        }
	
	        //
	        // If the lookahead symbol is parsable, then we check
	        // whether or not we have a match between the scope
	        // prefix and the transition symbols corresponding to
	        // the states on top of the stack.
	        //
	        if (act != ERROR_ACTION) {
	        	int j, k;
	            k = Parser.scope_prefix[i];
	            for (j = tempStackTop + 1;
	                 j >= (max_pos + 1) &&
	                 Parser.in_symbol(tempStack[j]) == Parser.scope_rhs[k]; j--) {
	                 k++;
	            }
	            if (j == max_pos) {
	                for (j = max_pos;
	                     j >= 1 && Parser.in_symbol(stck[j]) == Parser.scope_rhs[k];
	                     j--) {
	                    k++;
	                }
	            }
	            //
	            // If the prefix matches, check whether the state
	            // newly exposed on top of the stack, (after the
	            // corresponding prefix states are popped from the
	            // stack), is in the set of "source states" for the
	            // scope in question and that it is at a position
	            // below the threshold indicated by MARKED_POS.
	            //
	            int marked_pos = (max_pos < stack_top ? max_pos + 1 : stack_top);
	            if (Parser.scope_rhs[k] == 0 && j < marked_pos) { // match?
	                int stack_position = j;
	                for (j = Parser.scope_state_set[i];
	                     stck[stack_position] != Parser.scope_state[j] &&
	                     Parser.scope_state[j] != 0;
	                     j++){/*empty*/}
	                //
	                // If the top state is valid for scope recovery,
	                // the left-hand side of the scope is used as
	                // starting symbol and we calculate how far the
	                // parser can advance within the forward context
	                // after parsing the left-hand symbol.
	                //
	                if (Parser.scope_state[j] != 0) {     // state was found
	                    int previous_distance = repair.distance;
	                    int distance = parseCheck(stck,
	                                          stack_position,
	                                          Parser.scope_lhs[i]+NT_OFFSET,
	                                          repair.bufferPosition);
	                    //
	                    // if the recovery is not successful, we
	                    // update the stack with all actions induced
	                    // by the left-hand symbol, and recursively
	                    // call SCOPE_TRIAL_CHECK to try again.
	                    // Otherwise, the recovery is successful. If
	                    // the new distance is greater than the
	                    // initial SCOPE_DISTANCE, we update
	                    // SCOPE_DISTANCE and set scope_stack_top to INDX
	                    // to indicate the number of scopes that are
	                    // to be applied for a succesful  recovery.
	                    // NOTE that this procedure cannot get into
	                    // an infinite loop, since each prefix match
	                    // is guaranteed to take us to a lower point
	                    // within the stack.
	                    //
	                    if ((distance - repair.bufferPosition + 1) < MIN_DISTANCE) {
	                        int top = stack_position;
	                        act = Parser.ntAction(stck[top], Parser.scope_lhs[i]);
	                        while(act <= NUM_RULES) {
	                            top -= (Parser.rhs[act]-1);
	                            act = Parser.ntAction(stck[top], Parser.lhs[act]);
	                        }
	                        top++;
	
	                        j = act;
	                        act = stck[top];  // save
	                        stck[top] = j;    // swap
	                        scopeTrialCheck(stck, top, repair, indx+1);
	                        stck[top] = act; // restore
	                    } else if (distance > repair.distance) {
	                        scopeStackTop = indx;
	                        repair.distance = distance;
	                    }
	
	                    if (lexStream.kind(buffer[repair.bufferPosition]) == EOFT_SYMBOL &&
	                        repair.distance == previous_distance) {
	                        scopeStackTop = indx;
	                        repair.distance = MAX_DISTANCE;
	                    }
	
	                    //
	                    // If this scope recovery has beaten the
	                    // previous distance, then we have found a
	                    // better recovery (or this recovery is one
	                    // of a list of scope recoveries). Record
	                    // its information at the proper location
	                    // (INDX) in SCOPE_INDEX and SCOPE_STACK.
	                    //
	                    if (repair.distance > previous_distance) {
	                        scopeIndex[indx] = i;
	                        scopePosition[indx] = stack_position;
	                        return;
	                    }
	                }
	            }
	        }
	    }
	}
//
//	   This function computes the ParseCheck distance for the best
//	   possible secondary recovery for a given configuration that
//	   either deletes none or only one symbol in the forward context.
//	   If the recovery found is more effective than the best primary
//	   recovery previously computed, then the function returns true.
//	   Only misplacement, scope and manual recoveries are attempted;
//	   simple insertion or substitution of a nonterminal are tried
//	   in CHECK_PRIMARY_DISTANCE as part of primary recovery.
//
	private boolean secondaryCheck(int stck[], int stack_top, int buffer_position, int distance) {
		int top, j;

		for (top = stack_top - 1; top >= 0; top--) {
			j = parseCheck(stck, top,
						   lexStream.kind(buffer[buffer_position]),
						   buffer_position + 1);
			if (((j - buffer_position + 1) > MIN_DISTANCE) && (j > distance))
				return true;
		}
		
		PrimaryRepairInfo repair = new PrimaryRepairInfo();
	    repair.bufferPosition = buffer_position + 1;
	    repair.distance = distance;
	    repair = scopeTrial(stck, stack_top, repair);
	    if ((repair.distance - buffer_position) > MIN_DISTANCE && repair.distance > distance)
	         return true;
		return false;
	}


//
//	   Secondary_phase is a boolean function that checks whether or
//	   not some form of secondary recovery is applicable to one of
//	   the error configurations. First, if "next_stack" is available,
//	   misplacement and secondary recoveries are attempted on it.
//	   Then, in any case, these recoveries are attempted on "stack".
//	   If a successful recovery is found, a diagnosis is issued, the
//	   configuration is updated and the function returns "true".
//	   Otherwise, the function returns false.
//
	private RepairCandidate secondaryPhase(int error_token) {
		SecondaryRepairInfo repair = new SecondaryRepairInfo();
		SecondaryRepairInfo misplaced = new SecondaryRepairInfo();

		RepairCandidate candidate = new RepairCandidate();

		int i, j, k, top;
		int	next_last_index = 0;
		int	last_index;

		candidate.symbol = 0;

		repair.code = 0;
		repair.distance = 0;
		repair.recoveryOnNextStack = false;

		misplaced.distance = 0;
		misplaced.recoveryOnNextStack = false;

		//
		// If the next_stack is available, try misplaced and secondary
		// recovery on it first.
		//
		if (nextStackTop >= 0) {
			int  save_location;

			buffer[2] = error_token;
			buffer[1] = lexStream.previous(buffer[2]);
			buffer[0] = lexStream.previous(buffer[1]);

			for (k = 3; k < BUFF_UBOUND; k++)
				buffer[k] = lexStream.next(buffer[k - 1]);

			buffer[BUFF_UBOUND] = lexStream.badtoken();// elmt not available

			//
			// If we are at the end of the input stream, compute the
			// index position of the first EOFT symbol (last useful
			// index).
			//
			for (next_last_index = MAX_DISTANCE - 1;
				 next_last_index >= 1 &&
				 lexStream.kind(buffer[next_last_index]) == EOFT_SYMBOL;
				 next_last_index--){/*empty*/}
			next_last_index = next_last_index + 1;

			save_location = locationStack[nextStackTop];
			int save_location_start = locationStartStack[nextStackTop];
			locationStack[nextStackTop] = buffer[2];
			locationStartStack[nextStackTop] = lexStream.start(buffer[2]);
			misplaced.numDeletions = nextStackTop;
			misplaced = misplacementRecovery(nextStack, nextStackTop,
											 next_last_index,
											 misplaced, true);
			if (misplaced.recoveryOnNextStack)
				misplaced.distance++;

			repair.numDeletions = nextStackTop + BUFF_UBOUND;
			repair = secondaryRecovery(nextStack, nextStackTop,
									   next_last_index,
									   repair, true);
			if (repair.recoveryOnNextStack)
				repair.distance++;

			locationStack[nextStackTop] = save_location;
			locationStartStack[nextStackTop] = save_location_start;
		} else {            // next_stack not available, initialize ...
			misplaced.numDeletions = stateStackTop;
			repair.numDeletions = stateStackTop + BUFF_UBOUND;
		}

		//
		// Try secondary recovery on the "stack" configuration.
		//
		buffer[3] = error_token;

		buffer[2] = lexStream.previous(buffer[3]);
		buffer[1] = lexStream.previous(buffer[2]);
		buffer[0] = lexStream.previous(buffer[1]);

		for (k = 4; k < BUFF_SIZE; k++)
			buffer[k] = lexStream.next(buffer[k - 1]);

		for (last_index = MAX_DISTANCE - 1;
			 last_index >= 1 && lexStream.kind(buffer[last_index]) == EOFT_SYMBOL;
			 last_index--){/*empty*/}
		last_index++;

		misplaced = misplacementRecovery(stack, stateStackTop,
										 last_index,
										 misplaced, false);

		repair = secondaryRecovery(stack, stateStackTop,
								   last_index, repair, false);

		//
		// If a successful misplaced recovery was found, compare it with
		// the most successful secondary recovery.  If the misplaced
		// recovery either deletes fewer symbols or parse-checks further
		// then it is chosen.
		//
		if (misplaced.distance > MIN_DISTANCE) {
			if (misplaced.numDeletions <= repair.numDeletions ||
			   (misplaced.distance - misplaced.numDeletions) >=
			   (repair.distance - repair.numDeletions)) {
				repair.code = MISPLACED_CODE;
				repair.stackPosition = misplaced.stackPosition;
				repair.bufferPosition = 2;
				repair.numDeletions = misplaced.numDeletions;
				repair.distance = misplaced.distance;
				repair.recoveryOnNextStack = misplaced.recoveryOnNextStack;
			}
		}

		//
		// If the successful recovery was on next_stack, update: stack,
		// buffer, location_stack and last_index.
		//
		if (repair.recoveryOnNextStack) {
			stateStackTop = nextStackTop;
			for (i = 0; i <= stateStackTop; i++)
				stack[i] = nextStack[i];

			buffer[2] = error_token;
			buffer[1] = lexStream.previous(buffer[2]);
			buffer[0] = lexStream.previous(buffer[1]);

			for (k = 3; k < BUFF_UBOUND; k++)
				buffer[k] = lexStream.next(buffer[k - 1]);

			buffer[BUFF_UBOUND] = lexStream.badtoken();// elmt not available

			locationStack[nextStackTop] = buffer[2];
			locationStartStack[nextStackTop] = lexStream.start(buffer[2]);
			last_index = next_last_index;
		}

	    //
	    // Next, try scope recoveries after deletion of one, two, three,
	    // four ... buffer_position tokens from the input stream.
	    //
	    if (repair.code == SECONDARY_CODE || repair.code == DELETION_CODE) {
	        PrimaryRepairInfo scope_repair = new PrimaryRepairInfo();
	
	        scope_repair.distance = 0;
	        for (scope_repair.bufferPosition = 2;
	             scope_repair.bufferPosition <= repair.bufferPosition &&
	             repair.code != SCOPE_CODE; scope_repair.bufferPosition++) {
	            scope_repair = scopeTrial(stack, stateStackTop, scope_repair);
	            j = (scope_repair.distance == MAX_DISTANCE
	                                        ? last_index
	                                        : scope_repair.distance);
	            k = scope_repair.bufferPosition - 1;
	            if ((j - k) > MIN_DISTANCE && (j - k) > (repair.distance - repair.numDeletions)) {
	                repair.code = SCOPE_CODE;
	                i = scopeIndex[scopeStackTop];       // upper bound
	                repair.symbol = Parser.scope_lhs[i] + NT_OFFSET;
	                repair.stackPosition = stateStackTop;
	                repair.bufferPosition = scope_repair.bufferPosition;
	            }
	        }
	    }
	
	    //
	    // If no successful recovery is found and we have reached the
	    // end of the file, check whether or not scope recovery is
	    // applicable at the end of the file after discarding some
	    // states.
	    //
	    if (repair.code == 0 && lexStream.kind(buffer[last_index]) == EOFT_SYMBOL) {
	        PrimaryRepairInfo scope_repair = new PrimaryRepairInfo();
	
	        scope_repair.bufferPosition = last_index;
	        scope_repair.distance = 0;
	        for (top = stateStackTop;
	             top >= 0 && repair.code == 0; top--)
	        {
	            scope_repair = scopeTrial(stack, top, scope_repair);
	            if (scope_repair.distance > 0)
	            {
	                repair.code = SCOPE_CODE;
	                i = scopeIndex[scopeStackTop];    // upper bound
	                repair.symbol = Parser.scope_lhs[i] + NT_OFFSET;
	                repair.stackPosition = top;
	                repair.bufferPosition = scope_repair.bufferPosition;
	            }
	        }
	    }

		//
		// If a successful repair was not found, quit!  Otherwise, issue
		// diagnosis and adjust configuration...
		//
		if (repair.code == 0)
			return candidate;

		secondaryDiagnosis(repair);

		//
		// Update buffer based on number of elements that are deleted.
		//
		switch(repair.code) {
			case MISPLACED_CODE:
				 candidate.location = buffer[2];
				 candidate.symbol = lexStream.kind(buffer[2]);
				 lexStream.reset(lexStream.next(buffer[2]));

				 break;

			case DELETION_CODE:
				 candidate.location = buffer[repair.bufferPosition];
				 candidate.symbol =
						   lexStream.kind(buffer[repair.bufferPosition]);
				 lexStream.reset(lexStream.next(buffer[repair.bufferPosition]));

				 break;

		default: // SCOPE_CODE || SECONDARY_CODE
				 candidate.symbol = repair.symbol;
				 candidate.location = buffer[repair.bufferPosition];
				 lexStream.reset(buffer[repair.bufferPosition]);

				 break;
		}

		return candidate;
	}


//
//	   This boolean function checks whether or not a given
//	   configuration yields a better misplacement recovery than
//	   the best misplacement recovery computed previously.
//
	private SecondaryRepairInfo misplacementRecovery(int stck[], int stack_top, int last_index, SecondaryRepairInfo repair, boolean stack_flag) {
		int  previous_loc = buffer[2];
		int stack_deletions = 0;

		for (int top = stack_top - 1; top >= 0; top--) {
			if (locationStack[top] < previous_loc) {
				stack_deletions++;
			}
			previous_loc = locationStack[top];

			int j = parseCheck(stck, top, lexStream.kind(buffer[2]), 3);
			if (j == MAX_DISTANCE) {
				 j = last_index;
			}
			if ((j > MIN_DISTANCE) && (j - stack_deletions) > (repair.distance - repair.numDeletions)) {
				repair.stackPosition = top;
				repair.distance = j;
				repair.numDeletions = stack_deletions;
				repair.recoveryOnNextStack = stack_flag;
			}
		}

		return repair;
	}


//
//	   This boolean function checks whether or not a given
//	   configuration yields a better secondary recovery than the
//	   best misplacement recovery computed previously.
//
	private SecondaryRepairInfo secondaryRecovery(int stck[],int stack_top, int last_index, SecondaryRepairInfo repair, boolean stack_flag) {
		int previous_loc;
		int stack_deletions = 0;
		
		previous_loc = buffer[2];
		for (int top = stack_top; top >= 0 && repair.numDeletions >= stack_deletions; top--) {
			if (locationStack[top] < previous_loc) {
				stack_deletions++;
			}
			previous_loc = locationStack[top];

			for (int i = 2;
				 i <= (last_index - MIN_DISTANCE + 1) &&
				 (repair.numDeletions >= (stack_deletions + i - 1)); i++) {
				int j = parseCheck(stck, top, lexStream.kind(buffer[i]), i + 1);

				if (j == MAX_DISTANCE) {
					 j = last_index;
				}
				if ((j - i + 1) > MIN_DISTANCE) {
					int k = stack_deletions + i - 1;
					if ((k < repair.numDeletions) ||
						(j - k) > (repair.distance - repair.numDeletions) ||
						((repair.code == SECONDARY_CODE) && (j - k) == (repair.distance - repair.numDeletions))) {
						repair.code = DELETION_CODE;
						repair.distance = j;
						repair.stackPosition = top;
						repair.bufferPosition = i;
						repair.numDeletions = k;
						repair.recoveryOnNextStack = stack_flag;
					}
				}

				for (int l = Parser.nasi(stck[top]); l >= 0 && Parser.nasr[l] != 0; l++) {
					int symbol = Parser.nasr[l] + NT_OFFSET;
					j = parseCheck(stck, top, symbol, i);
					if (j == MAX_DISTANCE) {
						 j = last_index;
					}
					if ((j - i + 1) > MIN_DISTANCE) {
						int k = stack_deletions + i - 1;
						if (k < repair.numDeletions || (j - k) > (repair.distance - repair.numDeletions)) {
							repair.code = SECONDARY_CODE;
							repair.symbol = symbol;
							repair.distance = j;
							repair.stackPosition = top;
							repair.bufferPosition = i;
							repair.numDeletions = k;
							repair.recoveryOnNextStack = stack_flag;
						}
					}
				}
			}
		}

		return repair;
	}


//
//	   This procedure is invoked to issue a secondary diagnosis and
//	   adjust the input buffer.  The recovery in question is either
//	   an automatic scope recovery, a manual scope recovery, a
//	   secondary substitution or a secondary deletion.
//
	private void secondaryDiagnosis(SecondaryRepairInfo repair) {
		switch(repair.code) {
			case SCOPE_CODE: {
	            if (repair.stackPosition < stateStackTop) {
	                reportError(DELETION_CODE,
	                            Parser.terminal_index[ERROR_SYMBOL],
	                            locationStack[repair.stackPosition],
	                            buffer[1]);
	            }
	            for (int i = 0; i < scopeStackTop; i++) {
	                reportError(SCOPE_CODE,
	                            -scopeIndex[i],
	                            locationStack[scopePosition[i]],
	                            buffer[1],
	                            Parser.non_terminal_index[Parser.scope_lhs[scopeIndex[i]]]);
	            }
	
	            repair.symbol = Parser.scope_lhs[scopeIndex[scopeStackTop]] + NT_OFFSET;
	            stateStackTop = scopePosition[scopeStackTop];
	            reportError(SCOPE_CODE,
	                        -scopeIndex[scopeStackTop],
	                        locationStack[scopePosition[scopeStackTop]],
	                        buffer[1],
	                        getNtermIndex(stack[stateStackTop],
	                                      repair.symbol,
	                                      repair.bufferPosition)
	                       );
	            break;
	        }
			default: {
				reportError(repair.code,
							(repair.code == SECONDARY_CODE
										  ? getNtermIndex(stack[repair.stackPosition],
														  repair.symbol,
														  repair.bufferPosition)
										  : Parser.terminal_index[ERROR_SYMBOL]),
							locationStack[repair.stackPosition],
							buffer[repair.bufferPosition - 1]);
				stateStackTop = repair.stackPosition;
			}
		}
	}




//
//	   Try to parse until first_token and all tokens in BUFFER have
//	   been consumed, or an error is encountered. Return the number
//	   of tokens that were expended before the parse blocked.
//
	private int parseCheck(int stck[], int stack_top, int first_token, int buffer_position) {
		int max_pos;
		int indx;
		int ct;
		int act;

		//
		// Initialize pointer for temp_stack and initialize maximum
		// position of state stack that is still useful.
		//
		act = stck[stack_top];
		if (first_token > NT_OFFSET) {
			tempStackTop = stack_top;
			if(DEBUG_PARSECHECK) {
				System.out.println(tempStackTop);
			}
			max_pos = stack_top;
			indx = buffer_position;
			ct = lexStream.kind(buffer[indx]);
			lexStream.reset(lexStream.next(buffer[indx]));
			int lhs_symbol = first_token - NT_OFFSET;
			act = Parser.ntAction(act, lhs_symbol);
			if (act <= NUM_RULES) {
				// same loop as 'process_non_terminal'
				do {
					tempStackTop -= (Parser.rhs[act]-1);
					
					if(DEBUG_PARSECHECK) {
						System.out.print(tempStackTop);
						System.out.print(" ("); //$NON-NLS-1$
						System.out.print(-(Parser.rhs[act]-1));
						System.out.print(") [max:"); //$NON-NLS-1$
						System.out.print(max_pos);
						System.out.print("]\tprocess_non_terminal\t"); //$NON-NLS-1$
						System.out.print(act);
						System.out.print("\t"); //$NON-NLS-1$
						System.out.print(Parser.name[Parser.non_terminal_index[Parser.lhs[act]]]);
						System.out.println();
					}
					
					if(Parser.rules_compliance[act] > this.options.sourceLevel) {
					 	return 0;
					}
					lhs_symbol = Parser.lhs[act];
					act = (tempStackTop > max_pos
										  ? tempStack[tempStackTop]
										  : stck[tempStackTop]);
					act = Parser.ntAction(act, lhs_symbol);
				} while(act <= NUM_RULES);
	
				max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
			}
		} else {
			tempStackTop = stack_top - 1;
			
			if(DEBUG_PARSECHECK) {
				System.out.println(tempStackTop);
			}
			
			max_pos = tempStackTop;
			indx = buffer_position - 1;
			ct = first_token;
			lexStream.reset(buffer[buffer_position]);
		}

		process_terminal: for (;;) {
			if(DEBUG_PARSECHECK) {
				System.out.print(tempStackTop + 1);
				System.out.print(" (+1) [max:"); //$NON-NLS-1$
				System.out.print(max_pos);
				System.out.print("]\tprocess_terminal    \t"); //$NON-NLS-1$
				System.out.print(ct);
				System.out.print("\t"); //$NON-NLS-1$
				System.out.print(Parser.name[Parser.terminal_index[ct]]);
				System.out.println();
			}
			
			if (++tempStackTop >= stackLength)  // Stack overflow!!!
				return indx;
			tempStack[tempStackTop] = act;

			act = Parser.tAction(act, ct);

			if (act <= NUM_RULES) {               // reduce action
				tempStackTop--;
				
				if(DEBUG_PARSECHECK) {
					System.out.print(tempStackTop);
					System.out.print(" (-1) [max:"); //$NON-NLS-1$
					System.out.print(max_pos);
					System.out.print("]\treduce"); //$NON-NLS-1$
					System.out.println();
				}
			} else if (act < ACCEPT_ACTION ||     // shift action
					 act > ERROR_ACTION) {        // shift-reduce action
				if (indx == MAX_DISTANCE)
					return indx;
				indx++;
				ct = lexStream.kind(buffer[indx]);
				lexStream.reset(lexStream.next(buffer[indx]));
				if (act > ERROR_ACTION) {
					act -= ERROR_ACTION;
					
					if(DEBUG_PARSECHECK) {
						System.out.print(tempStackTop);
						System.out.print("\tshift reduce"); //$NON-NLS-1$
						System.out.println();
					}
				} else {
					if(DEBUG_PARSECHECK) {
						System.out.println("\tshift"); //$NON-NLS-1$
					}
					continue process_terminal;
				}
			} else if (act == ACCEPT_ACTION) {           // accept action
				 return MAX_DISTANCE;
			} else {
				return indx;                         // error action
			}

			// same loop as first token initialization
			// process_non_terminal:
			do {
				tempStackTop -= (Parser.rhs[act]-1);
				
				if(DEBUG_PARSECHECK) {
					System.out.print(tempStackTop);
					System.out.print(" ("); //$NON-NLS-1$
					System.out.print(-(Parser.rhs[act]-1));
					System.out.print(") [max:"); //$NON-NLS-1$
					System.out.print(max_pos);
					System.out.print("]\tprocess_non_terminal\t"); //$NON-NLS-1$
					System.out.print(act);
					System.out.print("\t"); //$NON-NLS-1$
					System.out.print(Parser.name[Parser.non_terminal_index[Parser.lhs[act]]]);
					System.out.println();
				}
				
				if(act <= NUM_RULES) {
					if(Parser.rules_compliance[act] > this.options.sourceLevel) {
					 	return 0;
					}
				}
				int lhs_symbol = Parser.lhs[act];
				act = (tempStackTop > max_pos
									  ? tempStack[tempStackTop]
									  : stck[tempStackTop]);
				act = Parser.ntAction(act, lhs_symbol);
			} while(act <= NUM_RULES);

			max_pos = max_pos < tempStackTop ? max_pos : tempStackTop;
		} // process_terminal;
	}
	private void reportError(int msgCode, int nameIndex, int leftToken, int rightToken) {
		reportError(msgCode, nameIndex, leftToken, rightToken, 0);
	}

	private void reportError(int msgCode, int nameIndex, int leftToken, int rightToken, int scopeNameIndex) {
		int lToken = (leftToken > rightToken ? rightToken : leftToken);

		if (lToken < rightToken) {
			reportSecondaryError(msgCode, nameIndex, lToken, rightToken, scopeNameIndex);
		} else {
			reportPrimaryError(msgCode, nameIndex, rightToken, scopeNameIndex);
		}
	}
	private void reportPrimaryError(int msgCode, int nameIndex, int token, int scopeNameIndex) {
		String name;
		if (nameIndex >= 0) {
			name = Parser.readableName[nameIndex];
		} else {
			name = EMPTY_STRING;
		}

		int errorStart = lexStream.start(token);
		int errorEnd = lexStream.end(token);
		int currentKind = lexStream.kind(token);
		String errorTokenName = Parser.name[Parser.terminal_index[lexStream.kind(token)]];
		char[] errorTokenSource = lexStream.name(token);

		switch(msgCode) {
			case BEFORE_CODE:
				problemReporter().parseErrorInsertBeforeToken(
					errorStart, 
					errorEnd, 
					currentKind,
					errorTokenSource, 
					errorTokenName, 
					name);
				 break;
			case INSERTION_CODE:
				problemReporter().parseErrorInsertAfterToken(
					errorStart, 
					errorEnd, 
					currentKind,
					errorTokenSource, 
					errorTokenName, 
					name);  
				 break;
			case DELETION_CODE:
				problemReporter().parseErrorDeleteToken(
					errorStart, 
					errorEnd, 
					currentKind,
					errorTokenSource, 
					errorTokenName);
				break;
			case INVALID_CODE:
				if (name.length() == 0) {
					problemReporter().parseErrorReplaceToken(
						errorStart, 
						errorEnd, 
						currentKind,
						errorTokenSource, 
						errorTokenName, 
						name);
				} else {
					problemReporter().parseErrorInvalidToken(
						errorStart, 
						errorEnd, 
						currentKind,
						errorTokenSource, 
						errorTokenName, 
						name);
				}
				break;
			case SUBSTITUTION_CODE:
				problemReporter().parseErrorReplaceToken(
					errorStart, 
					errorEnd, 
					currentKind,
					errorTokenSource, 
					errorTokenName, 
					name); 
				 break;
			case SCOPE_CODE:
				StringBuffer buf = new StringBuffer();
				for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
					buf.append(Parser.readableName[Parser.scope_rhs[i]]);
					if (Parser.scope_rhs[i + 1] != 0) // any more symbols to print?
						buf.append(' ');
						
				}

				if (scopeNameIndex != 0) {
					problemReporter().parseErrorInsertToComplete(
						errorStart, 
						errorEnd,
						buf.toString(),
						Parser.readableName[scopeNameIndex]);
				} else {
					problemReporter().parseErrorInsertToCompleteScope(
						errorStart, 
						errorEnd,
						buf.toString()); 
				}
				
				break;
			case EOF_CODE:
				problemReporter().parseErrorUnexpectedEnd(
					errorStart, 
					errorEnd); 
				break;
			case MERGE_CODE:
				problemReporter().parseErrorMergeTokens(
					errorStart, 
					errorEnd,
					name);
				break;
			case MISPLACED_CODE:
				problemReporter().parseErrorMisplacedConstruct(
					errorStart, 
					errorEnd);
				break;
			default:
				if (name.length() == 0) {
					problemReporter().parseErrorNoSuggestion(
						errorStart, 
						errorEnd, 
						currentKind,
						errorTokenSource, 
						errorTokenName);
				} else {
					problemReporter().parseErrorReplaceToken(
						errorStart, 
						errorEnd, 
						currentKind,
						errorTokenSource, 
						errorTokenName, 
						name); 
				}
				break;
		}
	}

	private void reportSecondaryError(int msgCode,	int nameIndex,	int leftToken,	int rightToken, int scopeNameIndex) {
		String name;
		if (nameIndex >= 0) {
			name = Parser.readableName[nameIndex];
		} else {
			name = EMPTY_STRING;	
		}

		int errorStart = -1;
		if(lexStream.isInsideStream(leftToken)) {
			if(leftToken == 0) {
				errorStart = lexStream.start(leftToken + 1);
			} else {
				errorStart = lexStream.start(leftToken);
			}
		} else {
			if(leftToken == errorToken) {
				errorStart = errorTokenStart;
			} else {
				for (int i = 0; i <= stateStackTop; i++) {
					if(locationStack[i] == leftToken) {
						errorStart = locationStartStack[i];
					}
				}
			}
			if(errorStart == -1) {
				errorStart = lexStream.start(rightToken);
			}
		}
		int errorEnd = lexStream.end(rightToken);
		
		switch(msgCode) {
			case MISPLACED_CODE:
				problemReporter().parseErrorMisplacedConstruct(
					errorStart, 
					errorEnd); 
				break;
			case SCOPE_CODE:
				// error start is on the last token start
				errorStart = lexStream.start(rightToken);
			
	            StringBuffer buf = new StringBuffer();
	            for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
	                buf.append(Parser.readableName[Parser.scope_rhs[i]]);
	                if (Parser.scope_rhs[i+1] != 0)
	                     buf.append(' ');
	            }
	            if (scopeNameIndex != 0) {
	                problemReporter().parseErrorInsertToComplete(
						errorStart, 
						errorEnd,
						buf.toString(),
						Parser.readableName[scopeNameIndex]);
	            } else {
	            	problemReporter().parseErrorInsertToCompletePhrase(
						errorStart, 
						errorEnd,
						buf.toString()); 
	            }
	            break;
			case MERGE_CODE:
				problemReporter().parseErrorMergeTokens(
					errorStart, 
					errorEnd,
					name);
				break;
			case DELETION_CODE:
				problemReporter().parseErrorDeleteTokens(
					errorStart, 
					errorEnd);
				break;
			default:
				if (name.length() == 0) {
					problemReporter().parseErrorNoSuggestionForTokens(
						errorStart, 
						errorEnd);
				} else {
					problemReporter().parseErrorReplaceTokens(
						errorStart, 
						errorEnd,
						name);
				}
		}
		return;
	}

	public String toString() {
		StringBuffer res = new StringBuffer();
		
		res.append(lexStream.toString());
		
		return res.toString();
	}
}
