boolean main_loop = true,hasDTD = false,hasDecl = false,docEnd = false,firstLT = true;
boolean main_loop = true,hasDTD = false,docEnd = false;
	public void parse(boolean NS)		throws EncodingException, EOFException, EntityException, ParseException {		// define internal variables			ns = NS;		int length1 = 0, length2 = 0;		int attr_count = 0 /*, ch = 0, ch_temp = 0*/;		int prev_ch = 0, prev2_ch = 0, parser_state = STATE_DOC_START;		//boolean has_amp = false; 		boolean is_ns = false;		encoding = FORMAT_UTF8;		boolean helper=false;		boolean main_loop = true,hasDTD = false,hasDecl = false,docEnd = false,firstLT = true;		//char char_temp; //holds the ' or " indicating start of attr val		//boolean must_utf_8 = false;		//boolean BOM_detected = false;		//long[] tag_stack = new long[256];		//long[] attr_name_array = new long[512]; // 512 attributes limit		//ASCII UTF-8 UTF-16 UTF-16BE UTF-16LE ISO-8859-1		//		//int[] scratch_buffer = new int[10];		// first check first several bytes to figure out the encoding		decide_encoding();		// enter the main finite state machine		try {			writeVTD(0,0,TOKEN_DOCUMENT,depth);			while (main_loop) {				switch (parser_state) {					case STATE_DOC_START :						if (r.getChar() == '<') {							temp_offset = offset;							// xml decl has to be right after the start of the document							if (r.skipChar('?')								&& (r.skipChar('x') || r.skipChar('X'))								&& (r.skipChar('m') || r.skipChar('M'))								&& (r.skipChar('l') || r.skipChar('L'))) {								if (r.skipChar(' ')									|| r.skipChar('\t')									|| r.skipChar('\n')									|| r.skipChar('\r')) {									ch = getCharAfterS();									temp_offset = offset;									parser_state = STATE_DEC_ATTR_NAME;									break;								} else if (r.skipChar('?'))									throw new ParseException(										"Error in XML decl: Premature ending"											+ formatLineNumber());							}							offset = temp_offset;							parser_state = STATE_LT_SEEN;							break;						}						throw new ParseException(							"Other Error: XML not starting properly"								+ formatLineNumber());					case STATE_DOC_END :						docEnd = true;						ch = getCharAfterS();						// eof exception should be thrown here for premature ending						if (ch == '<') {							if (r.skipChar('?')) {								// processing instruction after end tag of root element								temp_offset = offset;								parser_state = STATE_END_PI;								break;							} else if (								r.skipChar('!')									&& r.skipChar('-')									&& r.skipChar('-')) {								// comments allowed after the end tag of the root element								temp_offset = offset;								parser_state = STATE_END_COMMENT;								break;							}						}						throw new ParseException(							"Other Error: XML not terminated properly"								+ formatLineNumber());					case STATE_LT_SEEN : //if (depth < -1)						//    throw new ParseException("Other Errors: Invalid depth");						temp_offset = offset;						ch = r.getChar();						if (XMLChar.isNameStartChar(ch)) {							//temp_offset = offset;							//length1++;							depth++;							//if (ch == ':')							//   length2 = 0;							parser_state = STATE_START_TAG;						} else {							switch (ch) {								case '/' :									parser_state = STATE_END_TAG;									break;								case '?' :									temp_offset = offset;									ch = r.getChar();									if (XMLChar.isNameStartChar(ch)) {										//temp_offset = offset;										if ((ch == 'x' || ch == 'X')											&& (r.skipChar('m')	|| r.skipChar('M'))											&& (r.skipChar('l')	|| r.skipChar('L'))) {											ch = r.getChar();											if (ch == '?'												|| XMLChar.isSpaceChar(ch))												throw new ParseException(													"Error in PI: [xX][mM][lL] not a valid PI targetname"														+ formatLineNumber());											offset = getPrevOffset();										}										parser_state = STATE_PI_TAG;										break;									}									throw new ParseException(										"Other Error: First char after <? invalid"											+ formatLineNumber());								case '!' : // three possibility (comment, CDATA, DOCTYPE)									ch = r.getChar();									switch (ch) {										case '-' :											if (r.skipChar('-')) {												temp_offset = offset;												parser_state = STATE_COMMENT;												break;											} else												throw new ParseException(													"Error in comment: Invalid char sequence to start a comment"														+ formatLineNumber());										case '[' :											if (r.skipChar('C')												&& r.skipChar('D')												&& r.skipChar('A')												&& r.skipChar('T')												&& r.skipChar('A')												&& r.skipChar('[')												&& (depth != -1)) {												temp_offset = offset;												parser_state = STATE_CDATA;												break;											} else {												if (depth == -1)													throw new ParseException(														"Error in CDATA: Wrong place for CDATA"															+ formatLineNumber());												throw new ParseException(													"Error in CDATA: Invalid char sequence for CDATA"														+ formatLineNumber());											}										case 'D' :											if (r.skipChar('O')												&& r.skipChar('C')												&& r.skipChar('T')												&& r.skipChar('Y')												&& r.skipChar('P')												&& r.skipChar('E')												&& (depth == -1)												&& !hasDTD) {												hasDTD = true;												temp_offset = offset;												parser_state = STATE_DOCTYPE;												break;											} else {												if (hasDTD == true)													throw new ParseException(														"Error for DOCTYPE: Only DOCTYPE allowed"															+ formatLineNumber());												if (depth != -1)													throw new ParseException(														"Error for DOCTYPE: DTD at wrong place"															+ formatLineNumber());												throw new ParseException(													"Error for DOCTYPE: Invalid char sequence for DOCTYPE"														+ formatLineNumber());											}										default :											throw new ParseException(												"Other Error: Unrecognized char after <!"													+ formatLineNumber());									}									break;								default :									throw new ParseException(										"Other Error: Invalid char after <"											+ formatLineNumber());							}						}						break;					case STATE_START_TAG : //name space is handled by						while (true) {							ch = r.getChar();							if (XMLChar.isNameChar(ch)) {								if (ch == ':') {									length2 = offset - temp_offset - increment;								}							} else								break;						}						length1 = offset - temp_offset - increment;						if (depth > MAX_DEPTH) {							throw new ParseException(								"Other Error: Depth exceeds MAX_DEPTH"									+ formatLineNumber());						}						//writeVTD(offset, TOKEN_STARTING_TAG, length2:length1, depth)						long x = ((long) length1 << 32) + temp_offset;						tag_stack[depth] = x;												// System.out.println(						//     " " + (temp_offset) + " " + length2 + ":" + length1 + " startingTag " + depth);						if (depth > VTDDepth)							VTDDepth = depth;						if (encoding < FORMAT_UTF_16BE){							if (length2>MAX_PREFIX_LENGTH									|| length1 > MAX_QNAME_LENGTH)								throw new ParseException(										"Token Length Error: Starting tag prefix or qname length too long"															+ formatLineNumber());							writeVTD(								(temp_offset),								(length2 << 11) | length1,								TOKEN_STARTING_TAG,								depth);							}						else{							if (length2>(MAX_PREFIX_LENGTH <<1)									|| length1 > (MAX_QNAME_LENGTH<<1))								throw new ParseException(										"Token Length Error: Starting tag prefix or qname length too long"										+formatLineNumber());							writeVTD(								(temp_offset) >> 1,								(length2 << 10) | (length1 >> 1),								TOKEN_STARTING_TAG,								depth);						}						//offset += length1;						length2 = 0;						if (XMLChar.isSpaceChar(ch)) {							ch = getCharAfterS();							if (XMLChar.isNameStartChar(ch)) {								// seen an attribute here								temp_offset = getPrevOffset();								parser_state = STATE_ATTR_NAME;								break;							}						}						helper = true;						if (ch == '/') {							depth--;							helper = false;							ch = r.getChar();						}						if (ch == '>') {						if (depth != -1) {							temp_offset = offset;							ch = getCharAfterSe(); // consume WSs							if (ch == '<') {								parser_state = STATE_LT_SEEN;								if (r.skipChar('/')) {									if (helper == true) {										length1 = offset - temp_offset												- (increment << 1);										if (length1 > 0) {											if (encoding < FORMAT_UTF_16BE)												writeVTD((temp_offset),														length1,														TOKEN_CHARACTER_DATA,														depth);											else												writeVTD((temp_offset) >> 1,														(length1 >> 1),														TOKEN_CHARACTER_DATA,														depth);										}									}									parser_state = STATE_END_TAG;									break;								}							} else if (XMLChar.isContentChar(ch)) {								//temp_offset = offset;								parser_state = STATE_TEXT;							} else if (ch == '&') {								//has_amp = true;								//temp_offset = offset;								entityIdentifier();								parser_state = STATE_TEXT;							} else if (ch == ']') {								if (r.skipChar(']')) {									while (r.skipChar(']')) {									}									if (r.skipChar('>'))										throw new ParseException(												"Error in text content: ]]> in text content"														+ formatLineNumber());								}								parser_state = STATE_TEXT;							} else								throw new ParseException(										"Error in text content: Invalid char"												+ formatLineNumber());						} else {							parser_state = STATE_DOC_END;						}						break;					}					throw new ParseException(							"Starting tag Error: Invalid char in starting tag"									+ formatLineNumber());					case STATE_END_TAG :						temp_offset = offset;						int sos = (int) tag_stack[depth];						int sl = (int) (tag_stack[depth] >> 32);												offset = temp_offset+sl;												if (offset>= endOffset)							throw new EOFException("permature EOF reached, XML document incomplete");						for (int i = 0; i < sl; i++) {							if (XMLDoc[sos + i] != XMLDoc[temp_offset + i])								throw new ParseException(									"Ending tag error: Start/ending tag mismatch"									+ formatLineNumber());						}						depth--;						ch = getCharAfterS();						if(ch != '>')							throw new ParseException(								"Ending tag error: Invalid char in ending tag "								+ formatLineNumber()); 												if (depth != -1) {							temp_offset = offset;							ch = getCharAfterS();							if (ch == '<')								parser_state = STATE_LT_SEEN;							else if (XMLChar.isContentChar(ch)) {								parser_state = STATE_TEXT;							} 							else if (ch == '&') {								//has_amp = true;								entityIdentifier();								parser_state = STATE_TEXT;							} 							else if (ch == ']') {								if (r.skipChar(']')) {									while (r.skipChar(']')) {									}									if (r.skipChar('>'))										throw new ParseException(										"Error in text content: ]]> in text content"										+ formatLineNumber());								}									parser_state = STATE_TEXT;							}else								throw new ParseException(									"Other Error: Invalid char in xml"									+ formatLineNumber());						} else							parser_state = STATE_DOC_END;						break;											case STATE_UNRECORDED_TEXT :						break;					case STATE_PI_TAG :						parser_state = process_pi_tag();						break;						//throw new ParseException("Error in PI: Invalid char");					case STATE_PI_VAL :						parser_state = process_pi_val();						break;					case STATE_DEC_ATTR_NAME :						parser_state = process_dec_attr();						break;											case STATE_COMMENT :						parser_state = process_comment();						break;											case STATE_CDATA :						parser_state = process_cdata();						break;											case STATE_DOCTYPE :						parser_state = process_doc_type();						break;										case STATE_TEXT :						if (depth == -1)							throw new ParseException(								"Error in text content: Char data at the wrong place"									+ formatLineNumber());						while (true) {							ch = r.getChar();							if (XMLChar.isContentChar(ch)) {							} else if (ch == '&') {								//has_amp = true;								if (!XMLChar.isValidChar(entityIdentifier()))									throw new ParseException(										"Error in text content: Invalid char in text content "											+ formatLineNumber());								//parser_state = STATE_TEXT;							} else if (ch == '<') {								break;							} else if (ch == ']') {								if (r.skipChar(']')) {									while (r.skipChar(']')) {									}									if (r.skipChar('>'))										throw new ParseException(											"Error in text content: ]]> in text content"												+ formatLineNumber());								}							} else								throw new ParseException(									"Error in text content: Invalid char in text content "										+ formatLineNumber());						}						length1 = offset - increment - temp_offset;						if (encoding < FORMAT_UTF_16BE)							writeVTD(								temp_offset,								length1,								TOKEN_CHARACTER_DATA,								depth);						else							writeVTD(								temp_offset >> 1,								length1 >> 1,								TOKEN_CHARACTER_DATA,								depth);						//has_amp = true;						parser_state = STATE_LT_SEEN;						break;					case STATE_ATTR_NAME :						if (ch == 'x') {							if (r.skipChar('m')								&& r.skipChar('l')								&& r.skipChar('n')								&& r.skipChar('s')) {								ch = r.getChar();								if (ch == '='									|| XMLChar.isSpaceChar(ch)									|| ch == ':') {									is_ns = true; //break;								}							}						}						while (true) {							if (XMLChar.isNameChar(ch)) {								if (ch == ':') {									length2 = offset - temp_offset - increment;								}								ch = r.getChar();							} else								break;						}						length1 = getPrevOffset() - temp_offset;						// check for uniqueness here						boolean unique = true;						boolean unequal;						for (int i = 0; i < attr_count; i++) {							unequal = false;							int prevLen = (int) attr_name_array[i];							if (length1 == prevLen) {								int prevOffset =									(int) (attr_name_array[i] >> 32);								for (int j = 0; j < prevLen; j++) {									if (XMLDoc[prevOffset + j]										!= XMLDoc[temp_offset + j]) {										unequal = true;										break;									}								}							} else								unequal = true;							unique = unique && unequal;						}						if (!unique && attr_count != 0)							throw new ParseException(								"Error in attr: Attr name not unique"									+ formatLineNumber());						unique = true;						if (attr_count < attr_name_array.length) {							attr_name_array[attr_count] =								((long) (temp_offset) << 32) + length1;							attr_count++;						} else // grow the attr_name_array by 16							{							long[] temp_array = attr_name_array;							/*System.out.println(								"size increase from "									+ temp_array.length									+ "  to "									+ (attr_count + 16));*/							attr_name_array =								new long[attr_count + ATTR_NAME_ARRAY_SIZE];							for (int i = 0; i < attr_count; i++) {								attr_name_array[i] = temp_array[i];							}							attr_name_array[attr_count] =								((long) (temp_offset) << 32) + length1;							attr_count++;						}						// after checking, write VTD						if (is_ns) {							if (encoding < FORMAT_UTF_16BE){								if (length2>MAX_PREFIX_LENGTH										|| length1 > MAX_QNAME_LENGTH)									throw new ParseException(											"Token length overflow error: Attr NS tag prefix or qname length too long"											+formatLineNumber());								writeVTD(									temp_offset,									(length2 << 11) | length1,									TOKEN_ATTR_NS,									depth);							}							else{								if (length2>(MAX_PREFIX_LENGTH << 1)										|| length1 > (MAX_QNAME_LENGTH <<1))									throw new ParseException(											"Token length overflow error: Attr NS prefix or qname length too long"											+ formatLineNumber());								writeVTD(									temp_offset >> 1,									(length2 << 10) | (length1 >> 1),									TOKEN_ATTR_NS,									depth);							}							is_ns = false;						} else {							if (encoding < FORMAT_UTF_16BE){								if (length2>MAX_PREFIX_LENGTH										|| length1 > MAX_QNAME_LENGTH)									throw new ParseException(											"Token Length Error: Attr name prefix or qname length too long"											+ formatLineNumber());								writeVTD(									temp_offset,									(length2 << 11) | length1,									TOKEN_ATTR_NAME,									depth);							}							else{								if (length2>(MAX_PREFIX_LENGTH<<1)										|| length1 > (MAX_QNAME_LENGTH<<1))									throw new ParseException(											"Token Length overflow error: Attr name prefix or qname length too long" 											+ formatLineNumber());								writeVTD(									temp_offset >> 1,									(length2 << 10) | (length1 >> 1),									TOKEN_ATTR_NAME,									depth);							}						}						/*System.out.println(						    " " + temp_offset + " " + length2 + ":" + length1 + " attr name " + depth);*/						length2 = 0;						if (XMLChar.isSpaceChar(ch)) {							ch = getCharAfterS();						}						if (ch != '=')							throw new ParseException(								"Error in attr: invalid char"									+ formatLineNumber());						ch_temp = getCharAfterS();						if (ch_temp != '"' && ch_temp != '\'')							throw new ParseException(								"Error in attr: invalid char (should be ' or \" )"									+ formatLineNumber());						temp_offset = offset;						parser_state = STATE_ATTR_VAL;						break;					case STATE_ATTR_VAL :						while (true) {							ch = r.getChar();							if (XMLChar.isValidChar(ch) && ch != '<') {								if (ch == ch_temp)									break;								if (ch == '&') {									// as in vtd spec, we mark attr val with entities									if (!XMLChar										.isValidChar(entityIdentifier())) {										throw new ParseException(											"Error in attr: Invalid XML char"												+ formatLineNumber());									}								}							} else								throw new ParseException(									"Error in attr: Invalid XML char"										+ formatLineNumber());						}						length1 = offset - temp_offset - increment;						if (encoding < FORMAT_UTF_16BE){							if (length1 > MAX_TOKEN_LENGTH)								  throw new ParseException("Token Length Error:"											  +" Attr val too long (>0xfffff)"											  + formatLineNumber());							writeVTD(								temp_offset,								length1,								TOKEN_ATTR_VAL,								depth);						}						else{							if (length1 > (MAX_TOKEN_LENGTH <<1))								  throw new ParseException("Token Length Error:"											  +" Attr val too long (>0xfffff)"											  + formatLineNumber());							writeVTD(								temp_offset >> 1,								length1 >> 1,								TOKEN_ATTR_VAL,								depth);						}						ch = r.getChar();						if (XMLChar.isSpaceChar(ch)) {							ch = getCharAfterS();							if (XMLChar.isNameStartChar(ch)) {								temp_offset = offset - increment;								parser_state = STATE_ATTR_NAME;								break;							}						}						if (ch == '/') {							depth--;							ch = r.getChar();						}						if (ch == '>') {							attr_count = 0;							if (depth != -1) {								temp_offset = offset;								ch = getCharAfterSe();								if (ch == '<') {									parser_state = STATE_LT_SEEN;								} else if (XMLChar.isContentChar(ch)) {									//temp_offset = offset;									parser_state = STATE_TEXT;								} else if (ch == '&') {									//has_amp = true;									//temp_offset = offset;									entityIdentifier();									parser_state = STATE_TEXT;								} else if (ch == ']') {									if (r.skipChar(']')) {										while (r.skipChar(']')) {										}										if (r.skipChar('>'))											throw new ParseException(												"Error in text content: ]]> in text content"													+ formatLineNumber());									}									parser_state = STATE_TEXT;								}else									throw new ParseException(										"Error in text content: Invalid char"											+ formatLineNumber());							} else {								parser_state = STATE_DOC_END;							}							break;						}						throw new ParseException(							"Starting tag Error: Invalid char in starting tag"								+ formatLineNumber());					case STATE_END_PI :						parser_state = process_end_pi();						break;					case STATE_END_COMMENT :						parser_state = process_end_comment();						break;											default :						throw new ParseException(							"Other error: invalid parser state"								+formatLineNumber());				}			}		} catch (EOFException e) {			if (parser_state != STATE_DOC_END)				throw e;			finishUp();		}	}