diff --git a/README.md b/README.md
index d6fb12871bdda881e5b8186b30e6e2e122a58133..a0d1049cf2b714317075ccf1eaff13c18b77e5e5 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,17 @@ README
 Preambule
 ---------
 
-This GitHub repository contains the sources of 3 libraries implementing [IVOA](http://www.ivoa.net/ "International Virtual Observatory Alliance") standards and protocols:
+This GitHub repository contains the sources of the library-set named VOLLT. It
+contains 3 libraries implementing [IVOA](http://www.ivoa.net/ "International Virtual Observatory Alliance")
+standards and protocols:
+
 * [ADQL](http://www.ivoa.net/documents/latest/ADQL.html "Astronomical Data Query Language")
 * [UWS-1.1](http://www.ivoa.net/documents/UWS/20161024/index.html "Universal Worker Service pattern")
 * [TAP](http://www.ivoa.net/documents/TAP/ "Table Access Protocol")
 
+_**NOTE:** Support of ADQL-2.1 currently under development. For the moment, TAP
+is still using ADQL-2.0 by default._
+
 ### Documentation
 For a complete documentation/tutorial and a demo of the 3 libraries you should visit the following websites: [ADQLTuto](http://cdsportal.u-strasbg.fr/adqltuto), [UWSTuto](http://cdsportal.u-strasbg.fr/uwstuto) and [TAPTuto](http://cdsportal.u-strasbg.fr/taptuto).
 
@@ -40,7 +46,7 @@ Below are summed up the dependencies of each library:
 | Package `cds.utils`    |  X   |     |  X  |
 | Postgres JDBC Driver   |  X   |     |  X  |
 | Package `uws`          |      |  X  |  X  |
-| JSON library            |      |  X  |  X  |
+| JSON library           |      |  X  |  X  |
 | HTTP Servlet API       |      |  X  |  X  |
 | HTTP Multipart Library |      |  X  |  X  |
 | Packages `cds.*`       |      |     |  X  |
diff --git a/buildADQL.xml b/buildADQL.xml
index 0038f7b7365e247c5b8261bba7b9f5c4617cac42..dfba836497cb830e1b4a754c5de2a912b3b77c0e 100644
--- a/buildADQL.xml
+++ b/buildADQL.xml
@@ -2,7 +2,7 @@
 <!DOCTYPE project>
 <project name="adql" basedir="." default="buildLib">
 	
-	<property name="version" value="1.5" />
+	<property name="version" value="2.0" />
 
 	<property name="srcDir" value="src" />
 	<property name="testDir" value="test" />
diff --git a/src/adql/parser/ADQLParser.java b/src/adql/parser/ADQLParser.java
index 0adf1177a9bfd55840e63c09735240b833d92b68..ebfdc31854fa3dc411d17fb94af6e3385ac92d25 100644
--- a/src/adql/parser/ADQLParser.java
+++ b/src/adql/parser/ADQLParser.java
@@ -1,6477 +1,129 @@
-/* Generated By:JavaCC: Do not edit this line. ADQLParser.java */
 package adql.parser;
 
+/*
+ * This file is part of ADQLLibrary.
+ *
+ * ADQLLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ADQLLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ */
+
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Stack;
-import java.util.Vector;
+import java.io.InputStream;
+import java.io.Reader;
 
-import adql.db.exception.UnresolvedIdentifiersException;
-import adql.parser.ADQLQueryFactory.JoinType;
-import adql.parser.IdentifierItems.IdentifierItem;
 import adql.query.ADQLOrder;
 import adql.query.ADQLQuery;
 import adql.query.ClauseADQL;
 import adql.query.ClauseConstraints;
 import adql.query.ClauseSelect;
-import adql.query.SelectAllColumns;
-import adql.query.SelectItem;
-import adql.query.TextPosition;
-import adql.query.constraint.ADQLConstraint;
-import adql.query.constraint.Between;
-import adql.query.constraint.Comparison;
-import adql.query.constraint.ComparisonOperator;
-import adql.query.constraint.ConstraintsGroup;
-import adql.query.constraint.Exists;
-import adql.query.constraint.In;
-import adql.query.constraint.IsNull;
-import adql.query.constraint.NotConstraint;
-import adql.query.from.ADQLJoin;
 import adql.query.from.FromContent;
 import adql.query.operand.ADQLColumn;
 import adql.query.operand.ADQLOperand;
-import adql.query.operand.Concatenation;
-import adql.query.operand.NegativeOperand;
-import adql.query.operand.NumericConstant;
-import adql.query.operand.Operation;
-import adql.query.operand.OperationType;
-import adql.query.operand.StringConstant;
-import adql.query.operand.WrappedOperand;
-import adql.query.operand.function.ADQLFunction;
-import adql.query.operand.function.MathFunction;
-import adql.query.operand.function.MathFunctionType;
-import adql.query.operand.function.SQLFunction;
-import adql.query.operand.function.SQLFunctionType;
-import adql.query.operand.function.UserDefinedFunction;
-import adql.query.operand.function.geometry.GeometryFunction;
-import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;
-import adql.query.operand.function.geometry.PointFunction;
-import adql.translator.PostgreSQLTranslator;
-import adql.translator.TranslationException;
 
 /**
-* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.
-*
-* <p>
-*   This parser is able, thanks to a {@link QueryChecker} object, to check each
-*   {@link ADQLQuery} just after its generation. It could be used to check the
-*   consistency between the ADQL query to parse and the "database" on which the
-*   query must be executed. By default, there is no {@link QueryChecker}. Thus
-*   you must extend {@link QueryChecker} to check semantically all generated
-*   ADQLQuery objects.
-* </p>
-*
-* <p>
-*   To create an object representation of the given ADQL query, this parser uses
-*   a {@link ADQLQueryFactory} object. So if you want customize some object
-*   (ie. CONTAINS) of this representation you just have to extend the
-*   corresponding default object (ie. ContainsFunction) and to extend the
-*   corresponding function of {@link ADQLQueryFactory}
-*   (ie. createContains(...)).
-* </p>
-*
-* <p>Here are the key functions to use:</p>
-* <ul>
-* 	<li>{@link #parseQuery(java.lang.String)} (or any of its alternatives)
-* 		to parse an input ADQL query String and get its corresponding ADQL tree
-*   </li>
-*   <li>{@link #tryQuickFix(java.lang.String)} to try fixing the most common
-* 		issues with ADQL queries (e.g. Unicode confusable characters,
-* 		unescaped ADQL identifiers, SQL reserved keywords, ...)</li>
-* </ul>
-*
-* <p><b><u>WARNING:</u>
-*   To modify this class it's strongly encouraged to modify the .jj file in the
-*   section between <i>PARSER_BEGIN</i> and <i>PARSER_END</i> and to re-compile
-*   it with JavaCC.
-* </b></p>
-*
-* @see QueryChecker
-* @see ADQLQueryFactory
-*
-* @author Gr&eacute;gory Mantelet (CDS;ARI)
-* @version 1.5 (03/2019)
-*/
-public class ADQLParser implements ADQLParserConstants {
-
-	/** Tools to build the object representation of the ADQL query. */
-	private ADQLQueryFactory queryFactory = new ADQLQueryFactory();
-
-	/** The stack of queries (because there may be some sub-queries). */
-	private Stack<ADQLQuery> stackQuery = new Stack<ADQLQuery>();
-
-	/** The object representation of the ADQL query to parse.
-	* (ONLY USED DURING THE PARSING, else it is always <i>null</i>). */
-	private ADQLQuery query = null;
-
-	/** Checks each {@link ADQLQuery} (sub-query or not) just after their
-	* generation. */
-	private QueryChecker queryChecker = null;
-
-	/** The first token of a table/column name. This token is extracted by
-	* {@link #Identifier()}. */
-	private Token currentIdentifierToken = null;
-
-	/**
-	* Builds an ADQL parser without a query to parse.
-	*/
-	public ADQLParser(){
-		this(new java.io.ByteArrayInputStream("".getBytes()));
-		setDebug(false);
-	}
-
-	/**
-	* Builds an ADQL parser without a query to parse but with a
-	* {@link QueryChecker} and a {@link ADQLQueryFactory}.
-	*
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	* @param factory	The object to use to build an object representation of
-	*               	the given ADQL query.
-	*/
-	public ADQLParser(QueryChecker checker, ADQLQueryFactory factory){
-		this();
-
-		queryChecker = checker;
-
-		if (factory != null)
-			queryFactory = factory;
-	}
-
-	/**
-	* Builds an ADQL parser without a query to parse but with a
-	* {@link QueryChecker}.
-	*
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	*/
-	public ADQLParser(QueryChecker checker){
-		this(checker, null);
-	}
-
-	/**
-	* Builds an ADQL parser without a query to parse but with a
-	* {@link ADQLQueryFactory}.
-	*
-	* @param factory	The object to use to build an object representation of
-	*               	the given ADQL query.
-	*/
-	public ADQLParser(ADQLQueryFactory factory){
-		this((QueryChecker)null, factory);
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	* @param factory	The object to use to build an object representation of
-	*               	the given ADQL query.
-	*/
-	public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory){
-		this(stream);
-		setDebug(false);
-
-		setDebug(false);
-
-		queryChecker = checker;
-
-		if (factory != null)
-			queryFactory = factory;
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	*/
-	public ADQLParser(java.io.InputStream stream, QueryChecker checker){
-		this(stream, checker, null);
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param factory	The object to use to build an object representation of
-	*               	the given ADQL query.
-	*/
-	public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory){
-		this(stream, (QueryChecker)null, factory);
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param encoding	The supplied encoding.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	* @param factory	The object to use to build an object representation
-	*               	of the given ADQL query.
-	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory){
-		this(stream, encoding);
-		setDebug(false);
-
-		queryChecker = checker;
-
-		if (factory != null)
-			queryFactory = factory;
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param encoding	The supplied encoding.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker){
-		this(stream, encoding, checker, null);
-	}
-
-	/**
-	* Builds a parser with a stream containing the query to parse.
-	*
-	* @param stream		The stream in which the ADQL query to parse is given.
-	* @param encoding	The supplied encoding.
-	* @param factory	The object to use to build an object representation
-	*               	of the given ADQL query.
-	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory){
-		this(stream, encoding, null, factory);
-	}
-
-	/**
-	* Builds a parser with a reader containing the query to parse.
-	*
-	* @param reader		The reader in which the ADQL query to parse is given.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	* @param factory	The object to use to build an object representation
-	*               	of the given ADQL query.
-	*/
-	public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory){
-		this(reader);
-		setDebug(false);
-
-		setDebug(false);
-
-		queryChecker = checker;
-
-		if (factory != null)
-			queryFactory = factory;
-	}
-
-	/**
-	* Builds a parser with a reader containing the query to parse.
-	*
-	* @param reader		The reader in which the ADQL query to parse is given.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	*/
-	public ADQLParser(java.io.Reader reader, QueryChecker checker){
-		this(reader, checker, null);
-	}
-
-	/**
-	* Builds a parser with a reader containing the query to parse.
-	*
-	* @param reader		The reader in which the ADQL query to parse is given.
-	* @param factory	The object to use to build an object representation
-	*               	of the given ADQL query.
-	*/
-	public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory){
-		this(reader, null, factory);
-	}
-
-	/**
-	* Builds a parser with another token manager.
-	*
-	* @param tm			The manager which associates a token to a numeric code.
-	* @param checker	The object to use to check each {@link ADQLQuery }.
-	* @param factory	The object to use to build an object representation
-	*               	of the given ADQL query.
-	*/
-	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory){
-		this(tm);
-		setDebug(false);
-
-		setDebug(false);
-
-		queryChecker = checker;
+ * TODO
+ *
+ * @author Gr&eacute;gory Mantelet (CDS)
+ * @version 2.0 (04/2019)
+ * @since 2.0
+ */
+public interface ADQLParser {
 
-		if (factory != null)
-			queryFactory = factory;
-	}
+	/* **********************************************************************
+	 *                           GETTERS & SETTERS
+	 * ********************************************************************** */
 
-	/**
-	* Builds a parser with another token manager.
-	*
-	* @param tm			The manager which associates a token to a numeric code.
-	* @param checker	The object to use to check each {@link ADQLQuery}.
-	*/
-	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker){
-		this(tm, checker, null);
-	}
-
-	/**
-	* Builds a parser with another token manager.
-	*
-	* @param tm			The manager which associates a token to a numeric code.
-	* @param factory	The object to use to build an object representation of
-	*               	the given ADQL query.
-	*/
-	public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory){
-		this(tm, null, factory);
-	}
-
-	/* ADDITIONAL GETTERS & SETTERS */
-
-	public final void setDebug(boolean debug){
-		if (debug)
-			enable_tracing();
-		else
-			disable_tracing();
-	}
-
-	public final QueryChecker getQueryChecker(){
-		return queryChecker;
-	}
-
-	public final void setQueryChecker(QueryChecker checker){
-		queryChecker = checker;
-	}
-
-	public final ADQLQueryFactory getQueryFactory(){
-		return queryFactory;
-	}
-
-	public final void setQueryFactory(ADQLQueryFactory factory){
-		queryFactory = (factory != null) ? factory : (new ADQLQueryFactory());
-	}
-
-	/* EXCEPTION HELPER FUNCTION */
-
-	private final ParseException generateParseException(Exception ex){
-		if (!(ex instanceof ParseException)){
-			ParseException pex = new ParseException("[" + ex.getClass().getName() + "] " + ex.getMessage());
-			pex.setStackTrace(ex.getStackTrace());
-			return pex;
-		}else
-			return (ParseException)ex;
-	}
-
-	/* QUERY PARSING FUNCTIONS */
-
-	/**
-	* Tell whether the given string is a valid ADQL regular identifier.
-	*
-	* <p>
-	* 	According to the ADQL-2.0's BNF, a regular identifier (i.e. not delimited
-	* 	; not between double quotes) must be a letter followed by a letter, digit
-	* 	or underscore. So, the following regular expression:
-	* </p>
-	* <pre>[a-zA-Z]+[a-zA-Z0-9_]*</pre>
-	*
-	* <p>This is what this function tests on the given string.</p>
-	*
-	* @param idCandidate	The string to test.
-	*
-	* @return	<code>true</code> if the given string is a valid regular
-	*        	identifier,
-	*        	<code>false</code> otherwise.
-	*
-	* @see #testRegularIdentifier(adql.parser.Token)
-	*
-	* @since 1.5
-	*/
-	public final boolean isRegularIdentifier(final String idCandidate){
-		return idCandidate.matches("[a-zA-Z]+[a-zA-Z0-9_]*");
-	}
-
-	/**
-	* Test the given token as an ADQL's regular identifier.
-	*
-	* <p>
-	* 	This function uses {@link #isRegularIdentifier(java.lang.String)} to
-	* 	test the given token's image. If the test fails, a
-	* 	{@link adql.parser.ParseException} is thrown.
-	* </p>
-	*
-	* @param token	The token to test.
-	*
-	* @throws ParseException	If the given token is not a valid ADQL regular
-	*                       	identifier.
-	*
-	* @see #isRegularIdentifier(java.lang.String)
-	*
-	* @since 1.5
-	*/
-	public final void testRegularIdentifier(final Token token) throws ParseException{
-		if (!isRegularIdentifier(token.image))
-			throw new ParseException("Invalid ADQL regular identifier: \u005c"" + token.image + "\u005c"! If it aims to be a column/table name/alias, you should write it between double quotes.", new TextPosition(token));
-	}
-
-	/**
-	* Parses the query given at the creation of this parser or in the
-	* <i>ReInit</i> functions.
-	*
-	* @return 	The object representation of the given ADQL query.
-	*
-	* @throws ParseException	If there is at least one syntactic error.
-	*
-	* @see ADQLParser#Query()
-	*/
-	public final ADQLQuery parseQuery() throws ParseException{
-		stackQuery.clear();
-		query = null;
-		try{
-			return Query();
-		}catch(TokenMgrError tme){
-			throw new ParseException(tme);
-		}
-	}
-
-	/**
-	* Parses the query given in parameter.
-	*
-	* @param q	The ADQL query to parse.
-	*
-	* @return	The object representation of the given ADQL query.
-	*
-	* @throws ParseException	If there is at least one syntactic error.
-	*
-	* @see ADQLParser#ReInit(java.io.InputStream)
-	* @see ADQLParser#setDebug(boolean)
-	* @see ADQLParser#Query()
-	*/
-	public final ADQLQuery parseQuery(String q) throws ParseException{
-		stackQuery.clear();
-		query = null;
-		ReInit(new java.io.ByteArrayInputStream(q.getBytes()));
-		try{
-			return Query();
-		}catch(TokenMgrError tme){
-			throw new ParseException(tme);
-		}
-	}
-
-	/**
-	* Parses the query contained in the stream given in parameter.
-	*
-	* @param stream		The stream which contains the ADQL query to parse.
-	*
-	* @return	The object representation of the given ADQL query.
-	*
-	* @throws ParseException	If there is at least one syntactic error.
-	*
-	* @see ADQLParser#ReInit(java.io.InputStream)
-	* @see ADQLParser#setDebug(boolean)
-	* @see ADQLParser#Query()
-	*/
-	public final ADQLQuery parseQuery(java.io.InputStream stream) throws ParseException{
-		stackQuery.clear();
-		query = null;
-		ReInit(stream);
-		try{
-			return Query();
-		}catch(TokenMgrError tme){
-			throw new ParseException(tme);
-		}
-	}
-
-	/* CORRECTION SUGGESTION */
+	public QueryChecker getQueryChecker();
 
-	/**
-	* Try fixing tokens/terms of the input ADQL query.
-	*
-	* <p>
-	* 	<b>This function does not try to fix syntactical or semantical errors.</b>
-	*  It just try to fix the most common issues in ADQL queries, such as:
-	* </p>
-	* <ul>
-	* 	<li>some Unicode characters confusable with ASCII characters (like a
-	* 		space, a dash, ...) ; this function replace them by their ASCII
-	* 		alternative,</li>
-	* 	<li>any of the following are double quoted:
-	* 		<ul>
-	* 			<li>non regular ADQL identifiers
-	* 				(e.g. <code>_RAJ2000</code>),</li>
-	* 			<li>ADQL function names used as identifiers
-	* 				(e.g. <code>distance</code>)</li>
-	* 			<li>and SQL reserved keywords
-	* 				(e.g. <code>public</code>).</li>
-	* 		</ul>
-	* 	</li>
-	* </ul>
-	*
-	* <p><i><b>Note 1:</b>
-	* 	The given stream is NOT closed by this function even if the EOF is
-	* 	reached. It is the responsibility of the caller to close it.
-	* </i></p>
-	*
-	* <p><i><b>Note 2:</b>
-	* 	This function does not use any instance variable of this parser
-	* 	(especially the InputStream or Reader provided at initialisation or
-	* 	ReInit).
-	* </i></p>
-	*
-	* @param input	Stream containing the input ADQL query to fix.
-	*
-	* @return	The suggested correction of the input ADQL query.
-	*
-	* @throws java.io.IOException	If there is any error while reading from the
-	*                            	given input stream.
-	* @throws ParseException	If any unrecognised character is encountered,
-	*                       	or if anything else prevented the tokenization
-	*                       	   of some characters/words/terms.
-	*
-	* @see #tryQuickFix(java.lang.String)
-	*
-	* @since 1.5
-	*/
-	public final String tryQuickFix(final java.io.InputStream input) throws java.io.IOException, ParseException{
-		// Fetch everything into a single string:
-		StringBuffer buf = new StringBuffer();
-		byte[] cBuf = new byte[1024];
-		int nbChar;
-		while((nbChar = input.read(cBuf)) > -1){
-			buf.append(new String(cBuf, 0, nbChar));
-		}
-
-		// Convert the buffer into a String and now try to fix it:
-		return tryQuickFix(buf.toString());
-	}
-
-	/**
-	* Try fixing tokens/terms of the given ADQL query.
-	*
-	* <p>
-	* 	<b>This function does not try to fix syntactical or semantical errors.</b>
-	*  It just try to fix the most common issues in ADQL queries, such as:
-	* </p>
-	* <ul>
-	* 	<li>some Unicode characters confusable with ASCII characters (like a
-	* 		space, a dash, ...) ; this function replace them by their ASCII
-	* 		alternative,</li>
-	* 	<li>any of the following are double quoted:
-	* 		<ul>
-	* 			<li>non regular ADQL identifiers
-	* 				(e.g. <code>_RAJ2000</code>),</li>
-	* 			<li>ADQL function names used as identifiers
-	* 				(e.g. <code>distance</code>)</li>
-	* 			<li>and SQL reserved keywords
-	* 				(e.g. <code>public</code>).</li>
-	* 		</ul>
-	* 	</li>
-	* </ul>
-	*
-	* <p><i><b>Note:</b>
-	* 	This function does not use any instance variable of this parser
-	* 	(especially the InputStream or Reader provided at initialisation or
-	* 	ReInit).
-	* </i></p>
-	*
-	* @param adqlQuery	The input ADQL query to fix.
-	*
-	* @return	The suggested correction of the given ADQL query.
-	*
-	* @throws ParseException	If any unrecognised character is encountered,
-	*                       	or if anything else prevented the tokenization
-	*                       	   of some characters/words/terms.
-	*
-	* @since 1.5
-	*/
-	public String tryQuickFix(String adqlQuery) throws ParseException{
-		StringBuffer suggestedQuery = new StringBuffer();
+	public void setQueryChecker(final QueryChecker checker);
 
-		// 1. Replace all Unicode confusable characters:
-		adqlQuery = replaceUnicodeConfusables(adqlQuery);
+	public ADQLQueryFactory getQueryFactory();
 
-		/* 1.bis. Normalise new lines and tabulations
-		*        (to simplify the column counting): */
-		adqlQuery = adqlQuery.replaceAll("(\u005cr\u005cn|\u005cr|\u005cn)", System.getProperty("line.separator")).replaceAll("\u005ct", "    ");
+	public void setQueryFactory(final ADQLQueryFactory factory);
 
-		// 2. Analyse the query token by token:
-		ADQLParserTokenManager parser = new ADQLParserTokenManager(new SimpleCharStream(new java.io.ByteArrayInputStream(adqlQuery.getBytes())));
+	/* **********************************************************************
+	 *                         PARSING DEBUG FUNCTIONS
+	 * ********************************************************************** */
 
-		final String[] lines = adqlQuery.split(System.getProperty("line.separator"));
+	public void setDebug(final boolean debug);
 
-		try{
-			String suggestedToken;
-			int lastLine = 1, lastCol = 1;
+	/* **********************************************************************
+	 *                           PARSING FUNCTIONS
+	 * ********************************************************************** */
 
-			Token token = null, nextToken = parser.getNextToken();
-			// for all tokens until the EOF or EOQ:
-			do{
-				// get the next token:
-				token = nextToken;
-				nextToken = (isEnd(token) ? null : parser.getNextToken());
+	public void ReInit(InputStream stream);
 
-				// 3. Double quote any suspect token:
-				if (mustEscape(token, nextToken)){
-					suggestedToken = "\u005c"" + token.image + "\u005c"";
-				}else
-					suggestedToken = token.image;
+	public void ReInit(Reader reader);
 
-				/* 4. Append all space characters (and comments) before the
-				*    token: */
-				/* same line, just get the space characters between the last
-				* token and the one to append: */
-				if (lastLine == token.beginLine){
-					suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1, token.beginColumn - (isEnd(token) ? 0 : 1)));
-					lastCol = token.endColumn + 1;
-				}
-				// not the same line...
-				else{
-					/* append all remaining space characters until the position
-					* of the token to append: */
-					do{
-						suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1)).append('\u005cn');
-						lastLine++;
-						lastCol = 1;
-					}while(lastLine < token.beginLine);
-					/* if there are still space characters before the token,
-					* append them as well: */
-					if (lastCol < token.beginColumn)
-						suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1, token.beginColumn - 1));
-					// finally, set the correct column position:
-					lastCol = token.endColumn + 1;
-				}
+	public ADQLQuery parseQuery() throws ParseException;
 
-				// 5. Append the suggested token:
-				suggestedQuery.append(suggestedToken);
+	public ADQLQuery parseQuery(final String query) throws ParseException;
 
-			}while(!isEnd(token));
+	public ADQLQuery parseQuery(final InputStream stream) throws ParseException;
 
-		}catch(TokenMgrError err){
-			// wrap such errors and propagate them:
-			throw new ParseException(err);
-		}
+	public ClauseSelect parseSelect(final String adql) throws ParseException;
 
-		return suggestedQuery.toString();
-	}
+	public FromContent parseFrom(final String adql) throws ParseException;
 
-	/**
-	* All of the most common Unicode confusable characters and their
-	* ASCII/UTF-8 alternative.
-	*
-	* <p>
-	* 	Keys of this map represent the ASCII character while the values are the
-	* 	regular expression for all possible Unicode alternatives.
-	* </p>
-	*
-	* <p><i><b>Note:</b>
-	* 	All of them have been listed using
-	* 	<a href="https://unicode.org/cldr/utility/confusables.jsp">Unicode Utilities: Confusables</a>.
-	* </i></p>
-	*
-	* @since 1.5
-	*/
-	protected final static java.util.Map<String, String> REGEX_UNICODE_CONFUSABLES = new java.util.HashMap<String, String>(10);
-	/** Regular expression matching all Unicode alternatives for <code>-</code>.
-	* @since 1.5 */
-	protected final static String REGEX_DASH = "[-\u02d7\u06d4\u2010\u2011\u2012\u2013\u2043\u2212\u2796\u2cba\ufe58\u2014\u2015\u207b\u208b\u0096\u058a\ufe63\uff0d]";
-	/** Regular expression matching all Unicode alternatives for <code>_</code>.
-	* @since 1.5 */
-	protected final static String REGEX_UNDERSCORE = "[_\u07fa\ufe4d\ufe4e\ufe4f]";
-	/** Regular expression matching all Unicode alternatives for <code>'</code>.
-	* @since 1.5 */
-	protected final static String REGEX_QUOTE = "['`\u00b4\u02b9\u02bb\u02bc\u02bd\u02be\u02c8\u02ca\u02cb\u02f4\u0374\u0384\u055a\u055d\u05d9\u05f3\u07f4\u07f5\u144a\u16cc\u1fbd\u1fbf\u1fef\u1ffd\u1ffe\u2018\u2019\u201b\u2032\u2035\ua78c\uff07\uff40]";
-	/** Regular expression matching all Unicode alternatives for <code>"</code>.
-	* @since 1.5 */
-	protected final static String REGEX_DOUBLE_QUOTE = "[\u02ba\u02dd\u02ee\u02f6\u05f2\u05f4\u1cd3\u201c\u201d\u201f\u2033\u2036\u3003\uff02]";
-	/** Regular expression matching all Unicode alternatives for <code>.</code>.
-	* @since 1.5 */
-	protected final static String REGEX_STOP = "[.\u0660\u06f0\u0701\u0702\u2024\ua4f8\ua60e]";
-	/** Regular expression matching all Unicode alternatives for <code>+</code>.
-	* @since 1.5 */
-	protected final static String REGEX_PLUS = "[+\u16ed\u2795]";
-	/** Regular expression matching all Unicode alternatives for <code> </code>.
-	* @since 1.5 */
-	protected final static String REGEX_SPACE = "[ \u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f]";
-	/** Regular expression matching all Unicode alternatives for <code>&lt;</code>.
-	* @since 1.5 */
-	protected final static String REGEX_LESS_THAN = "[<\u02c2\u1438\u16b2\u2039\u276e]";
-	/** Regular expression matching all Unicode alternatives for <code>&gt;</code>.
-	* @since 1.5 */
-	protected final static String REGEX_GREATER_THAN = "[>\u02c3\u1433\u203a\u276f]";
-	/** Regular expression matching all Unicode alternatives for <code>=</code>.
-	* @since 1.5 */
-	protected final static String REGEX_EQUAL = "[=\u1400\u2e40\u30a0\ua4ff]";
-	static{
-		REGEX_UNICODE_CONFUSABLES.put("-", REGEX_DASH);
-		REGEX_UNICODE_CONFUSABLES.put("_", REGEX_UNDERSCORE);
-		REGEX_UNICODE_CONFUSABLES.put("'", REGEX_QUOTE);
-		REGEX_UNICODE_CONFUSABLES.put("\u005c"", REGEX_DOUBLE_QUOTE);
-		REGEX_UNICODE_CONFUSABLES.put(".", REGEX_STOP);
-		REGEX_UNICODE_CONFUSABLES.put("+", REGEX_PLUS);
-		REGEX_UNICODE_CONFUSABLES.put(" ", REGEX_SPACE);
-		REGEX_UNICODE_CONFUSABLES.put("<", REGEX_LESS_THAN);
-		REGEX_UNICODE_CONFUSABLES.put(">", REGEX_GREATER_THAN);
-		REGEX_UNICODE_CONFUSABLES.put("=", REGEX_EQUAL);
-	}
+	public ClauseConstraints parseWhere(final String adql) throws ParseException;
 
-	/**
-	* Replace all Unicode characters that can be confused with other ASCI/UTF-8
-	* characters (e.g. different spaces, dashes, ...) in their ASCII version.
-	*
-	* @param adqlQuery	The ADQL query string in which Unicode confusable
-	*                 	characters must be replaced.
-	*
-	* @return	The same query without the most common Unicode confusable
-	*        	characters.
-	*
-	* @since 1.5
-	*/
-	protected String replaceUnicodeConfusables(final String adqlQuery){
-		String newAdqlQuery = adqlQuery;
-		for(java.util.Map.Entry<String, String> confusable : REGEX_UNICODE_CONFUSABLES.entrySet())
-			newAdqlQuery = newAdqlQuery.replaceAll(confusable.getValue(), confusable.getKey());
-		return newAdqlQuery;
-	}
+	public ClauseADQL<ADQLOrder> parseOrderBy(final String adql) throws ParseException;
 
-	/**
-	* Tell whether the given token represents the end of an ADQL query.
-	*
-	* @param token	Token to analyze.
-	*
-	* @return	<code>true</code> if the given token represents a query end,
-	*        	<code>false</code> otherwise.
-	*
-	* @since 1.5
-	*/
-	protected boolean isEnd(final Token token){
-		return token.kind == ADQLParserConstants.EOF || token.kind == ADQLParserConstants.EOQ;
-	}
+	public ClauseADQL<ADQLColumn> parseGroupBy(final String adql) throws ParseException;
 
-	/**
-	* Tell whether the given token must be double quoted.
-	*
-	* <p>
-	* 	This function considers all the following as terms to double quote:
-	* </p>
-	* <ul>
-	* 	<li>SQL reserved keywords</li>,
-	* 	<li>unrecognised regular identifiers (e.g. neither a delimited nor a
-	* 		valid ADQL regular identifier)</li>
-	* 	<li>and ADQL function name without a parameters list.</li>
-	* </ul>
-	*
-	* @param token		The token to analyze.
-	* @param nextToken	The following token. (useful to detect the start of a
-	*                 	function's parameters list)
-	*
-	* @return	<code>true</code> if the given token must be double quoted,
-	*        	<code>false</code> to keep it as provided.
-	*
-	* @since 1.5
-	*/
-	protected boolean mustEscape(final Token token, final Token nextToken){
-		switch(token.kind){
-			case ADQLParserConstants.SQL_RESERVED_WORD:
-				return true;
-			case ADQLParserConstants.REGULAR_IDENTIFIER_CANDIDATE:
-				return !isRegularIdentifier(token.image);
-			default:
-				return isFunctionName(token) && (nextToken == null || nextToken.kind != ADQLParserConstants.LEFT_PAR);
-		}
-	}
+	/* **********************************************************************
+	 *                           AUTO-FIX FUNCTIONS
+	 * ********************************************************************** */
 
-	/**
-	* Tell whether the given token matches to an ADQL function name.
-	*
-	* @param token	The token to analyze.
-	*
-	* @return	<code>true</code> if the given token is an ADQL function name,
-	*        	<code>false</code> otherwise.
-	*
-	* @since 1.5
-	*/
-	protected boolean isFunctionName(final Token token){
-		switch(token.kind){
-			case ADQLParserConstants.COUNT:
-			case ADQLParserConstants.EXISTS:
-			case ADQLParserConstants.AVG:
-			case ADQLParserConstants.MAX:
-			case ADQLParserConstants.MIN:
-			case ADQLParserConstants.SUM:
-			case ADQLParserConstants.BOX:
-			case ADQLParserConstants.CENTROID:
-			case ADQLParserConstants.CIRCLE:
-			case ADQLParserConstants.POINT:
-			case ADQLParserConstants.POLYGON:
-			case ADQLParserConstants.REGION:
-			case ADQLParserConstants.CONTAINS:
-			case ADQLParserConstants.INTERSECTS:
-			case ADQLParserConstants.AREA:
-			case ADQLParserConstants.COORD1:
-			case ADQLParserConstants.COORD2:
-			case ADQLParserConstants.COORDSYS:
-			case ADQLParserConstants.DISTANCE:
-			case ADQLParserConstants.ABS:
-			case ADQLParserConstants.CEILING:
-			case ADQLParserConstants.DEGREES:
-			case ADQLParserConstants.EXP:
-			case ADQLParserConstants.FLOOR:
-			case ADQLParserConstants.LOG:
-			case ADQLParserConstants.LOG10:
-			case ADQLParserConstants.MOD:
-			case ADQLParserConstants.PI:
-			case ADQLParserConstants.POWER:
-			case ADQLParserConstants.RADIANS:
-			case ADQLParserConstants.RAND:
-			case ADQLParserConstants.ROUND:
-			case ADQLParserConstants.SQRT:
-			case ADQLParserConstants.TRUNCATE:
-			case ADQLParserConstants.ACOS:
-			case ADQLParserConstants.ASIN:
-			case ADQLParserConstants.ATAN:
-			case ADQLParserConstants.ATAN2:
-			case ADQLParserConstants.COS:
-			case ADQLParserConstants.COT:
-			case ADQLParserConstants.SIN:
-			case ADQLParserConstants.TAN:
-			case ADQLParserConstants.USING:
-				return true;
-			default:
-				return false;
-		}
-	}
+	public String tryQuickFix(final InputStream input) throws IOException, ParseException;
 
-	/* MAIN PROGRAM */
+	public String tryQuickFix(final String adqlQuery) throws ParseException;
 
 	/**
-	* Gets the specified ADQL query and parses the given ADQL query. The SQL
-	* translation is then printed if the syntax is correct.
-	*
-	* <p>
-	*     <b>ONLY the syntax is checked: the query is NOT EXECUTED !</b>
-	* </p>
-	*
-	* @param args
-
-	* @throws Exception
-	*/
-	public static final void main(String[] args) throws Exception{
-		final String USAGE = "Usage:\u005cn    adqlParser.jar [-d] [-v] [-e] [-a|-s] [-f] [<FILE>|<URL>]\u005cn\u005cnNOTE: If no file or URL is given, the ADQL query is expected in the standard\u005cn      input. This query must end with a ';' or <Ctrl+D>!\u005cn\u005cnParameters:\u005cn    -v or --verbose : Print the main steps of the parsing\u005cn    -d or --debug   : Print stack traces when a grave error occurs\u005cn    -e or --explain : Explain the ADQL parsing (or Expand the parsing tree)\u005cn    -a or --adql    : Display the understood ADQL query\u005cn    -s or --sql     : Ask the SQL translation of the given ADQL query\u005cn                      (SQL compatible with PostgreSQL)\u005cn    -f or --try-fix : Try fixing the most common ADQL query issues before\u005cn                      attempting to parse the query.\u005cn\u005cnReturn:\u005cn    By default: nothing if the query is correct. Otherwise a message explaining\u005cn                why the query is not correct is displayed.\u005cn    With the -s option, the SQL translation of the given ADQL query will be\u005cn    returned.\u005cn    With the -a option, the ADQL query is returned as it has been understood.\u005cn\u005cnExit status:\u005cn    0  OK !\u005cn    1  Parameter error (missing or incorrect parameter)\u005cn    2  File error (incorrect file/url, reading error, ...)\u005cn    3  Parsing error (syntactic or semantic error)\u005cn    4  Translation error (a problem has occurred during the translation of the\u005cn       given ADQL query in SQL).";
-
-		ADQLParser parser;
-
-		final String urlRegex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
-
-		String file = null, metaFile = null;
-		short mode = -1;
-		boolean verbose = false, debug = false, explain = false, tryFix = false;
-
-		// Parameters reading:
-		for(int i = 0; i < args.length; i++){
-			if (args[i].equalsIgnoreCase("-d") || args[i].equalsIgnoreCase("--debug"))
-				debug = true;
-			else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("--verbose"))
-				verbose = true;
-			else if (args[i].equalsIgnoreCase("-e") || args[i].equalsIgnoreCase("--explain"))
-				explain = true;
-			else if (args[i].equalsIgnoreCase("-a") || args[i].equalsIgnoreCase("--adql")){
-				if (mode != -1){
-					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\u005cn" + USAGE);
-					System.exit(1);
-				}else
-					mode = 1;
-			}else if (args[i].equalsIgnoreCase("-s") || args[i].equalsIgnoreCase("--sql")){
-				if (mode != -1){
-					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\u005cn" + USAGE);
-					System.exit(1);
-				}else
-					mode = 2;
-			}else if (args[i].equalsIgnoreCase("-f") || args[i].equalsIgnoreCase("--try-fix"))
-				tryFix = true;
-			else if (args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")){
-				System.out.println(USAGE);
-				System.exit(0);
-			}else if (args[i].startsWith("-")){
-				System.err.println("((!)) Unknown parameter: \u005c"" + args[i] + "\u005c" ((!))\u005cn" + USAGE);
-				System.exit(1);
-			}else
-				file = args[i].trim();
-		}
-
-		try{
-
-			// Try fixing the query, if asked:
-			if (tryFix){
-				if (verbose)
-					System.out.println("((i)) Trying to automatically fix the query...");
-
-				String query;
-				java.io.InputStream in = null;
-				try{
-					// get the input stream...
-					if (file == null || file.length() == 0)
-						in = System.in;
-					else if (file.matches(urlRegex))
-						in = (new java.net.URL(file)).openStream();
-					else
-						in = new java.io.FileInputStream(file);
-
-					// ...and try fixing the query:
-					query = (new ADQLParser()).tryQuickFix(in);
-				}finally{
-					// close the stream (if opened):
-					if (in != null)
-						in.close();
-					in = null;
-				}
-
-				if (verbose)
-					System.out.println("((i)) SUGGESTED QUERY:\u005cn" + query);
-
-				// Initialise the parser with this fixed query:
-				parser = new ADQLParser(new java.io.ByteArrayInputStream(query.getBytes()));
-			}
-			// Otherwise, take the query as provided:
-			else{
-				// Initialise the parser with the specified input:
-				if (file == null || file.length() == 0)
-					parser = new ADQLParser(System.in);
-				else if (file.matches(urlRegex))
-					parser = new ADQLParser((new java.net.URL(file)).openStream());
-				else
-					parser = new ADQLParser(new java.io.FileInputStream(file));
-			}
-
-			// Enable/Disable the debugging in function of the parameters:
-			parser.setDebug(explain);
-
-			// Query parsing:
-			try{
-				if (verbose)
-					System.out.print("((i)) Parsing ADQL query...");
-				ADQLQuery q = parser.parseQuery();
-				if (verbose)
-					System.out.println("((i)) CORRECT ADQL QUERY ((i))");
-				if (mode == 2){
-					PostgreSQLTranslator translator = new PostgreSQLTranslator();
-					if (verbose)
-						System.out.print("((i)) Translating in SQL...");
-					String sql = translator.translate(q);
-					if (verbose)
-						System.out.println("ok");
-					System.out.println(sql);
-				}else if (mode == 1){
-					System.out.println(q.toADQL());
-				}
-			}catch(UnresolvedIdentifiersException uie){
-				System.err.println("((X)) " + uie.getNbErrors() + " unresolved identifiers:");
-				for(ParseException pe : uie)
-					System.err.println("\u005ct - at " + pe.getPosition() + ": " + uie.getMessage());
-				if (debug)
-					uie.printStackTrace(System.err);
-				System.exit(3);
-			}catch(ParseException pe){
-				System.err.println("((X)) Syntax error: " + pe.getMessage() + " ((X))");
-				if (debug)
-					pe.printStackTrace(System.err);
-				System.exit(3);
-			}catch(TranslationException te){
-				if (verbose)
-					System.out.println("error");
-				System.err.println("((X)) Translation error: " + te.getMessage() + " ((X))");
-				if (debug)
-					te.printStackTrace(System.err);
-				System.exit(4);
-			}
-
-		}catch(IOException ioe){
-			System.err.println("\u005cn((X)) Error while reading the file \u005c"" + file + "\u005c": " + ioe.getMessage() + " ((X))");
-			if (debug)
-				ioe.printStackTrace(System.err);
-			System.exit(2);
-		}
-
-	}
-
-	/* ########## */
-	/* # SYNTAX # */
-	/* ########## */
-
-	/* ******************* */
-	/* GENERAL ADQL SYNTAX */
-	/* ******************* */
-	/**
-	* Parses the ADQL query given at the parser creation or in the {@link ADQLParser#ReInit(java.io.InputStream)}
-	* or in the <i>parseQuery</i> functions.
-	*
-	* @return					The object representation of the query.
-	* @throws ParseException	If the query syntax is incorrect.
-	*/
-	final public ADQLQuery Query() throws ParseException{
-		trace_call("Query");
-		try{
-			ADQLQuery q = null;
-			q = QueryExpression();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case 0:
-					jj_consume_token(0);
-					break;
-				case EOQ:
-					jj_consume_token(EOQ);
-					break;
-				default:
-					jj_la1[0] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			// check the query:
-			if (queryChecker != null)
-				queryChecker.check(q);
-
-			{
-				if (true)
-					return q;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Query");
-		}
-	}
-
-	final public ADQLQuery QueryExpression() throws ParseException{
-		trace_call("QueryExpression");
-		try{
-			TextPosition endPos = null;
-			try{
-				// create the query:
-				query = queryFactory.createQuery();
-				stackQuery.push(query);
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			Select();
-			From();
-			endPos = query.getFrom().getPosition();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case WHERE:
-					Where();
-					endPos = query.getWhere().getPosition();
-					break;
-				default:
-					jj_la1[1] = jj_gen;
-					;
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case GROUP:
-					GroupBy();
-					endPos = query.getGroupBy().getPosition();
-					break;
-				default:
-					jj_la1[2] = jj_gen;
-					;
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case HAVING:
-					Having();
-					endPos = query.getHaving().getPosition();
-					break;
-				default:
-					jj_la1[3] = jj_gen;
-					;
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ORDER:
-					OrderBy();
-					endPos = query.getOrderBy().getPosition();
-					break;
-				default:
-					jj_la1[4] = jj_gen;
-					;
-			}
-			// set the position of the query:
-			query.setPosition(new TextPosition(query.getSelect().getPosition(), endPos));
-
-			// get the previous query (!= null if the current query is a sub-query):
-			ADQLQuery previousQuery = stackQuery.pop();
-			if (stackQuery.isEmpty())
-				query = null;
-			else
-				query = stackQuery.peek();
-
-			{
-				if (true)
-					return previousQuery;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("QueryExpression");
-		}
-	}
-
-	final public ADQLQuery SubQueryExpression() throws ParseException{
-		trace_call("SubQueryExpression");
-		try{
-			ADQLQuery q = null;
-			Token start, end;
-			start = jj_consume_token(LEFT_PAR);
-			q = QueryExpression();
-			end = jj_consume_token(RIGHT_PAR);
-			q.setPosition(new TextPosition(start, end));
-			{
-				if (true)
-					return q;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("SubQueryExpression");
-		}
-	}
-
-	final public void Select() throws ParseException{
-		trace_call("Select");
-		try{
-			ClauseSelect select = query.getSelect();
-			SelectItem item = null;
-			Token start, t = null;
-			start = jj_consume_token(SELECT);
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case QUANTIFIER:
-					t = jj_consume_token(QUANTIFIER);
-					select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT"));
-					break;
-				default:
-					jj_la1[5] = jj_gen;
-					;
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case TOP:
-					jj_consume_token(TOP);
-					t = jj_consume_token(UNSIGNED_INTEGER);
-					try{
-						select.setLimit(Integer.parseInt(t.image));
-					}catch(NumberFormatException nfe){
-						{
-							if (true)
-								throw new ParseException("[l." + t.beginLine + ";c." + t.beginColumn + "] The TOP limit (\u005c"" + t.image + "\u005c") isn't a regular unsigned integer !");
-						}
-					}
-					break;
-				default:
-					jj_la1[6] = jj_gen;
-					;
-			}
-			item = SelectItem();
-			select.add(item);
-			label_1: while(true){
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case COMMA:
-						;
-						break;
-					default:
-						jj_la1[7] = jj_gen;
-						break label_1;
-				}
-				jj_consume_token(COMMA);
-				item = SelectItem();
-				select.add(item);
-			}
-			TextPosition lastItemPos = query.getSelect().get(query.getSelect().size() - 1).getPosition();
-			select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn));
-		}finally{
-			trace_return("Select");
-		}
-	}
-
-	final public SelectItem SelectItem() throws ParseException{
-		trace_call("SelectItem");
-		try{
-			IdentifierItems identifiers = new IdentifierItems(true);
-			IdentifierItem id = null, label = null;
-			ADQLOperand op = null;
-			SelectItem item;
-			Token starToken;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ASTERISK:
-					starToken = jj_consume_token(ASTERISK);
-					item = new SelectAllColumns(query);
-					item.setPosition(new TextPosition(starToken));{
-					if (true)
-						return item;
-				}
-					break;
-				default:
-					jj_la1[12] = jj_gen;
-					if (jj_2_1(7)){
-						id = Identifier();
-						jj_consume_token(DOT);
-						identifiers.append(id);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								id = Identifier();
-								jj_consume_token(DOT);
-								identifiers.append(id);
-								switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-									case DELIMITED_IDENTIFIER:
-									case REGULAR_IDENTIFIER_CANDIDATE:
-										id = Identifier();
-										jj_consume_token(DOT);
-										identifiers.append(id);
-										break;
-									default:
-										jj_la1[8] = jj_gen;
-										;
-								}
-								break;
-							default:
-								jj_la1[9] = jj_gen;
-								;
-						}
-						starToken = jj_consume_token(ASTERISK);
-						try{
-							item = new SelectAllColumns(queryFactory.createTable(identifiers, null));
-							TextPosition firstPos = identifiers.get(0).position;
-							item.setPosition(new TextPosition(firstPos.beginLine, firstPos.beginColumn, starToken.endLine, (starToken.endColumn < 0) ? -1 : (starToken.endColumn + 1)));
-							{
-								if (true)
-									return item;
-							}
-						}catch(Exception ex){
-							{
-								if (true)
-									throw generateParseException(ex);
-							}
-						}
-					}else{
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case LEFT_PAR:
-							case PLUS:
-							case MINUS:
-							case AVG:
-							case MAX:
-							case MIN:
-							case SUM:
-							case COUNT:
-							case BOX:
-							case CENTROID:
-							case CIRCLE:
-							case POINT:
-							case POLYGON:
-							case REGION:
-							case CONTAINS:
-							case INTERSECTS:
-							case AREA:
-							case COORD1:
-							case COORD2:
-							case COORDSYS:
-							case DISTANCE:
-							case ABS:
-							case CEILING:
-							case DEGREES:
-							case EXP:
-							case FLOOR:
-							case LOG:
-							case LOG10:
-							case MOD:
-							case PI:
-							case POWER:
-							case RADIANS:
-							case RAND:
-							case ROUND:
-							case SQRT:
-							case TRUNCATE:
-							case ACOS:
-							case ASIN:
-							case ATAN:
-							case ATAN2:
-							case COS:
-							case COT:
-							case SIN:
-							case TAN:
-							case STRING_LITERAL:
-							case SCIENTIFIC_NUMBER:
-							case UNSIGNED_FLOAT:
-							case UNSIGNED_INTEGER:
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								op = ValueExpression();
-								switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-									case AS:
-									case DELIMITED_IDENTIFIER:
-									case REGULAR_IDENTIFIER_CANDIDATE:
-										switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-											case AS:
-												jj_consume_token(AS);
-												break;
-											default:
-												jj_la1[10] = jj_gen;
-												;
-										}
-										label = Identifier();
-										break;
-									default:
-										jj_la1[11] = jj_gen;
-										;
-								}
-								break;
-							default:
-								jj_la1[13] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-					}
-			}
-			try{
-				item = queryFactory.createSelectItem(op, (label == null) ? null : label.identifier);
-				if (label != null){
-					item.setCaseSensitive(label.caseSensitivity);
-					item.setPosition(new TextPosition(op.getPosition(), label.position));
-				}else
-					item.setPosition(new TextPosition(op.getPosition()));
-				{
-					if (true)
-						return item;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("SelectItem");
-		}
-	}
-
-	final public void From() throws ParseException{
-		trace_call("From");
-		try{
-			FromContent content = null, content2 = null;
-			try{
-				jj_consume_token(FROM);
-				content = TableRef();
-				label_2: while(true){
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case COMMA:
-							;
-							break;
-						default:
-							jj_la1[14] = jj_gen;
-							break label_2;
-					}
-					jj_consume_token(COMMA);
-					content2 = TableRef();
-					TextPosition startPos = content.getPosition(),
-							endPos = content2.getPosition();
-					content = queryFactory.createJoin(JoinType.CROSS, content, content2);
-					content.setPosition(new TextPosition(startPos, endPos));
-				}
-				query.setFrom(content);
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-		}finally{
-			trace_return("From");
-		}
-	}
-
-	final public void Where() throws ParseException{
-		trace_call("Where");
-		try{
-			ClauseConstraints where = query.getWhere();
-			ADQLConstraint condition;
-			Token start;
-			start = jj_consume_token(WHERE);
-			ConditionsList(where);
-			TextPosition endPosition = where.getPosition();
-			where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
-		}finally{
-			trace_return("Where");
-		}
-	}
-
-	final public void GroupBy() throws ParseException{
-		trace_call("GroupBy");
-		try{
-			ClauseADQL<ADQLColumn> groupBy = query.getGroupBy();
-			ADQLColumn colRef = null;
-			Token start;
-			start = jj_consume_token(GROUP);
-			jj_consume_token(BY);
-			colRef = Column();
-			groupBy.add(colRef);
-			label_3: while(true){
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case COMMA:
-						;
-						break;
-					default:
-						jj_la1[15] = jj_gen;
-						break label_3;
-				}
-				jj_consume_token(COMMA);
-				colRef = Column();
-				groupBy.add(colRef);
-			}
-			groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn));
-		}finally{
-			trace_return("GroupBy");
-		}
-	}
-
-	final public void Having() throws ParseException{
-		trace_call("Having");
-		try{
-			ClauseConstraints having = query.getHaving();
-			Token start;
-			start = jj_consume_token(HAVING);
-			ConditionsList(having);
-			TextPosition endPosition = having.getPosition();
-			having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
-		}finally{
-			trace_return("Having");
-		}
-	}
-
-	final public void OrderBy() throws ParseException{
-		trace_call("OrderBy");
-		try{
-			ClauseADQL<ADQLOrder> orderBy = query.getOrderBy();
-			ADQLOrder order = null;
-			Token start;
-			start = jj_consume_token(ORDER);
-			jj_consume_token(BY);
-			order = OrderItem();
-			orderBy.add(order);
-			label_4: while(true){
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case COMMA:
-						;
-						break;
-					default:
-						jj_la1[16] = jj_gen;
-						break label_4;
-				}
-				jj_consume_token(COMMA);
-				order = OrderItem();
-				orderBy.add(order);
-			}
-			orderBy.setPosition(new TextPosition(start, token));
-		}finally{
-			trace_return("OrderBy");
-		}
-	}
-
-	/* *************************** */
-	/* COLUMN AND TABLE REFERENCES */
-	/* *************************** */
-	final public IdentifierItem Identifier() throws ParseException{
-		trace_call("Identifier");
-		try{
-			Token t;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case REGULAR_IDENTIFIER_CANDIDATE:
-					t = jj_consume_token(REGULAR_IDENTIFIER_CANDIDATE);
-					testRegularIdentifier(t);{
-					if (true)
-						return new IdentifierItem(t, false);
-				}
-					break;
-				case DELIMITED_IDENTIFIER:
-					t = jj_consume_token(DELIMITED_IDENTIFIER);{
-					if (true)
-						return new IdentifierItem(t, true);
-				}
-					break;
-				default:
-					jj_la1[17] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Identifier");
-		}
-	}
-
-	/**
-	 * Extracts the name of a table with its possible catalog and schema prefixes.
-	 * 
-	 * @return A {@link IdentifierItems} which contains at most three items: catalogName, schemaName and tableName.
+	 * Tell whether the given string is a valid ADQL regular identifier.
+	 *
+	 * <p>
+	 * 	According to the ADQL grammar, a regular identifier (i.e. not
+	 * 	delimited ; not between double quotes) must be a letter followed by a
+	 * 	letter, digit or underscore. So, the following regular expression:
+	 * </p>
+	 *
+	 * <pre>
+	 * [a-zA-Z]+[a-zA-Z0-9_]*
+	 * </pre>
+	 *
+	 * <p>
+	 * 	This is what this function tests on the given string.
+	 * </p>
+	 *
+	 * @param idCandidate	The string to test.
+	 *
+	 * @return	<code>true</code> if the given string is a valid regular
+	 *        	identifier,
+	 *        	<code>false</code> otherwise.
+	 *
+	 * @see #testRegularIdentifier(adql.parser.Token)
 	 */
-	final public IdentifierItems TableName() throws ParseException{
-		trace_call("TableName");
-		try{
-			IdentifierItems identifiers = new IdentifierItems(true);
-			IdentifierItem id = null;
-			id = Identifier();
-			identifiers.append(id);
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case DOT:
-					jj_consume_token(DOT);
-					id = Identifier();
-					identifiers.append(id);
-					break;
-				default:
-					jj_la1[18] = jj_gen;
-					;
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case DOT:
-					jj_consume_token(DOT);
-					id = Identifier();
-					identifiers.append(id);
-					break;
-				default:
-					jj_la1[19] = jj_gen;
-					;
-			}
-			{
-				if (true)
-					return identifiers;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("TableName");
-		}
-	}
-
-	/**
-	 * Extracts the name of a column with its possible catalog, schema and table prefixes.
-	 * 
-	 * @return A {@link IdentifierItems} which contains at most four items: catalogName, schemaName, tableName and columnName.
-	 */
-	final public IdentifierItems ColumnName() throws ParseException{
-		trace_call("ColumnName");
-		try{
-			IdentifierItem id;
-			IdentifierItems table = null,
-					identifiers = new IdentifierItems(false);
-			id = Identifier();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case DOT:
-					jj_consume_token(DOT);
-					table = TableName();
-					break;
-				default:
-					jj_la1[20] = jj_gen;
-					;
-			}
-			identifiers.append(id);
-			if (table != null){
-				for(int i = 0; i < table.size(); i++)
-					identifiers.append(table.get(i));
-			}
-			{
-				if (true)
-					return identifiers;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("ColumnName");
-		}
-	}
-
-	final public ADQLColumn Column() throws ParseException{
-		trace_call("Column");
-		try{
-			IdentifierItems identifiers;
-			identifiers = ColumnName();
-			try{
-				{
-					if (true)
-						return queryFactory.createColumn(identifiers);
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Column");
-		}
-	}
-
-	final public ADQLOrder OrderItem() throws ParseException{
-		trace_call("OrderItem");
-		try{
-			IdentifierItem identifier = null;
-			Token ind = null, desc = null;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case DELIMITED_IDENTIFIER:
-				case REGULAR_IDENTIFIER_CANDIDATE:
-					identifier = Identifier();
-					break;
-				case UNSIGNED_INTEGER:
-					ind = jj_consume_token(UNSIGNED_INTEGER);
-					break;
-				default:
-					jj_la1[21] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ASC:
-				case DESC:
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case ASC:
-							jj_consume_token(ASC);
-							break;
-						case DESC:
-							desc = jj_consume_token(DESC);
-							break;
-						default:
-							jj_la1[22] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					break;
-				default:
-					jj_la1[23] = jj_gen;
-					;
-			}
-			try{
-				ADQLOrder order = null;
-				if (identifier != null){
-					order = queryFactory.createOrder(identifier, desc != null);
-					order.setPosition(identifier.position);
-				}else{
-					order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null);
-					order.setPosition(new TextPosition(ind));
-				}
-				{
-					if (true)
-						return order;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("OrderItem");
-		}
-	}
-
-	final public FromContent SimpleTableRef() throws ParseException{
-		trace_call("SimpleTableRef");
-		try{
-			IdentifierItem alias = null;
-			IdentifierItems identifiers = null;
-			ADQLQuery subQuery = null;
-			FromContent content = null;
-			Token start, end;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case DELIMITED_IDENTIFIER:
-					case REGULAR_IDENTIFIER_CANDIDATE:
-						identifiers = TableName();
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case AS:
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-									case AS:
-										jj_consume_token(AS);
-										break;
-									default:
-										jj_la1[24] = jj_gen;
-										;
-								}
-								alias = Identifier();
-								break;
-							default:
-								jj_la1[25] = jj_gen;
-								;
-						}
-						content = queryFactory.createTable(identifiers, alias);
-						if (alias == null)
-							content.setPosition(new TextPosition(identifiers.get(0).position, identifiers.get(identifiers.size() - 1).position));
-						else
-							content.setPosition(new TextPosition(identifiers.get(0).position, alias.position));{
-						if (true)
-							return content;
-					}
-						break;
-					default:
-						jj_la1[27] = jj_gen;
-						if (jj_2_2(2)){
-							subQuery = SubQueryExpression();
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case AS:
-									jj_consume_token(AS);
-									break;
-								default:
-									jj_la1[26] = jj_gen;
-									;
-							}
-							alias = Identifier();
-							content = queryFactory.createTable(subQuery, alias);
-							if (alias == null)
-								content.setPosition(new TextPosition(subQuery.getPosition()));
-							else
-								content.setPosition(new TextPosition(subQuery.getPosition(), alias.position));
-							{
-								if (true)
-									return content;
-							}
-						}else{
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case LEFT_PAR:
-									start = jj_consume_token(LEFT_PAR);
-									content = JoinedTable();
-									end = jj_consume_token(RIGHT_PAR);
-									content.setPosition(new TextPosition(start, end));{
-									if (true)
-										return content;
-								}
-									break;
-								default:
-									jj_la1[28] = jj_gen;
-									jj_consume_token(-1);
-									throw new ParseException();
-							}
-						}
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("SimpleTableRef");
-		}
-	}
-
-	final public FromContent TableRef() throws ParseException{
-		trace_call("TableRef");
-		try{
-			FromContent content;
-			content = SimpleTableRef();
-			label_5: while(true){
-				if (jj_2_3(2)){
-					;
-				}else{
-					break label_5;
-				}
-				content = JoinSpecification(content);
-			}
-			{
-				if (true)
-					return content;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("TableRef");
-		}
-	}
-
-	final public FromContent JoinedTable() throws ParseException{
-		trace_call("JoinedTable");
-		try{
-			FromContent content;
-			content = SimpleTableRef();
-			label_6: while(true){
-				content = JoinSpecification(content);
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case NATURAL:
-					case INNER:
-					case RIGHT:
-					case LEFT:
-					case FULL:
-					case JOIN:
-						;
-						break;
-					default:
-						jj_la1[29] = jj_gen;
-						break label_6;
-				}
-			}
-			{
-				if (true)
-					return content;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("JoinedTable");
-		}
-	}
-
-	final public ADQLJoin JoinSpecification(FromContent leftTable) throws ParseException{
-		trace_call("JoinSpecification");
-		try{
-			boolean natural = false;
-			JoinType type = JoinType.INNER;
-			ClauseConstraints condition = new ClauseConstraints("ON");
-			ArrayList<ADQLColumn> lstColumns = new ArrayList<ADQLColumn>();
-			IdentifierItem id;
-			FromContent rightTable;
-			ADQLJoin join;
-			Token lastPar;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case NATURAL:
-						jj_consume_token(NATURAL);
-						natural = true;
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case INNER:
-							case RIGHT:
-							case LEFT:
-							case FULL:
-								switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-									case INNER:
-										jj_consume_token(INNER);
-										break;
-									case RIGHT:
-									case LEFT:
-									case FULL:
-										switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-											case LEFT:
-												jj_consume_token(LEFT);
-												type = JoinType.OUTER_LEFT;
-												break;
-											case RIGHT:
-												jj_consume_token(RIGHT);
-												type = JoinType.OUTER_RIGHT;
-												break;
-											case FULL:
-												jj_consume_token(FULL);
-												type = JoinType.OUTER_FULL;
-												break;
-											default:
-												jj_la1[30] = jj_gen;
-												jj_consume_token(-1);
-												throw new ParseException();
-										}
-										switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-											case OUTER:
-												jj_consume_token(OUTER);
-												break;
-											default:
-												jj_la1[31] = jj_gen;
-												;
-										}
-										break;
-									default:
-										jj_la1[32] = jj_gen;
-										jj_consume_token(-1);
-										throw new ParseException();
-								}
-								break;
-							default:
-								jj_la1[33] = jj_gen;
-								;
-						}
-						jj_consume_token(JOIN);
-						rightTable = SimpleTableRef();
-						join = queryFactory.createJoin(type, leftTable, rightTable);
-						join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition()));{
-						if (true)
-							return join;
-					}
-						break;
-					case INNER:
-					case RIGHT:
-					case LEFT:
-					case FULL:
-					case JOIN:
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case INNER:
-							case RIGHT:
-							case LEFT:
-							case FULL:
-								switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-									case INNER:
-										jj_consume_token(INNER);
-										break;
-									case RIGHT:
-									case LEFT:
-									case FULL:
-										switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-											case LEFT:
-												jj_consume_token(LEFT);
-												type = JoinType.OUTER_LEFT;
-												break;
-											case RIGHT:
-												jj_consume_token(RIGHT);
-												type = JoinType.OUTER_RIGHT;
-												break;
-											case FULL:
-												jj_consume_token(FULL);
-												type = JoinType.OUTER_FULL;
-												break;
-											default:
-												jj_la1[34] = jj_gen;
-												jj_consume_token(-1);
-												throw new ParseException();
-										}
-										switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-											case OUTER:
-												jj_consume_token(OUTER);
-												break;
-											default:
-												jj_la1[35] = jj_gen;
-												;
-										}
-										break;
-									default:
-										jj_la1[36] = jj_gen;
-										jj_consume_token(-1);
-										throw new ParseException();
-								}
-								break;
-							default:
-								jj_la1[37] = jj_gen;
-								;
-						}
-						jj_consume_token(JOIN);
-						rightTable = SimpleTableRef();
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case ON:
-								jj_consume_token(ON);
-								ConditionsList(condition);
-								join = queryFactory.createJoin(type, leftTable, rightTable, condition);
-								join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition()));{
-								if (true)
-									return join;
-							}
-								break;
-							case USING:
-								jj_consume_token(USING);
-								jj_consume_token(LEFT_PAR);
-								id = Identifier();
-								lstColumns.add(queryFactory.createColumn(id));
-								label_7: while(true){
-									switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-										case COMMA:
-											;
-											break;
-										default:
-											jj_la1[38] = jj_gen;
-											break label_7;
-									}
-									jj_consume_token(COMMA);
-									id = Identifier();
-									lstColumns.add(queryFactory.createColumn(id));
-								}
-								lastPar = jj_consume_token(RIGHT_PAR);
-								join = queryFactory.createJoin(type, leftTable, rightTable, lstColumns);
-								join.setPosition(new TextPosition(leftTable.getPosition().beginLine, leftTable.getPosition().beginColumn, lastPar.endLine, (lastPar.endColumn < 0) ? -1 : (lastPar.endColumn + 1)));{
-								if (true)
-									return join;
-							}
-								break;
-							default:
-								jj_la1[39] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						break;
-					default:
-						jj_la1[40] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("JoinSpecification");
-		}
-	}
-
-	/* ****** */
-	/* STRING */
-	/* ****** */
-	final public StringConstant String() throws ParseException{
-		trace_call("String");
-		try{
-			Token t, start = null;
-			String str = "";
-			StringConstant cst;
-			label_8: while(true){
-				t = jj_consume_token(STRING_LITERAL);
-				str += t.image.substring(1, t.image.length() - 1).replaceAll("''", "'");
-				if (start == null)
-					start = t;
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case STRING_LITERAL:
-						;
-						break;
-					default:
-						jj_la1[41] = jj_gen;
-						break label_8;
-				}
-			}
-			try{
-				cst = queryFactory.createStringConstant(str);
-				cst.setPosition(new TextPosition(start, t));
-				{
-					if (true)
-						return cst;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("String");
-		}
-	}
-
-	/* ************* */
-	/* NUMERIC TYPES */
-	/* ************* */
-	final public NumericConstant UnsignedNumeric() throws ParseException{
-		trace_call("UnsignedNumeric");
-		try{
-			Token t;
-			NumericConstant cst;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case SCIENTIFIC_NUMBER:
-					t = jj_consume_token(SCIENTIFIC_NUMBER);
-					break;
-				case UNSIGNED_FLOAT:
-					t = jj_consume_token(UNSIGNED_FLOAT);
-					break;
-				case UNSIGNED_INTEGER:
-					t = jj_consume_token(UNSIGNED_INTEGER);
-					break;
-				default:
-					jj_la1[42] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			try{
-				cst = queryFactory.createNumericConstant(t.image);
-				cst.setPosition(new TextPosition(t));
-				{
-					if (true)
-						return cst;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("UnsignedNumeric");
-		}
-	}
-
-	final public NumericConstant UnsignedFloat() throws ParseException{
-		trace_call("UnsignedFloat");
-		try{
-			Token t;
-			NumericConstant cst;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case UNSIGNED_INTEGER:
-					t = jj_consume_token(UNSIGNED_INTEGER);
-					break;
-				case UNSIGNED_FLOAT:
-					t = jj_consume_token(UNSIGNED_FLOAT);
-					break;
-				default:
-					jj_la1[43] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			try{
-				cst = queryFactory.createNumericConstant(t.image);
-				cst.setPosition(new TextPosition(t));
-				{
-					if (true)
-						return cst;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("UnsignedFloat");
-		}
-	}
-
-	final public NumericConstant SignedInteger() throws ParseException{
-		trace_call("SignedInteger");
-		try{
-			Token sign = null, number;
-			NumericConstant cst;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case PLUS:
-				case MINUS:
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case PLUS:
-							sign = jj_consume_token(PLUS);
-							break;
-						case MINUS:
-							sign = jj_consume_token(MINUS);
-							break;
-						default:
-							jj_la1[44] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					break;
-				default:
-					jj_la1[45] = jj_gen;
-					;
-			}
-			number = jj_consume_token(UNSIGNED_INTEGER);
-			try{
-				if (sign == null){
-					cst = queryFactory.createNumericConstant(number.image);
-					cst.setPosition(new TextPosition(number));
-				}else{
-					cst = queryFactory.createNumericConstant(sign.image + number.image);
-					cst.setPosition(new TextPosition(sign, number));
-				}
-				{
-					if (true)
-						return cst;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("SignedInteger");
-		}
-	}
-
-	/* *********** */
-	/* EXPRESSIONS */
-	/* *********** */
-	final public ADQLOperand NumericValueExpressionPrimary() throws ParseException{
-		trace_call("NumericValueExpressionPrimary");
-		try{
-			ADQLColumn column;
-			ADQLOperand op;
-			Token left, right;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case SCIENTIFIC_NUMBER:
-					case UNSIGNED_FLOAT:
-					case UNSIGNED_INTEGER:
-						// unsigned_value_specification
-						op = UnsignedNumeric();{
-						if (true)
-							return op;
-					}
-						break;
-					case DELIMITED_IDENTIFIER:
-					case REGULAR_IDENTIFIER_CANDIDATE:
-						column = Column();
-						column.setExpectedType('N');{
-						if (true)
-							return column;
-					}
-						break;
-					case AVG:
-					case MAX:
-					case MIN:
-					case SUM:
-					case COUNT:
-						op = SqlFunction();{
-						if (true)
-							return op;
-					}
-						break;
-					case LEFT_PAR:
-						left = jj_consume_token(LEFT_PAR);
-						op = NumericExpression();
-						right = jj_consume_token(RIGHT_PAR);
-						WrappedOperand wop = queryFactory.createWrappedOperand(op);
-						wop.setPosition(new TextPosition(left, right));{
-						if (true)
-							return wop;
-					}
-						break;
-					default:
-						jj_la1[46] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("NumericValueExpressionPrimary");
-		}
-	}
-
-	final public ADQLOperand StringValueExpressionPrimary() throws ParseException{
-		trace_call("StringValueExpressionPrimary");
-		try{
-			StringConstant expr;
-			ADQLColumn column;
-			ADQLOperand op;
-			Token left, right;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case STRING_LITERAL:
-						// string
-						expr = String();{
-						if (true)
-							return expr;
-					}
-						break;
-					case SCIENTIFIC_NUMBER:
-					case UNSIGNED_FLOAT:
-					case UNSIGNED_INTEGER:
-						op = UnsignedNumeric();{
-						if (true)
-							return op;
-					}
-						break;
-					case AVG:
-					case MAX:
-					case MIN:
-					case SUM:
-					case COUNT:
-						op = SqlFunction();{
-						if (true)
-							return op;
-					}
-						break;
-					case DELIMITED_IDENTIFIER:
-					case REGULAR_IDENTIFIER_CANDIDATE:
-						column = Column();
-						column.setExpectedType('*');{
-						if (true)
-							return column;
-					}
-						break;
-					case LEFT_PAR:
-						left = jj_consume_token(LEFT_PAR);
-						op = ValueExpression();
-						right = jj_consume_token(RIGHT_PAR);
-						WrappedOperand wop = queryFactory.createWrappedOperand(op);
-						wop.setPosition(new TextPosition(left, right));{
-						if (true)
-							return wop;
-					}
-						break;
-					default:
-						jj_la1[47] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("StringValueExpressionPrimary");
-		}
-	}
-
-	final public ADQLOperand ValueExpression() throws ParseException{
-		trace_call("ValueExpression");
-		try{
-			ADQLOperand valueExpr = null;
-			Token left, right;
-			try{
-				if (jj_2_4(2147483647)){
-					valueExpr = NumericExpression();
-				}else if (jj_2_5(2147483647)){
-					valueExpr = StringExpression();
-				}else if (jj_2_6(2147483647)){
-					left = jj_consume_token(LEFT_PAR);
-					valueExpr = ValueExpression();
-					right = jj_consume_token(RIGHT_PAR);
-					valueExpr = queryFactory.createWrappedOperand(valueExpr);
-					((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right));
-				}else if (jj_2_7(2147483647)){
-					valueExpr = UserDefinedFunction();
-				}else if (jj_2_8(2)){
-					valueExpr = GeometryValueFunction();
-				}else if (jj_2_9(2147483647)){
-					valueExpr = Column();
-				}else if (jj_2_10(2147483647)){
-					valueExpr = StringFactor();
-				}else if (jj_2_11(3)){
-					valueExpr = Factor();
-				}else{
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case DELIMITED_IDENTIFIER:
-						case REGULAR_IDENTIFIER_CANDIDATE:
-							valueExpr = Column();
-							break;
-						default:
-							jj_la1[48] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-				}
-				{
-					if (true)
-						return valueExpr;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("ValueExpression");
-		}
-	}
-
-	final public ADQLOperand NumericExpression() throws ParseException{
-		trace_call("NumericExpression");
-		try{
-			Token sign = null;
-			ADQLOperand leftOp, rightOp = null;
-			leftOp = NumericTerm();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case PLUS:
-				case MINUS:
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case PLUS:
-							sign = jj_consume_token(PLUS);
-							break;
-						case MINUS:
-							sign = jj_consume_token(MINUS);
-							break;
-						default:
-							jj_la1[49] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					rightOp = NumericExpression();
-					break;
-				default:
-					jj_la1[50] = jj_gen;
-					;
-			}
-			if (sign == null){
-				if (true)
-					return leftOp;
-			}else{
-				try{
-					Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
-					operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
-					{
-						if (true)
-							return operation;
-					}
-				}catch(Exception ex){
-					{
-						if (true)
-							throw generateParseException(ex);
-					}
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("NumericExpression");
-		}
-	}
-
-	final public ADQLOperand NumericTerm() throws ParseException{
-		trace_call("NumericTerm");
-		try{
-			Token sign = null;
-			ADQLOperand leftOp, rightOp = null;
-			leftOp = Factor();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ASTERISK:
-				case DIVIDE:
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case ASTERISK:
-							sign = jj_consume_token(ASTERISK);
-							break;
-						case DIVIDE:
-							sign = jj_consume_token(DIVIDE);
-							break;
-						default:
-							jj_la1[51] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					rightOp = NumericTerm();
-					break;
-				default:
-					jj_la1[52] = jj_gen;
-					;
-			}
-			if (sign == null){
-				if (true)
-					return leftOp;
-			}else{
-				try{
-					Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
-					operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
-					{
-						if (true)
-							return operation;
-					}
-				}catch(Exception ex){
-					{
-						if (true)
-							throw generateParseException(ex);
-					}
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("NumericTerm");
-		}
-	}
-
-	final public ADQLOperand Factor() throws ParseException{
-		trace_call("Factor");
-		try{
-			boolean negative = false;
-			Token minusSign = null;
-			ADQLOperand op;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case PLUS:
-				case MINUS:
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case PLUS:
-							jj_consume_token(PLUS);
-							break;
-						case MINUS:
-							minusSign = jj_consume_token(MINUS);
-							negative = true;
-							break;
-						default:
-							jj_la1[53] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					break;
-				default:
-					jj_la1[54] = jj_gen;
-					;
-			}
-			if (jj_2_12(2)){
-				op = NumericFunction();
-			}else{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case LEFT_PAR:
-					case AVG:
-					case MAX:
-					case MIN:
-					case SUM:
-					case COUNT:
-					case SCIENTIFIC_NUMBER:
-					case UNSIGNED_FLOAT:
-					case UNSIGNED_INTEGER:
-					case DELIMITED_IDENTIFIER:
-					case REGULAR_IDENTIFIER_CANDIDATE:
-						op = NumericValueExpressionPrimary();
-						break;
-					default:
-						jj_la1[55] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}
-			if (negative){
-				try{
-					TextPosition position = op.getPosition();
-					op = queryFactory.createNegativeOperand(op);
-					NegativeOperand negativeOp = (NegativeOperand)op;
-					if (minusSign != null)
-						negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, position.endLine, position.endColumn));
-					else
-						negativeOp.setPosition(position);
-				}catch(Exception ex){
-					{
-						if (true)
-							throw generateParseException(ex);
-					}
-				}
-			}
-
-			{
-				if (true)
-					return op;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Factor");
-		}
-	}
-
-	final public ADQLOperand StringExpression() throws ParseException{
-		trace_call("StringExpression");
-		try{
-			ADQLOperand leftOp;
-			ADQLOperand rightOp = null;
-			leftOp = StringFactor();
-			label_9: while(true){
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case CONCAT:
-						;
-						break;
-					default:
-						jj_la1[56] = jj_gen;
-						break label_9;
-				}
-				jj_consume_token(CONCAT);
-				rightOp = StringFactor();
-				if (!(leftOp instanceof Concatenation)){
-					try{
-						ADQLOperand temp = leftOp;
-						leftOp = queryFactory.createConcatenation();
-						((Concatenation)leftOp).add(temp);
-					}catch(Exception ex){
-						{
-							if (true)
-								throw generateParseException(ex);
-						}
-					}
-				}
-				((Concatenation)leftOp).add(rightOp);
-			}
-			if (leftOp instanceof Concatenation){
-				Concatenation concat = (Concatenation)leftOp;
-				concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size() - 1).getPosition()));
-			}
-			{
-				if (true)
-					return leftOp;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("StringExpression");
-		}
-	}
-
-	final public ADQLOperand StringFactor() throws ParseException{
-		trace_call("StringFactor");
-		try{
-			ADQLOperand op;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case COORDSYS:
-					op = ExtractCoordSys();
-					break;
-				default:
-					jj_la1[57] = jj_gen;
-					if (jj_2_13(2)){
-						op = UserDefinedFunction();
-						((UserDefinedFunction)op).setExpectedType('S');
-					}else{
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case LEFT_PAR:
-							case AVG:
-							case MAX:
-							case MIN:
-							case SUM:
-							case COUNT:
-							case STRING_LITERAL:
-							case SCIENTIFIC_NUMBER:
-							case UNSIGNED_FLOAT:
-							case UNSIGNED_INTEGER:
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								op = StringValueExpressionPrimary();
-								break;
-							default:
-								jj_la1[58] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-					}
-			}
-			{
-				if (true)
-					return op;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("StringFactor");
-		}
-	}
-
-	final public GeometryValue<GeometryFunction> GeometryExpression() throws ParseException{
-		trace_call("GeometryExpression");
-		try{
-			ADQLColumn col = null;
-			GeometryFunction gf = null;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case DELIMITED_IDENTIFIER:
-				case REGULAR_IDENTIFIER_CANDIDATE:
-					col = Column();
-					break;
-				case BOX:
-				case CENTROID:
-				case CIRCLE:
-				case POINT:
-				case POLYGON:
-				case REGION:
-					gf = GeometryValueFunction();
-					break;
-				default:
-					jj_la1[59] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			if (col != null){
-				col.setExpectedType('G');
-				{
-					if (true)
-						return new GeometryValue<GeometryFunction>(col);
-				}
-			}else{
-				if (true)
-					return new GeometryValue<GeometryFunction>(gf);
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("GeometryExpression");
-		}
-	}
-
-	/* ********************************** */
-	/* BOOLEAN EXPRESSIONS (WHERE clause) */
-	/* ********************************** */
-	final public ClauseConstraints ConditionsList(ClauseConstraints clause) throws ParseException{
-		trace_call("ConditionsList");
-		try{
-			ADQLConstraint constraint = null;
-			Token op = null;
-			boolean notOp = false;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case NOT:
-						op = jj_consume_token(NOT);
-						notOp = true;
-						break;
-					default:
-						jj_la1[60] = jj_gen;
-						;
-				}
-				constraint = Constraint();
-				if (notOp){
-					TextPosition oldPos = constraint.getPosition();
-					constraint = queryFactory.createNot(constraint);
-					((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
-				}
-				notOp = false;
-
-				if (clause instanceof ADQLConstraint)
-					clause.add(constraint);
-				else
-					clause.add(constraint);
-				label_10: while(true){
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case AND:
-						case OR:
-							;
-							break;
-						default:
-							jj_la1[61] = jj_gen;
-							break label_10;
-					}
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case AND:
-							op = jj_consume_token(AND);
-							break;
-						case OR:
-							op = jj_consume_token(OR);
-							break;
-						default:
-							jj_la1[62] = jj_gen;
-							jj_consume_token(-1);
-							throw new ParseException();
-					}
-					switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-						case NOT:
-							jj_consume_token(NOT);
-							notOp = true;
-							break;
-						default:
-							jj_la1[63] = jj_gen;
-							;
-					}
-					constraint = Constraint();
-					if (notOp){
-						TextPosition oldPos = constraint.getPosition();
-						constraint = queryFactory.createNot(constraint);
-						((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
-					}
-					notOp = false;
-
-					if (clause instanceof ADQLConstraint)
-						clause.add(op.image, constraint);
-					else
-						clause.add(op.image, constraint);
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			if (!clause.isEmpty()){
-				TextPosition start = clause.get(0).getPosition();
-				TextPosition end = clause.get(clause.size() - 1).getPosition();
-				clause.setPosition(new TextPosition(start, end));
-			}
-			{
-				if (true)
-					return clause;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("ConditionsList");
-		}
-	}
-
-	final public ADQLConstraint Constraint() throws ParseException{
-		trace_call("Constraint");
-		try{
-			ADQLConstraint constraint = null;
-			Token start, end;
-			if (jj_2_14(2147483647)){
-				constraint = Predicate();
-			}else{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case LEFT_PAR:
-						start = jj_consume_token(LEFT_PAR);
-						try{
-							constraint = queryFactory.createGroupOfConstraints();
-						}catch(Exception ex){
-							{
-								if (true)
-									throw generateParseException(ex);
-							}
-						}
-						ConditionsList((ConstraintsGroup)constraint);
-						end = jj_consume_token(RIGHT_PAR);
-						((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end));
-						break;
-					default:
-						jj_la1[64] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}
-			{
-				if (true)
-					return constraint;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Constraint");
-		}
-	}
-
-	final public ADQLConstraint Predicate() throws ParseException{
-		trace_call("Predicate");
-		try{
-			ADQLQuery q = null;
-			ADQLColumn column = null;
-			ADQLOperand strExpr1 = null, strExpr2 = null;
-			ADQLOperand op;
-			Token start, notToken = null, end;
-			ADQLConstraint constraint = null;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case EXISTS:
-						start = jj_consume_token(EXISTS);
-						q = SubQueryExpression();
-						Exists e = queryFactory.createExists(q);
-						e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));{
-						if (true)
-							return e;
-					}
-						break;
-					default:
-						jj_la1[69] = jj_gen;
-						if (jj_2_16(2147483647)){
-							column = Column();
-							jj_consume_token(IS);
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case NOT:
-									notToken = jj_consume_token(NOT);
-									break;
-								default:
-									jj_la1[65] = jj_gen;
-									;
-							}
-							end = jj_consume_token(NULL);
-							IsNull in = queryFactory.createIsNull((notToken != null), column);
-							in.setPosition(new TextPosition(column.getPosition().beginLine, column.getPosition().beginColumn, end.endLine, (end.endColumn < 0) ? -1 : (end.endColumn + 1)));
-							{
-								if (true)
-									return in;
-							}
-						}else if (jj_2_17(2147483647)){
-							strExpr1 = StringExpression();
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case NOT:
-									notToken = jj_consume_token(NOT);
-									break;
-								default:
-									jj_la1[66] = jj_gen;
-									;
-							}
-							jj_consume_token(LIKE);
-							strExpr2 = StringExpression();
-							Comparison comp = queryFactory.createComparison(strExpr1, (notToken == null) ? ComparisonOperator.LIKE : ComparisonOperator.NOTLIKE, strExpr2);
-							comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition()));
-							{
-								if (true)
-									return comp;
-							}
-						}else{
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case LEFT_PAR:
-								case PLUS:
-								case MINUS:
-								case AVG:
-								case MAX:
-								case MIN:
-								case SUM:
-								case COUNT:
-								case BOX:
-								case CENTROID:
-								case CIRCLE:
-								case POINT:
-								case POLYGON:
-								case REGION:
-								case CONTAINS:
-								case INTERSECTS:
-								case AREA:
-								case COORD1:
-								case COORD2:
-								case COORDSYS:
-								case DISTANCE:
-								case ABS:
-								case CEILING:
-								case DEGREES:
-								case EXP:
-								case FLOOR:
-								case LOG:
-								case LOG10:
-								case MOD:
-								case PI:
-								case POWER:
-								case RADIANS:
-								case RAND:
-								case ROUND:
-								case SQRT:
-								case TRUNCATE:
-								case ACOS:
-								case ASIN:
-								case ATAN:
-								case ATAN2:
-								case COS:
-								case COT:
-								case SIN:
-								case TAN:
-								case STRING_LITERAL:
-								case SCIENTIFIC_NUMBER:
-								case UNSIGNED_FLOAT:
-								case UNSIGNED_INTEGER:
-								case DELIMITED_IDENTIFIER:
-								case REGULAR_IDENTIFIER_CANDIDATE:
-									op = ValueExpression();
-									switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-										case EQUAL:
-										case NOT_EQUAL:
-										case LESS_THAN:
-										case LESS_EQUAL_THAN:
-										case GREATER_THAN:
-										case GREATER_EQUAL_THAN:
-											constraint = ComparisonEnd(op);
-											break;
-										default:
-											jj_la1[67] = jj_gen;
-											if (jj_2_15(2)){
-												constraint = BetweenEnd(op);
-											}else{
-												switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-													case NOT:
-													case IN:
-														constraint = InEnd(op);
-														break;
-													default:
-														jj_la1[68] = jj_gen;
-														jj_consume_token(-1);
-														throw new ParseException();
-												}
-											}
-									}
-									break;
-								default:
-									jj_la1[70] = jj_gen;
-									jj_consume_token(-1);
-									throw new ParseException();
-							}
-						}
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			{
-				if (true)
-					return constraint;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Predicate");
-		}
-	}
-
-	final public Comparison ComparisonEnd(ADQLOperand leftOp) throws ParseException{
-		trace_call("ComparisonEnd");
-		try{
-			Token comp;
-			ADQLOperand rightOp;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case EQUAL:
-					comp = jj_consume_token(EQUAL);
-					break;
-				case NOT_EQUAL:
-					comp = jj_consume_token(NOT_EQUAL);
-					break;
-				case LESS_THAN:
-					comp = jj_consume_token(LESS_THAN);
-					break;
-				case LESS_EQUAL_THAN:
-					comp = jj_consume_token(LESS_EQUAL_THAN);
-					break;
-				case GREATER_THAN:
-					comp = jj_consume_token(GREATER_THAN);
-					break;
-				case GREATER_EQUAL_THAN:
-					comp = jj_consume_token(GREATER_EQUAL_THAN);
-					break;
-				default:
-					jj_la1[71] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			rightOp = ValueExpression();
-			try{
-				Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
-				comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
-				{
-					if (true)
-						return comparison;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("ComparisonEnd");
-		}
-	}
-
-	final public Between BetweenEnd(ADQLOperand leftOp) throws ParseException{
-		trace_call("BetweenEnd");
-		try{
-			Token start, notToken = null;
-			ADQLOperand min, max;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case NOT:
-					notToken = jj_consume_token(NOT);
-					break;
-				default:
-					jj_la1[72] = jj_gen;
-					;
-			}
-			start = jj_consume_token(BETWEEN);
-			min = ValueExpression();
-			jj_consume_token(AND);
-			max = ValueExpression();
-			try{
-				Between bet = queryFactory.createBetween((notToken != null), leftOp, min, max);
-				if (notToken != null)
-					start = notToken;
-				bet.setPosition(new TextPosition(start.beginLine, start.beginColumn, max.getPosition().endLine, max.getPosition().endColumn));
-				{
-					if (true)
-						return bet;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("BetweenEnd");
-		}
-	}
-
-	final public In InEnd(ADQLOperand leftOp) throws ParseException{
-		trace_call("InEnd");
-		try{
-			Token not = null, start;
-			ADQLQuery q = null;
-			ADQLOperand item;
-			Vector<ADQLOperand> items = new Vector<ADQLOperand>();
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case NOT:
-					not = jj_consume_token(NOT);
-					break;
-				default:
-					jj_la1[73] = jj_gen;
-					;
-			}
-			start = jj_consume_token(IN);
-			if (jj_2_18(2)){
-				q = SubQueryExpression();
-			}else{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case LEFT_PAR:
-						jj_consume_token(LEFT_PAR);
-						item = ValueExpression();
-						items.add(item);
-						label_11: while(true){
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case COMMA:
-									;
-									break;
-								default:
-									jj_la1[74] = jj_gen;
-									break label_11;
-							}
-							jj_consume_token(COMMA);
-							item = ValueExpression();
-							items.add(item);
-						}
-						jj_consume_token(RIGHT_PAR);
-						break;
-					default:
-						jj_la1[75] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}
-			try{
-				In in;
-				start = (not != null) ? not : start;
-				if (q != null){
-					in = queryFactory.createIn(leftOp, q, not != null);
-					in.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
-				}else{
-					ADQLOperand[] list = new ADQLOperand[items.size()];
-					int i = 0;
-					for(ADQLOperand op : items)
-						list[i++] = op;
-					in = queryFactory.createIn(leftOp, list, not != null);
-					in.setPosition(new TextPosition(start.beginLine, start.beginColumn, list[list.length - 1].getPosition().endLine, list[list.length - 1].getPosition().endColumn));
-				}
-				{
-					if (true)
-						return in;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("InEnd");
-		}
-	}
-
-	/* ************* */
-	/* SQL FUNCTIONS */
-	/* ************* */
-	final public SQLFunction SqlFunction() throws ParseException{
-		trace_call("SqlFunction");
-		try{
-			Token fct, all = null, distinct = null, end;
-			ADQLOperand op = null;
-			SQLFunction funct = null;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case COUNT:
-						fct = jj_consume_token(COUNT);
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case QUANTIFIER:
-								distinct = jj_consume_token(QUANTIFIER);
-								break;
-							default:
-								jj_la1[76] = jj_gen;
-								;
-						}
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case ASTERISK:
-								all = jj_consume_token(ASTERISK);
-								break;
-							case LEFT_PAR:
-							case PLUS:
-							case MINUS:
-							case AVG:
-							case MAX:
-							case MIN:
-							case SUM:
-							case COUNT:
-							case BOX:
-							case CENTROID:
-							case CIRCLE:
-							case POINT:
-							case POLYGON:
-							case REGION:
-							case CONTAINS:
-							case INTERSECTS:
-							case AREA:
-							case COORD1:
-							case COORD2:
-							case COORDSYS:
-							case DISTANCE:
-							case ABS:
-							case CEILING:
-							case DEGREES:
-							case EXP:
-							case FLOOR:
-							case LOG:
-							case LOG10:
-							case MOD:
-							case PI:
-							case POWER:
-							case RADIANS:
-							case RAND:
-							case ROUND:
-							case SQRT:
-							case TRUNCATE:
-							case ACOS:
-							case ASIN:
-							case ATAN:
-							case ATAN2:
-							case COS:
-							case COT:
-							case SIN:
-							case TAN:
-							case STRING_LITERAL:
-							case SCIENTIFIC_NUMBER:
-							case UNSIGNED_FLOAT:
-							case UNSIGNED_INTEGER:
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								op = ValueExpression();
-								break;
-							default:
-								jj_la1[77] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						funct = queryFactory.createSQLFunction((all != null) ? SQLFunctionType.COUNT_ALL : SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
-						funct.setPosition(new TextPosition(fct, end));
-						break;
-					case AVG:
-					case MAX:
-					case MIN:
-					case SUM:
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case AVG:
-								fct = jj_consume_token(AVG);
-								break;
-							case MAX:
-								fct = jj_consume_token(MAX);
-								break;
-							case MIN:
-								fct = jj_consume_token(MIN);
-								break;
-							case SUM:
-								fct = jj_consume_token(SUM);
-								break;
-							default:
-								jj_la1[78] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case QUANTIFIER:
-								distinct = jj_consume_token(QUANTIFIER);
-								break;
-							default:
-								jj_la1[79] = jj_gen;
-								;
-						}
-						op = ValueExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
-						funct.setPosition(new TextPosition(fct, end));
-						break;
-					default:
-						jj_la1[80] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			{
-				if (true)
-					return funct;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("SqlFunction");
-		}
-	}
-
-	/* ************** */
-	/* ADQL FUNCTIONS */
-	/* ************** */
-	final public ADQLOperand[] Coordinates() throws ParseException{
-		trace_call("Coordinates");
-		try{
-			ADQLOperand[] ops = new ADQLOperand[2];
-			ops[0] = NumericExpression();
-			jj_consume_token(COMMA);
-			ops[1] = NumericExpression();
-			{
-				if (true)
-					return ops;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Coordinates");
-		}
-	}
-
-	final public GeometryFunction GeometryFunction() throws ParseException{
-		trace_call("GeometryFunction");
-		try{
-			Token fct = null, end;
-			GeometryValue<GeometryFunction> gvf1, gvf2;
-			GeometryValue<PointFunction> gvp1, gvp2;
-			GeometryFunction gf = null;
-			PointFunction p1 = null, p2 = null;
-			ADQLColumn col1 = null, col2 = null;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case CONTAINS:
-					case INTERSECTS:
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case CONTAINS:
-								fct = jj_consume_token(CONTAINS);
-								break;
-							case INTERSECTS:
-								fct = jj_consume_token(INTERSECTS);
-								break;
-							default:
-								jj_la1[81] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						jj_consume_token(LEFT_PAR);
-						gvf1 = GeometryExpression();
-						jj_consume_token(COMMA);
-						gvf2 = GeometryExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						if (fct.image.equalsIgnoreCase("contains"))
-							gf = queryFactory.createContains(gvf1, gvf2);
-						else
-							gf = queryFactory.createIntersects(gvf1, gvf2);
-						break;
-					case AREA:
-						fct = jj_consume_token(AREA);
-						jj_consume_token(LEFT_PAR);
-						gvf1 = GeometryExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createArea(gvf1);
-						break;
-					case COORD1:
-						fct = jj_consume_token(COORD1);
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case POINT:
-								p1 = Point();
-								gf = queryFactory.createCoord1(p1);
-								break;
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								col1 = Column();
-								col1.setExpectedType('G');
-								gf = queryFactory.createCoord1(col1);
-								break;
-							default:
-								jj_la1[82] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case COORD2:
-						fct = jj_consume_token(COORD2);
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case POINT:
-								p1 = Point();
-								gf = queryFactory.createCoord2(p1);
-								break;
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								col1 = Column();
-								col1.setExpectedType('G');
-								gf = queryFactory.createCoord2(col1);
-								break;
-							default:
-								jj_la1[83] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case DISTANCE:
-						fct = jj_consume_token(DISTANCE);
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case POINT:
-								p1 = Point();
-								break;
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								col1 = Column();
-								break;
-							default:
-								jj_la1[84] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						if (p1 != null)
-							gvp1 = new GeometryValue<PointFunction>(p1);
-						else{
-							col1.setExpectedType('G');
-							gvp1 = new GeometryValue<PointFunction>(col1);
-						}
-						jj_consume_token(COMMA);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case POINT:
-								p2 = Point();
-								break;
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								col2 = Column();
-								break;
-							default:
-								jj_la1[85] = jj_gen;
-								jj_consume_token(-1);
-								throw new ParseException();
-						}
-						if (p2 != null)
-							gvp2 = new GeometryValue<PointFunction>(p2);
-						else{
-							col2.setExpectedType('G');
-							gvp2 = new GeometryValue<PointFunction>(col2);
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createDistance(gvp1, gvp2);
-						break;
-					default:
-						jj_la1[86] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			gf.setPosition(new TextPosition(fct, end));
-			{
-				if (true)
-					return gf;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("GeometryFunction");
-		}
-	}
-
-	final public ADQLOperand CoordinateSystem() throws ParseException{
-		trace_call("CoordinateSystem");
-		try{
-			ADQLOperand coordSys = null;
-			coordSys = StringExpression();
-			{
-				if (true)
-					return coordSys;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("CoordinateSystem");
-		}
-	}
-
-	final public GeometryFunction GeometryValueFunction() throws ParseException{
-		trace_call("GeometryValueFunction");
-		try{
-			Token fct = null, end = null;
-			ADQLOperand coordSys;
-			ADQLOperand width, height;
-			ADQLOperand[] coords, tmp;
-			Vector<ADQLOperand> vCoords;
-			ADQLOperand op = null;
-			GeometryValue<GeometryFunction> gvf = null;
-			GeometryFunction gf = null;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case BOX:
-						fct = jj_consume_token(BOX);
-						jj_consume_token(LEFT_PAR);
-						coordSys = CoordinateSystem();
-						jj_consume_token(COMMA);
-						coords = Coordinates();
-						jj_consume_token(COMMA);
-						width = NumericExpression();
-						jj_consume_token(COMMA);
-						height = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);
-						break;
-					case CENTROID:
-						fct = jj_consume_token(CENTROID);
-						jj_consume_token(LEFT_PAR);
-						gvf = GeometryExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createCentroid(gvf);
-						break;
-					case CIRCLE:
-						fct = jj_consume_token(CIRCLE);
-						jj_consume_token(LEFT_PAR);
-						coordSys = CoordinateSystem();
-						jj_consume_token(COMMA);
-						coords = Coordinates();
-						jj_consume_token(COMMA);
-						width = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);
-						break;
-					case POINT:
-						gf = Point();
-						break;
-					case POLYGON:
-						fct = jj_consume_token(POLYGON);
-						jj_consume_token(LEFT_PAR);
-						coordSys = CoordinateSystem();
-						vCoords = new Vector<ADQLOperand>();
-						jj_consume_token(COMMA);
-						tmp = Coordinates();
-						vCoords.add(tmp[0]);
-						vCoords.add(tmp[1]);
-						jj_consume_token(COMMA);
-						tmp = Coordinates();
-						vCoords.add(tmp[0]);
-						vCoords.add(tmp[1]);
-						jj_consume_token(COMMA);
-						tmp = Coordinates();
-						vCoords.add(tmp[0]);
-						vCoords.add(tmp[1]);
-						label_12: while(true){
-							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-								case COMMA:
-									;
-									break;
-								default:
-									jj_la1[87] = jj_gen;
-									break label_12;
-							}
-							jj_consume_token(COMMA);
-							tmp = Coordinates();
-							vCoords.add(tmp[0]);
-							vCoords.add(tmp[1]);
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createPolygon(coordSys, vCoords);
-						break;
-					case REGION:
-						fct = jj_consume_token(REGION);
-						jj_consume_token(LEFT_PAR);
-						op = StringExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						gf = queryFactory.createRegion(op);
-						break;
-					default:
-						jj_la1[88] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			if (fct != null && end != null) // = !(gf instanceof Point)
-				gf.setPosition(new TextPosition(fct, end));
-			{
-				if (true)
-					return gf;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("GeometryValueFunction");
-		}
-	}
-
-	final public PointFunction Point() throws ParseException{
-		trace_call("Point");
-		try{
-			Token start, end;
-			ADQLOperand coordSys;
-			ADQLOperand[] coords;
-			start = jj_consume_token(POINT);
-			jj_consume_token(LEFT_PAR);
-			coordSys = CoordinateSystem();
-			jj_consume_token(COMMA);
-			coords = Coordinates();
-			end = jj_consume_token(RIGHT_PAR);
-			try{
-				PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]);
-				pf.setPosition(new TextPosition(start, end));
-				{
-					if (true)
-						return pf;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("Point");
-		}
-	}
-
-	final public GeometryFunction ExtractCoordSys() throws ParseException{
-		trace_call("ExtractCoordSys");
-		try{
-			Token start, end;
-			GeometryValue<GeometryFunction> gvf;
-			start = jj_consume_token(COORDSYS);
-			jj_consume_token(LEFT_PAR);
-			gvf = GeometryExpression();
-			end = jj_consume_token(RIGHT_PAR);
-			try{
-				GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
-				gf.setPosition(new TextPosition(start, end));
-				{
-					if (true)
-						return gf;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("ExtractCoordSys");
-		}
-	}
-
-	/* ***************** */
-	/* NUMERIC FUNCTIONS */
-	/* ***************** */
-	final public ADQLFunction NumericFunction() throws ParseException{
-		trace_call("NumericFunction");
-		try{
-			ADQLFunction fct;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ABS:
-				case CEILING:
-				case DEGREES:
-				case EXP:
-				case FLOOR:
-				case LOG:
-				case LOG10:
-				case MOD:
-				case PI:
-				case POWER:
-				case RADIANS:
-				case RAND:
-				case ROUND:
-				case SQRT:
-				case TRUNCATE:
-					fct = MathFunction();
-					break;
-				case ACOS:
-				case ASIN:
-				case ATAN:
-				case ATAN2:
-				case COS:
-				case COT:
-				case SIN:
-				case TAN:
-					fct = TrigFunction();
-					break;
-				case CONTAINS:
-				case INTERSECTS:
-				case AREA:
-				case COORD1:
-				case COORD2:
-				case DISTANCE:
-					fct = GeometryFunction();
-					break;
-				case REGULAR_IDENTIFIER_CANDIDATE:
-					fct = UserDefinedFunction();
-					((UserDefinedFunction)fct).setExpectedType('N');
-					break;
-				default:
-					jj_la1[89] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			{
-				if (true)
-					return fct;
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("NumericFunction");
-		}
-	}
-
-	final public MathFunction MathFunction() throws ParseException{
-		trace_call("MathFunction");
-		try{
-			Token fct = null, end;
-			ADQLOperand param1 = null, param2 = null;
-			NumericConstant integerValue = null;
-			try{
-				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-					case ABS:
-						fct = jj_consume_token(ABS);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case CEILING:
-						fct = jj_consume_token(CEILING);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case DEGREES:
-						fct = jj_consume_token(DEGREES);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case EXP:
-						fct = jj_consume_token(EXP);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case FLOOR:
-						fct = jj_consume_token(FLOOR);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case LOG:
-						fct = jj_consume_token(LOG);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case LOG10:
-						fct = jj_consume_token(LOG10);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case MOD:
-						fct = jj_consume_token(MOD);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						jj_consume_token(COMMA);
-						param2 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case PI:
-						fct = jj_consume_token(PI);
-						jj_consume_token(LEFT_PAR);
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case POWER:
-						fct = jj_consume_token(POWER);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						jj_consume_token(COMMA);
-						param2 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case RADIANS:
-						fct = jj_consume_token(RADIANS);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case RAND:
-						fct = jj_consume_token(RAND);
-						jj_consume_token(LEFT_PAR);
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case LEFT_PAR:
-							case PLUS:
-							case MINUS:
-							case AVG:
-							case MAX:
-							case MIN:
-							case SUM:
-							case COUNT:
-							case CONTAINS:
-							case INTERSECTS:
-							case AREA:
-							case COORD1:
-							case COORD2:
-							case DISTANCE:
-							case ABS:
-							case CEILING:
-							case DEGREES:
-							case EXP:
-							case FLOOR:
-							case LOG:
-							case LOG10:
-							case MOD:
-							case PI:
-							case POWER:
-							case RADIANS:
-							case RAND:
-							case ROUND:
-							case SQRT:
-							case TRUNCATE:
-							case ACOS:
-							case ASIN:
-							case ATAN:
-							case ATAN2:
-							case COS:
-							case COT:
-							case SIN:
-							case TAN:
-							case SCIENTIFIC_NUMBER:
-							case UNSIGNED_FLOAT:
-							case UNSIGNED_INTEGER:
-							case DELIMITED_IDENTIFIER:
-							case REGULAR_IDENTIFIER_CANDIDATE:
-								param1 = NumericExpression();
-								break;
-							default:
-								jj_la1[90] = jj_gen;
-								;
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case ROUND:
-						fct = jj_consume_token(ROUND);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case COMMA:
-								jj_consume_token(COMMA);
-								param2 = SignedInteger();
-								break;
-							default:
-								jj_la1[91] = jj_gen;
-								;
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case SQRT:
-						fct = jj_consume_token(SQRT);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					case TRUNCATE:
-						fct = jj_consume_token(TRUNCATE);
-						jj_consume_token(LEFT_PAR);
-						param1 = NumericExpression();
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case COMMA:
-								jj_consume_token(COMMA);
-								param2 = SignedInteger();
-								break;
-							default:
-								jj_la1[92] = jj_gen;
-								;
-						}
-						end = jj_consume_token(RIGHT_PAR);
-						break;
-					default:
-						jj_la1[93] = jj_gen;
-						jj_consume_token(-1);
-						throw new ParseException();
-				}
-				MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
-				mf.setPosition(new TextPosition(fct, end));
-				{
-					if (true)
-						return mf;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("MathFunction");
-		}
-	}
-
-	final public MathFunction TrigFunction() throws ParseException{
-		trace_call("TrigFunction");
-		try{
-			Token fct = null, end;
-			ADQLOperand param1 = null, param2 = null;
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case ACOS:
-					fct = jj_consume_token(ACOS);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case ASIN:
-					fct = jj_consume_token(ASIN);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case ATAN:
-					fct = jj_consume_token(ATAN);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case ATAN2:
-					fct = jj_consume_token(ATAN2);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					jj_consume_token(COMMA);
-					param2 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case COS:
-					fct = jj_consume_token(COS);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case COT:
-					fct = jj_consume_token(COT);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case SIN:
-					fct = jj_consume_token(SIN);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				case TAN:
-					fct = jj_consume_token(TAN);
-					jj_consume_token(LEFT_PAR);
-					param1 = NumericExpression();
-					end = jj_consume_token(RIGHT_PAR);
-					break;
-				default:
-					jj_la1[94] = jj_gen;
-					jj_consume_token(-1);
-					throw new ParseException();
-			}
-			try{
-				MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
-				mf.setPosition(new TextPosition(fct, end));
-				{
-					if (true)
-						return mf;
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("TrigFunction");
-		}
-	}
-
-	final public UserDefinedFunction UserDefinedFunction() throws ParseException{
-		trace_call("UserDefinedFunction");
-		try{
-			Token fct, end;
-			Vector<ADQLOperand> params = new Vector<ADQLOperand>();
-			ADQLOperand op;
-			fct = jj_consume_token(REGULAR_IDENTIFIER_CANDIDATE);
-			jj_consume_token(LEFT_PAR);
-			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-				case LEFT_PAR:
-				case PLUS:
-				case MINUS:
-				case AVG:
-				case MAX:
-				case MIN:
-				case SUM:
-				case COUNT:
-				case BOX:
-				case CENTROID:
-				case CIRCLE:
-				case POINT:
-				case POLYGON:
-				case REGION:
-				case CONTAINS:
-				case INTERSECTS:
-				case AREA:
-				case COORD1:
-				case COORD2:
-				case COORDSYS:
-				case DISTANCE:
-				case ABS:
-				case CEILING:
-				case DEGREES:
-				case EXP:
-				case FLOOR:
-				case LOG:
-				case LOG10:
-				case MOD:
-				case PI:
-				case POWER:
-				case RADIANS:
-				case RAND:
-				case ROUND:
-				case SQRT:
-				case TRUNCATE:
-				case ACOS:
-				case ASIN:
-				case ATAN:
-				case ATAN2:
-				case COS:
-				case COT:
-				case SIN:
-				case TAN:
-				case STRING_LITERAL:
-				case SCIENTIFIC_NUMBER:
-				case UNSIGNED_FLOAT:
-				case UNSIGNED_INTEGER:
-				case DELIMITED_IDENTIFIER:
-				case REGULAR_IDENTIFIER_CANDIDATE:
-					op = ValueExpression();
-					params.add(op);
-					label_13: while(true){
-						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
-							case COMMA:
-								;
-								break;
-							default:
-								jj_la1[95] = jj_gen;
-								break label_13;
-						}
-						jj_consume_token(COMMA);
-						op = ValueExpression();
-						params.add(op);
-					}
-					break;
-				default:
-					jj_la1[96] = jj_gen;
-					;
-			}
-			end = jj_consume_token(RIGHT_PAR);
-			// Ensure the given function name is valid: 
-			if (!isRegularIdentifier(fct.image)){
-				if (true)
-					throw new ParseException("Invalid (User Defined) Function name: \u005c"" + fct.image + "\u005c"!", new TextPosition(fct));
-			}
-
-			//System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
-
-			try{
-				//  Build the parameters list:
-				ADQLOperand[] parameters = new ADQLOperand[params.size()];
-				for(int i = 0; i < params.size(); i++)
-					parameters[i] = params.get(i);
-
-				// Create the UDF function:
-				UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
-				udf.setPosition(new TextPosition(fct, end));
-				{
-					if (true)
-						return udf;
-				}
-
-			}catch(UnsupportedOperationException uoe){
-				/* This catch clause is just for backward compatibility:
-				* if the createUserDefinedFunction(...) is overridden and
-				* the function can not be identified a such exception may be thrown). */
-				{
-					if (true)
-						throw new ParseException(uoe.getMessage(), new TextPosition(fct, token));
-				}
-			}catch(Exception ex){
-				{
-					if (true)
-						throw generateParseException(ex);
-				}
-			}
-			throw new Error("Missing return statement in function");
-		}finally{
-			trace_return("UserDefinedFunction");
-		}
-	}
-
-	private boolean jj_2_1(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_1();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(0, xla);
-		}
-	}
-
-	private boolean jj_2_2(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_2();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(1, xla);
-		}
-	}
-
-	private boolean jj_2_3(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_3();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(2, xla);
-		}
-	}
-
-	private boolean jj_2_4(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_4();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(3, xla);
-		}
-	}
-
-	private boolean jj_2_5(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_5();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(4, xla);
-		}
-	}
-
-	private boolean jj_2_6(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_6();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(5, xla);
-		}
-	}
-
-	private boolean jj_2_7(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_7();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(6, xla);
-		}
-	}
-
-	private boolean jj_2_8(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_8();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(7, xla);
-		}
-	}
-
-	private boolean jj_2_9(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_9();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(8, xla);
-		}
-	}
-
-	private boolean jj_2_10(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_10();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(9, xla);
-		}
-	}
-
-	private boolean jj_2_11(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_11();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(10, xla);
-		}
-	}
-
-	private boolean jj_2_12(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_12();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(11, xla);
-		}
-	}
-
-	private boolean jj_2_13(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_13();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(12, xla);
-		}
-	}
-
-	private boolean jj_2_14(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_14();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(13, xla);
-		}
-	}
-
-	private boolean jj_2_15(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_15();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(14, xla);
-		}
-	}
-
-	private boolean jj_2_16(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_16();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(15, xla);
-		}
-	}
-
-	private boolean jj_2_17(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_17();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(16, xla);
-		}
-	}
-
-	private boolean jj_2_18(int xla){
-		jj_la = xla;
-		jj_lastpos = jj_scanpos = token;
-		try{
-			return !jj_3_18();
-		}catch(LookaheadSuccess ls){
-			return true;
-		}finally{
-			jj_save(17, xla);
-		}
-	}
-
-	private boolean jj_3R_76(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_3(){
-		if (jj_3R_17())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_16(){
-		if (jj_3R_22())
-			return true;
-		if (jj_scan_token(IS))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_134(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_51())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_2(){
-		if (jj_3R_16())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_75(){
-		if (jj_3R_79())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_27(){
-		if (jj_3R_51())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_56(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_75()){
-			jj_scanpos = xsp;
-			if (jj_3_2()){
-				jj_scanpos = xsp;
-				if (jj_3R_76())
-					return true;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3_14(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(42)){
-			jj_scanpos = xsp;
-			if (jj_3R_27())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_120(){
-		if (jj_3R_51())
-			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_134()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_60(){
-		if (jj_scan_token(DOT))
-			return true;
-		if (jj_3R_79())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_22(){
-		if (jj_3R_43())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_150(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_153())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_149(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_153())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_43(){
-		if (jj_3R_14())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_60())
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3R_127(){
-		if (jj_scan_token(DOT))
-			return true;
-		if (jj_3R_14())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_126(){
-		if (jj_scan_token(DOT))
-			return true;
-		if (jj_3R_14())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_79(){
-		if (jj_3R_14())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_126())
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_127())
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3R_31(){
-		if (jj_scan_token(DELIMITED_IDENTIFIER))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_133(){
-		if (jj_3R_21())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_30(){
-		if (jj_scan_token(REGULAR_IDENTIFIER_CANDIDATE))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_26(){
-		if (jj_scan_token(REGULAR_IDENTIFIER_CANDIDATE))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_120())
-			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_141(){
-		if (jj_3R_112())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_14(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_30()){
-			jj_scanpos = xsp;
-			if (jj_3R_31())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_132(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_119(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_132()){
-			jj_scanpos = xsp;
-			if (jj_3R_133())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_106(){
-		if (jj_scan_token(TAN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_105(){
-		if (jj_scan_token(SIN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_58(){
-		if (jj_3R_78())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_104(){
-		if (jj_scan_token(COT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_13(){
-		if (jj_3R_26())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_103(){
-		if (jj_scan_token(COS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_102(){
-		if (jj_scan_token(ATAN2))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_57(){
-		if (jj_3R_77())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_101(){
-		if (jj_scan_token(ATAN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_36(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_57()){
-			jj_scanpos = xsp;
-			if (jj_3_13()){
-				jj_scanpos = xsp;
-				if (jj_3R_58())
-					return true;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_100(){
-		if (jj_scan_token(ASIN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_99(){
-		if (jj_scan_token(ACOS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_64(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_99()){
-			jj_scanpos = xsp;
-			if (jj_3R_100()){
-				jj_scanpos = xsp;
-				if (jj_3R_101()){
-					jj_scanpos = xsp;
-					if (jj_3R_102()){
-						jj_scanpos = xsp;
-						if (jj_3R_103()){
-							jj_scanpos = xsp;
-							if (jj_3R_104()){
-								jj_scanpos = xsp;
-								if (jj_3R_105()){
-									jj_scanpos = xsp;
-									if (jj_3R_106())
-										return true;
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_46(){
-		if (jj_3R_62())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_98(){
-		if (jj_scan_token(TRUNCATE))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_150())
-			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_97(){
-		if (jj_scan_token(SQRT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_96(){
-		if (jj_scan_token(ROUND))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_149())
-			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_95(){
-		if (jj_scan_token(RAND))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_141())
-			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_94(){
-		if (jj_scan_token(RADIANS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_93(){
-		if (jj_scan_token(POWER))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_92(){
-		if (jj_scan_token(PI))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_91(){
-		if (jj_scan_token(MOD))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_90(){
-		if (jj_scan_token(LOG10))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_89(){
-		if (jj_scan_token(LOG))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_88(){
-		if (jj_scan_token(FLOOR))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_87(){
-		if (jj_scan_token(EXP))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_52(){
-		if (jj_scan_token(CONCAT))
-			return true;
-		if (jj_3R_36())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_86(){
-		if (jj_scan_token(DEGREES))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_85(){
-		if (jj_scan_token(CEILING))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_84(){
-		if (jj_scan_token(ABS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_29(){
-		if (jj_3R_36())
-			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_52()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_63(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_84()){
-			jj_scanpos = xsp;
-			if (jj_3R_85()){
-				jj_scanpos = xsp;
-				if (jj_3R_86()){
-					jj_scanpos = xsp;
-					if (jj_3R_87()){
-						jj_scanpos = xsp;
-						if (jj_3R_88()){
-							jj_scanpos = xsp;
-							if (jj_3R_89()){
-								jj_scanpos = xsp;
-								if (jj_3R_90()){
-									jj_scanpos = xsp;
-									if (jj_3R_91()){
-										jj_scanpos = xsp;
-										if (jj_3R_92()){
-											jj_scanpos = xsp;
-											if (jj_3R_93()){
-												jj_scanpos = xsp;
-												if (jj_3R_94()){
-													jj_scanpos = xsp;
-													if (jj_3R_95()){
-														jj_scanpos = xsp;
-														if (jj_3R_96()){
-															jj_scanpos = xsp;
-															if (jj_3R_97()){
-																jj_scanpos = xsp;
-																if (jj_3R_98())
-																	return true;
-															}
-														}
-													}
-												}
-											}
-										}
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_61(){
-		if (jj_scan_token(MINUS))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_50(){
-		if (jj_3R_26())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_49(){
-		if (jj_3R_65())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_48(){
-		if (jj_3R_64())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_47(){
-		if (jj_3R_63())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_25(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_47()){
-			jj_scanpos = xsp;
-			if (jj_3R_48()){
-				jj_scanpos = xsp;
-				if (jj_3R_49()){
-					jj_scanpos = xsp;
-					if (jj_3R_50())
-						return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3_12(){
-		if (jj_3R_25())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_45(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(9)){
-			jj_scanpos = xsp;
-			if (jj_3R_61())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_32(){
-		if (jj_3R_14())
-			return true;
-		if (jj_scan_token(DOT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_137(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(11)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(12))
-				return true;
-		}
-		if (jj_3R_130())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_24(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_45())
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_3_12()){
-			jj_scanpos = xsp;
-			if (jj_3R_46())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_15(){
-		if (jj_3R_14())
-			return true;
-		if (jj_scan_token(DOT))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_32())
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3R_77(){
-		if (jj_scan_token(COORDSYS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_119())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_145(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_143(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_140(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_131(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(9)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(10))
-				return true;
-		}
-		if (jj_3R_112())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_59(){
-		if (jj_scan_token(POINT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_138())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_130(){
-		if (jj_3R_24())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_137())
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3R_42(){
-		if (jj_scan_token(REGION))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_29())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_19(){
-		if (jj_3R_24())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(9)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(10)){
-				jj_scanpos = xsp;
-				if (jj_scan_token(11)){
-					jj_scanpos = xsp;
-					if (jj_scan_token(12))
-						return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_20(){
-		if (jj_3R_36())
-			return true;
-		if (jj_scan_token(CONCAT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_1(){
-		if (jj_3R_14())
-			return true;
-		if (jj_scan_token(DOT))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_15())
-			jj_scanpos = xsp;
-		if (jj_scan_token(ASTERISK))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_41(){
-		if (jj_scan_token(POLYGON))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_138())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_140()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_72(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_40(){
-		if (jj_3R_59())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_10(){
-		if (jj_3R_23())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_112(){
-		if (jj_3R_130())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_131())
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3_9(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_7(){
-		if (jj_scan_token(REGULAR_IDENTIFIER_CANDIDATE))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_6(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_39(){
-		if (jj_scan_token(CIRCLE))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_138())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_5(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(65)){
-			jj_scanpos = xsp;
-			if (jj_3R_20())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3_4(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_18()){
-			jj_scanpos = xsp;
-			if (jj_3R_19())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_18(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(9)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(10))
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_38(){
-		if (jj_scan_token(CENTROID))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_119())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_11(){
-		if (jj_3R_24())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_71(){
-		if (jj_3R_36())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_70(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_8(){
-		if (jj_3R_21())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_69(){
-		if (jj_3R_26())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_68(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_51())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_37(){
-		if (jj_scan_token(BOX))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_138())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_139())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_67(){
-		if (jj_3R_29())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_66(){
-		if (jj_3R_112())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_152(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_53(){
-		if (jj_scan_token(SELECT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_125(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_51())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_144(){
-		if (jj_3R_59())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_21(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_37()){
-			jj_scanpos = xsp;
-			if (jj_3R_38()){
-				jj_scanpos = xsp;
-				if (jj_3R_39()){
-					jj_scanpos = xsp;
-					if (jj_3R_40()){
-						jj_scanpos = xsp;
-						if (jj_3R_41()){
-							jj_scanpos = xsp;
-							if (jj_3R_42())
-								return true;
-						}
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_148(){
-		if (jj_3R_51())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_142(){
-		if (jj_3R_59())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_124(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_51(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_66()){
-			jj_scanpos = xsp;
-			if (jj_3R_67()){
-				jj_scanpos = xsp;
-				if (jj_3R_68()){
-					jj_scanpos = xsp;
-					if (jj_3R_69()){
-						jj_scanpos = xsp;
-						if (jj_3_8()){
-							jj_scanpos = xsp;
-							if (jj_3R_70()){
-								jj_scanpos = xsp;
-								if (jj_3R_71()){
-									jj_scanpos = xsp;
-									if (jj_3_11()){
-										jj_scanpos = xsp;
-										if (jj_3R_72())
-											return true;
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_147(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_123(){
-		if (jj_3R_129())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_151(){
-		if (jj_3R_59())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_138(){
-		if (jj_3R_29())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_122(){
-		if (jj_3R_128())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_16(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_33())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_121(){
-		if (jj_3R_23())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_115(){
-		if (jj_scan_token(FULL))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_146(){
-		if (jj_3R_59())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_83(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_82(){
-		if (jj_3R_129())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_78(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_121()){
-			jj_scanpos = xsp;
-			if (jj_3R_122()){
-				jj_scanpos = xsp;
-				if (jj_3R_123()){
-					jj_scanpos = xsp;
-					if (jj_3R_124()){
-						jj_scanpos = xsp;
-						if (jj_3R_125())
-							return true;
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_81(){
-		if (jj_3R_22())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_80(){
-		if (jj_3R_128())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_111(){
-		if (jj_scan_token(DISTANCE))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_146()){
-			jj_scanpos = xsp;
-			if (jj_3R_147())
-				return true;
-		}
-		if (jj_scan_token(COMMA))
-			return true;
-		xsp = jj_scanpos;
-		if (jj_3R_151()){
-			jj_scanpos = xsp;
-			if (jj_3R_152())
-				return true;
-		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_110(){
-		if (jj_scan_token(COORD2))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_144()){
-			jj_scanpos = xsp;
-			if (jj_3R_145())
-				return true;
-		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_109(){
-		if (jj_scan_token(COORD1))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_142()){
-			jj_scanpos = xsp;
-			if (jj_3R_143())
-				return true;
-		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_108(){
-		if (jj_scan_token(AREA))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_119())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_118(){
-		if (jj_scan_token(FULL))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_62(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_80()){
-			jj_scanpos = xsp;
-			if (jj_3R_81()){
-				jj_scanpos = xsp;
-				if (jj_3R_82()){
-					jj_scanpos = xsp;
-					if (jj_3R_83())
-						return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_107(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(60)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(61))
-				return true;
-		}
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_119())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_119())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_33(){
-		if (jj_3R_53())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_114(){
-		if (jj_scan_token(RIGHT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_154(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(9)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(10))
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_153(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_154())
-			jj_scanpos = xsp;
-		if (jj_scan_token(UNSIGNED_INTEGER))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_65(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_107()){
-			jj_scanpos = xsp;
-			if (jj_3R_108()){
-				jj_scanpos = xsp;
-				if (jj_3R_109()){
-					jj_scanpos = xsp;
-					if (jj_3R_110()){
-						jj_scanpos = xsp;
-						if (jj_3R_111())
-							return true;
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_139(){
-		if (jj_3R_112())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_112())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_136(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(49)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(50)){
-				jj_scanpos = xsp;
-				if (jj_scan_token(51)){
-					jj_scanpos = xsp;
-					if (jj_scan_token(52))
-						return true;
-				}
-			}
-		}
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		xsp = jj_scanpos;
-		if (jj_scan_token(20))
-			jj_scanpos = xsp;
-		if (jj_3R_51())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_135(){
-		if (jj_scan_token(COUNT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(20))
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(11)){
-			jj_scanpos = xsp;
-			if (jj_3R_148())
-				return true;
-		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_117(){
-		if (jj_scan_token(RIGHT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_128(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(94)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(95)){
-				jj_scanpos = xsp;
-				if (jj_scan_token(96))
-					return true;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_129(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_135()){
-			jj_scanpos = xsp;
-			if (jj_3R_136())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_113(){
-		if (jj_scan_token(LEFT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_73(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_113()){
-			jj_scanpos = xsp;
-			if (jj_3R_114()){
-				jj_scanpos = xsp;
-				if (jj_3R_115())
-					return true;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_54(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(25)){
-			jj_scanpos = xsp;
-			if (jj_3R_73())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_44(){
-		if (jj_scan_token(STRING_LITERAL))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_23(){
-		Token xsp;
-		if (jj_3R_44())
-			return true;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_44()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_116(){
-		if (jj_scan_token(LEFT))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_74(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_116()){
-			jj_scanpos = xsp;
-			if (jj_3R_117()){
-				jj_scanpos = xsp;
-				if (jj_3R_118())
-					return true;
-			}
-		}
-		xsp = jj_scanpos;
-		if (jj_scan_token(26))
-			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3_18(){
-		if (jj_3R_16())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_55(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(25)){
-			jj_scanpos = xsp;
-			if (jj_3R_74())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_35(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_55())
-			jj_scanpos = xsp;
-		if (jj_scan_token(JOIN))
-			return true;
-		if (jj_3R_56())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_34(){
-		if (jj_scan_token(NATURAL))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_54())
-			jj_scanpos = xsp;
-		if (jj_scan_token(JOIN))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_28(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(36))
-			jj_scanpos = xsp;
-		if (jj_scan_token(BETWEEN))
-			return true;
-		if (jj_3R_51())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_15(){
-		if (jj_3R_28())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_17(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_34()){
-			jj_scanpos = xsp;
-			if (jj_3R_35())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3_17(){
-		if (jj_3R_29())
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(36))
-			jj_scanpos = xsp;
-		if (jj_scan_token(LIKE))
-			return true;
-		return false;
-	}
-
-	/** Generated Token Manager. */
-	public ADQLParserTokenManager token_source;
-	SimpleCharStream jj_input_stream;
-	/** Current token. */
-	public Token token;
-	/** Next token. */
-	public Token jj_nt;
-	private int jj_ntk;
-	private Token jj_scanpos, jj_lastpos;
-	private int jj_la;
-	private int jj_gen;
-	final private int[] jj_la1 = new int[97];
-	static private int[] jj_la1_0;
-	static private int[] jj_la1_1;
-	static private int[] jj_la1_2;
-	static private int[] jj_la1_3;
-	static{
-		jj_la1_init_0();
-		jj_la1_init_1();
-		jj_la1_init_2();
-		jj_la1_init_3();
-	}
-
-	private static void jj_la1_init_0(){
-		jj_la1_0 = new int[]{ 0x81, 0x0, 0x0, 0x0, 0x0, 0x100000, 0x200000, 0x40, 0x0, 0x0, 0x800000, 0x800000, 0x800, 0x608, 0x40, 0x40, 0x40, 0x0, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x800000, 0x800000, 0x800000, 0x0, 0x8, 0x7b000000, 0x38000000, 0x4000000, 0x3a000000, 0x3a000000, 0x38000000, 0x4000000, 0x3a000000, 0x3a000000, 0x40, 0x80000000, 0x7b000000, 0x0, 0x0, 0x0, 0x600, 0x600, 0x8, 0x8, 0x0, 0x600, 0x600, 0x1800, 0x1800, 0x600, 0x600, 0x8, 0x100, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x7e000, 0x0, 0x0, 0x608, 0x7e000, 0x0, 0x0, 0x40, 0x8, 0x100000, 0xe08, 0x0, 0x100000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x608, 0x40, 0x40, 0x0, 0x0, 0x40, 0x608, };
-	}
-
-	private static void jj_la1_init_1(){
-		jj_la1_1 = new int[]{ 0x0, 0x2, 0x1000, 0x2000, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18000, 0x18000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e0000, 0x3e0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e0000, 0x0, 0x0, 0x3e0000, 0xfc00000, 0x10, 0xc, 0xc, 0x10, 0x0, 0x10, 0x10, 0x0, 0x210, 0x400, 0xfffe0000, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0xfffe0000, 0x1e0000, 0x0, 0x3e0000, 0x30000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0xf0000000, 0x0, 0xfc00000, 0xf0000000, 0xf03e0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, };
-	}
-
-	private static void jj_la1_init_2(){
-		jj_la1_2 = new int[]{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3ffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000, 0xc0000000, 0x80000000, 0x0, 0x0, 0xc0000000, 0xe0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x2, 0xe0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3ffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe3ffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x3fffffd, 0xc3fffffd, 0x0, 0x0, 0x3fff8, 0x3fc0000, 0x0, 0xe3ffffff, };
-	}
-
-	private static void jj_la1_init_3(){
-		jj_la1_3 = new int[]{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x0, 0x30, 0x0, 0x31, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x31, 0x31, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x31, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x0, 0x20, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, };
-	}
-
-	final private JJCalls[] jj_2_rtns = new JJCalls[18];
-	private boolean jj_rescan = false;
-	private int jj_gc = 0;
-
-	/** Constructor with InputStream. */
-	public ADQLParser(java.io.InputStream stream){
-		this(stream, (String)null);
-	}
-
-	/** Constructor with InputStream and supplied encoding */
-	public ADQLParser(java.io.InputStream stream, String encoding){
-		try{
-			jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1);
-		}catch(java.io.UnsupportedEncodingException e){
-			throw new RuntimeException(e);
-		}
-		token_source = new ADQLParserTokenManager(jj_input_stream);
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	/** Reinitialise. */
-	public void ReInit(java.io.InputStream stream){
-		ReInit(stream, null);
-	}
-
-	/** Reinitialise. */
-	public void ReInit(java.io.InputStream stream, String encoding){
-		try{
-			jj_input_stream.ReInit(stream, encoding, 1, 1);
-		}catch(java.io.UnsupportedEncodingException e){
-			throw new RuntimeException(e);
-		}
-		token_source.ReInit(jj_input_stream);
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	/** Constructor. */
-	public ADQLParser(java.io.Reader stream){
-		jj_input_stream = new SimpleCharStream(stream, 1, 1);
-		token_source = new ADQLParserTokenManager(jj_input_stream);
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	/** Reinitialise. */
-	public void ReInit(java.io.Reader stream){
-		jj_input_stream.ReInit(stream, 1, 1);
-		token_source.ReInit(jj_input_stream);
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	/** Constructor with generated Token Manager. */
-	public ADQLParser(ADQLParserTokenManager tm){
-		token_source = tm;
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	/** Reinitialise. */
-	public void ReInit(ADQLParserTokenManager tm){
-		token_source = tm;
-		token = new Token();
-		jj_ntk = -1;
-		jj_gen = 0;
-		for(int i = 0; i < 97; i++)
-			jj_la1[i] = -1;
-		for(int i = 0; i < jj_2_rtns.length; i++)
-			jj_2_rtns[i] = new JJCalls();
-	}
-
-	private Token jj_consume_token(int kind) throws ParseException{
-		Token oldToken;
-		if ((oldToken = token).next != null)
-			token = token.next;
-		else
-			token = token.next = token_source.getNextToken();
-		jj_ntk = -1;
-		if (token.kind == kind){
-			jj_gen++;
-			if (++jj_gc > 100){
-				jj_gc = 0;
-				for(int i = 0; i < jj_2_rtns.length; i++){
-					JJCalls c = jj_2_rtns[i];
-					while(c != null){
-						if (c.gen < jj_gen)
-							c.first = null;
-						c = c.next;
-					}
-				}
-			}
-			trace_token(token, "");
-			return token;
-		}
-		token = oldToken;
-		jj_kind = kind;
-		throw generateParseException();
-	}
-
-	static private final class LookaheadSuccess extends java.lang.Error {
-	}
-
-	final private LookaheadSuccess jj_ls = new LookaheadSuccess();
-
-	private boolean jj_scan_token(int kind){
-		if (jj_scanpos == jj_lastpos){
-			jj_la--;
-			if (jj_scanpos.next == null){
-				jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
-			}else{
-				jj_lastpos = jj_scanpos = jj_scanpos.next;
-			}
-		}else{
-			jj_scanpos = jj_scanpos.next;
-		}
-		if (jj_rescan){
-			int i = 0;
-			Token tok = token;
-			while(tok != null && tok != jj_scanpos){
-				i++;
-				tok = tok.next;
-			}
-			if (tok != null)
-				jj_add_error_token(kind, i);
-		}
-		if (jj_scanpos.kind != kind)
-			return true;
-		if (jj_la == 0 && jj_scanpos == jj_lastpos)
-			throw jj_ls;
-		return false;
-	}
-
-	/** Get the next Token. */
-	final public Token getNextToken(){
-		if (token.next != null)
-			token = token.next;
-		else
-			token = token.next = token_source.getNextToken();
-		jj_ntk = -1;
-		jj_gen++;
-		trace_token(token, " (in getNextToken)");
-		return token;
-	}
-
-	/** Get the specific Token. */
-	final public Token getToken(int index){
-		Token t = token;
-		for(int i = 0; i < index; i++){
-			if (t.next != null)
-				t = t.next;
-			else
-				t = t.next = token_source.getNextToken();
-		}
-		return t;
-	}
-
-	private int jj_ntk(){
-		if ((jj_nt = token.next) == null)
-			return (jj_ntk = (token.next = token_source.getNextToken()).kind);
-		else
-			return (jj_ntk = jj_nt.kind);
-	}
-
-	private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
-	private int[] jj_expentry;
-	private int jj_kind = -1;
-	private int[] jj_lasttokens = new int[100];
-	private int jj_endpos;
-
-	private void jj_add_error_token(int kind, int pos){
-		if (pos >= 100)
-			return;
-		if (pos == jj_endpos + 1){
-			jj_lasttokens[jj_endpos++] = kind;
-		}else if (jj_endpos != 0){
-			jj_expentry = new int[jj_endpos];
-			for(int i = 0; i < jj_endpos; i++){
-				jj_expentry[i] = jj_lasttokens[i];
-			}
-			jj_entries_loop: for(java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();){
-				int[] oldentry = (int[])(it.next());
-				if (oldentry.length == jj_expentry.length){
-					for(int i = 0; i < jj_expentry.length; i++){
-						if (oldentry[i] != jj_expentry[i]){
-							continue jj_entries_loop;
-						}
-					}
-					jj_expentries.add(jj_expentry);
-					break jj_entries_loop;
-				}
-			}
-			if (pos != 0)
-				jj_lasttokens[(jj_endpos = pos) - 1] = kind;
-		}
-	}
-
-	/** Generate ParseException. */
-	public ParseException generateParseException(){
-		jj_expentries.clear();
-		boolean[] la1tokens = new boolean[103];
-		if (jj_kind >= 0){
-			la1tokens[jj_kind] = true;
-			jj_kind = -1;
-		}
-		for(int i = 0; i < 97; i++){
-			if (jj_la1[i] == jj_gen){
-				for(int j = 0; j < 32; j++){
-					if ((jj_la1_0[i] & (1 << j)) != 0){
-						la1tokens[j] = true;
-					}
-					if ((jj_la1_1[i] & (1 << j)) != 0){
-						la1tokens[32 + j] = true;
-					}
-					if ((jj_la1_2[i] & (1 << j)) != 0){
-						la1tokens[64 + j] = true;
-					}
-					if ((jj_la1_3[i] & (1 << j)) != 0){
-						la1tokens[96 + j] = true;
-					}
-				}
-			}
-		}
-		for(int i = 0; i < 103; i++){
-			if (la1tokens[i]){
-				jj_expentry = new int[1];
-				jj_expentry[0] = i;
-				jj_expentries.add(jj_expentry);
-			}
-		}
-		jj_endpos = 0;
-		jj_rescan_token();
-		jj_add_error_token(0, 0);
-		int[][] exptokseq = new int[jj_expentries.size()][];
-		for(int i = 0; i < jj_expentries.size(); i++){
-			exptokseq[i] = jj_expentries.get(i);
-		}
-		return new ParseException(token, exptokseq, tokenImage);
-	}
-
-	private int trace_indent = 0;
-	private boolean trace_enabled = true;
-
-	/** Enable tracing. */
-	final public void enable_tracing(){
-		trace_enabled = true;
-	}
-
-	/** Disable tracing. */
-	final public void disable_tracing(){
-		trace_enabled = false;
-	}
-
-	private void trace_call(String s){
-		if (trace_enabled){
-			for(int i = 0; i < trace_indent; i++){
-				System.out.print(" ");
-			}
-			System.out.println("Call:   " + s);
-		}
-		trace_indent = trace_indent + 2;
-	}
-
-	private void trace_return(String s){
-		trace_indent = trace_indent - 2;
-		if (trace_enabled){
-			for(int i = 0; i < trace_indent; i++){
-				System.out.print(" ");
-			}
-			System.out.println("Return: " + s);
-		}
-	}
-
-	private void trace_token(Token t, String where){
-		if (trace_enabled){
-			for(int i = 0; i < trace_indent; i++){
-				System.out.print(" ");
-			}
-			System.out.print("Consumed token: <" + tokenImage[t.kind]);
-			if (t.kind != 0 && !tokenImage[t.kind].equals("\"" + t.image + "\"")){
-				System.out.print(": \"" + t.image + "\"");
-			}
-			System.out.println(" at line " + t.beginLine + " column " + t.beginColumn + ">" + where);
-		}
-	}
-
-	private void trace_scan(Token t1, int t2){
-		if (trace_enabled){
-			for(int i = 0; i < trace_indent; i++){
-				System.out.print(" ");
-			}
-			System.out.print("Visited token: <" + tokenImage[t1.kind]);
-			if (t1.kind != 0 && !tokenImage[t1.kind].equals("\"" + t1.image + "\"")){
-				System.out.print(": \"" + t1.image + "\"");
-			}
-			System.out.println(" at line " + t1.beginLine + " column " + t1.beginColumn + ">; Expected token: <" + tokenImage[t2] + ">");
-		}
-	}
+	public boolean isRegularIdentifier(final String idCandidate);
 
-	private void jj_rescan_token(){
-		jj_rescan = true;
-		for(int i = 0; i < 18; i++){
-			try{
-				JJCalls p = jj_2_rtns[i];
-				do{
-					if (p.gen > jj_gen){
-						jj_la = p.arg;
-						jj_lastpos = jj_scanpos = p.first;
-						switch(i){
-							case 0:
-								jj_3_1();
-								break;
-							case 1:
-								jj_3_2();
-								break;
-							case 2:
-								jj_3_3();
-								break;
-							case 3:
-								jj_3_4();
-								break;
-							case 4:
-								jj_3_5();
-								break;
-							case 5:
-								jj_3_6();
-								break;
-							case 6:
-								jj_3_7();
-								break;
-							case 7:
-								jj_3_8();
-								break;
-							case 8:
-								jj_3_9();
-								break;
-							case 9:
-								jj_3_10();
-								break;
-							case 10:
-								jj_3_11();
-								break;
-							case 11:
-								jj_3_12();
-								break;
-							case 12:
-								jj_3_13();
-								break;
-							case 13:
-								jj_3_14();
-								break;
-							case 14:
-								jj_3_15();
-								break;
-							case 15:
-								jj_3_16();
-								break;
-							case 16:
-								jj_3_17();
-								break;
-							case 17:
-								jj_3_18();
-								break;
-						}
-					}
-					p = p.next;
-				}while(p != null);
-			}catch(LookaheadSuccess ls){
-			}
-		}
-		jj_rescan = false;
-	}
+	public void testRegularIdentifier(final Token token) throws ParseException;
 
-	private void jj_save(int index, int xla){
-		JJCalls p = jj_2_rtns[index];
-		while(p.gen > jj_gen){
-			if (p.next == null){
-				p = p.next = new JJCalls();
-				break;
-			}
-			p = p.next;
-		}
-		p.gen = jj_gen + xla - jj_la;
-		p.first = token;
-		p.arg = xla;
-	}
+	/* **********************************************************************
+	 *                     FUNCTIONS JUST FOR JUNIT
+	 * ********************************************************************** */
 
-	static final class JJCalls {
-		int gen;
-		Token first;
-		int arg;
-		JJCalls next;
-	}
+	ADQLOperand StringExpression() throws ParseException;
 
 }
diff --git a/src/adql/parser/ADQLParserConstants.java b/src/adql/parser/ADQLParserConstants.java
deleted file mode 100644
index 7d09b7bccc42b8c42b7d3ef0c615e56b9050a7f2..0000000000000000000000000000000000000000
--- a/src/adql/parser/ADQLParserConstants.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ADQLParserConstants.java */
-package adql.parser;
-
-
-/**
- * Token literal values and constants.
- * Generated by org.javacc.parser.OtherFilesGen#start()
- */
-public interface ADQLParserConstants {
-
-  /** End of File. */
-  int EOF = 0;
-  /** RegularExpression Id. */
-  int SQL_RESERVED_WORD = 2;
-  /** RegularExpression Id. */
-  int LEFT_PAR = 3;
-  /** RegularExpression Id. */
-  int RIGHT_PAR = 4;
-  /** RegularExpression Id. */
-  int DOT = 5;
-  /** RegularExpression Id. */
-  int COMMA = 6;
-  /** RegularExpression Id. */
-  int EOQ = 7;
-  /** RegularExpression Id. */
-  int CONCAT = 8;
-  /** RegularExpression Id. */
-  int PLUS = 9;
-  /** RegularExpression Id. */
-  int MINUS = 10;
-  /** RegularExpression Id. */
-  int ASTERISK = 11;
-  /** RegularExpression Id. */
-  int DIVIDE = 12;
-  /** RegularExpression Id. */
-  int EQUAL = 13;
-  /** RegularExpression Id. */
-  int NOT_EQUAL = 14;
-  /** RegularExpression Id. */
-  int LESS_THAN = 15;
-  /** RegularExpression Id. */
-  int LESS_EQUAL_THAN = 16;
-  /** RegularExpression Id. */
-  int GREATER_THAN = 17;
-  /** RegularExpression Id. */
-  int GREATER_EQUAL_THAN = 18;
-  /** RegularExpression Id. */
-  int SELECT = 19;
-  /** RegularExpression Id. */
-  int QUANTIFIER = 20;
-  /** RegularExpression Id. */
-  int TOP = 21;
-  /** RegularExpression Id. */
-  int FROM = 22;
-  /** RegularExpression Id. */
-  int AS = 23;
-  /** RegularExpression Id. */
-  int NATURAL = 24;
-  /** RegularExpression Id. */
-  int INNER = 25;
-  /** RegularExpression Id. */
-  int OUTER = 26;
-  /** RegularExpression Id. */
-  int RIGHT = 27;
-  /** RegularExpression Id. */
-  int LEFT = 28;
-  /** RegularExpression Id. */
-  int FULL = 29;
-  /** RegularExpression Id. */
-  int JOIN = 30;
-  /** RegularExpression Id. */
-  int ON = 31;
-  /** RegularExpression Id. */
-  int USING = 32;
-  /** RegularExpression Id. */
-  int WHERE = 33;
-  /** RegularExpression Id. */
-  int AND = 34;
-  /** RegularExpression Id. */
-  int OR = 35;
-  /** RegularExpression Id. */
-  int NOT = 36;
-  /** RegularExpression Id. */
-  int IS = 37;
-  /** RegularExpression Id. */
-  int NULL = 38;
-  /** RegularExpression Id. */
-  int BETWEEN = 39;
-  /** RegularExpression Id. */
-  int LIKE = 40;
-  /** RegularExpression Id. */
-  int IN = 41;
-  /** RegularExpression Id. */
-  int EXISTS = 42;
-  /** RegularExpression Id. */
-  int BY = 43;
-  /** RegularExpression Id. */
-  int GROUP = 44;
-  /** RegularExpression Id. */
-  int HAVING = 45;
-  /** RegularExpression Id. */
-  int ORDER = 46;
-  /** RegularExpression Id. */
-  int ASC = 47;
-  /** RegularExpression Id. */
-  int DESC = 48;
-  /** RegularExpression Id. */
-  int AVG = 49;
-  /** RegularExpression Id. */
-  int MAX = 50;
-  /** RegularExpression Id. */
-  int MIN = 51;
-  /** RegularExpression Id. */
-  int SUM = 52;
-  /** RegularExpression Id. */
-  int COUNT = 53;
-  /** RegularExpression Id. */
-  int BOX = 54;
-  /** RegularExpression Id. */
-  int CENTROID = 55;
-  /** RegularExpression Id. */
-  int CIRCLE = 56;
-  /** RegularExpression Id. */
-  int POINT = 57;
-  /** RegularExpression Id. */
-  int POLYGON = 58;
-  /** RegularExpression Id. */
-  int REGION = 59;
-  /** RegularExpression Id. */
-  int CONTAINS = 60;
-  /** RegularExpression Id. */
-  int INTERSECTS = 61;
-  /** RegularExpression Id. */
-  int AREA = 62;
-  /** RegularExpression Id. */
-  int COORD1 = 63;
-  /** RegularExpression Id. */
-  int COORD2 = 64;
-  /** RegularExpression Id. */
-  int COORDSYS = 65;
-  /** RegularExpression Id. */
-  int DISTANCE = 66;
-  /** RegularExpression Id. */
-  int ABS = 67;
-  /** RegularExpression Id. */
-  int CEILING = 68;
-  /** RegularExpression Id. */
-  int DEGREES = 69;
-  /** RegularExpression Id. */
-  int EXP = 70;
-  /** RegularExpression Id. */
-  int FLOOR = 71;
-  /** RegularExpression Id. */
-  int LOG = 72;
-  /** RegularExpression Id. */
-  int LOG10 = 73;
-  /** RegularExpression Id. */
-  int MOD = 74;
-  /** RegularExpression Id. */
-  int PI = 75;
-  /** RegularExpression Id. */
-  int POWER = 76;
-  /** RegularExpression Id. */
-  int RADIANS = 77;
-  /** RegularExpression Id. */
-  int RAND = 78;
-  /** RegularExpression Id. */
-  int ROUND = 79;
-  /** RegularExpression Id. */
-  int SQRT = 80;
-  /** RegularExpression Id. */
-  int TRUNCATE = 81;
-  /** RegularExpression Id. */
-  int ACOS = 82;
-  /** RegularExpression Id. */
-  int ASIN = 83;
-  /** RegularExpression Id. */
-  int ATAN = 84;
-  /** RegularExpression Id. */
-  int ATAN2 = 85;
-  /** RegularExpression Id. */
-  int COS = 86;
-  /** RegularExpression Id. */
-  int COT = 87;
-  /** RegularExpression Id. */
-  int SIN = 88;
-  /** RegularExpression Id. */
-  int TAN = 89;
-  /** RegularExpression Id. */
-  int STRING_LITERAL = 93;
-  /** RegularExpression Id. */
-  int SCIENTIFIC_NUMBER = 94;
-  /** RegularExpression Id. */
-  int UNSIGNED_FLOAT = 95;
-  /** RegularExpression Id. */
-  int UNSIGNED_INTEGER = 96;
-  /** RegularExpression Id. */
-  int DIGIT = 97;
-  /** RegularExpression Id. */
-  int DELIMITED_IDENTIFIER = 100;
-  /** RegularExpression Id. */
-  int REGULAR_IDENTIFIER_CANDIDATE = 101;
-  /** RegularExpression Id. */
-  int Letter = 102;
-
-  /** Lexical state. */
-  int DEFAULT = 0;
-  /** Lexical state. */
-  int WithinString = 1;
-  /** Lexical state. */
-  int WithinDelimitedId = 2;
-
-  /** Literal token values. */
-  String[] tokenImage = {
-    "<EOF>",
-    "<token of kind 1>",
-    "<SQL_RESERVED_WORD>",
-    "\"(\"",
-    "\")\"",
-    "\".\"",
-    "\",\"",
-    "\";\"",
-    "\"||\"",
-    "\"+\"",
-    "\"-\"",
-    "\"*\"",
-    "\"/\"",
-    "\"=\"",
-    "<NOT_EQUAL>",
-    "\"<\"",
-    "\"<=\"",
-    "\">\"",
-    "\">=\"",
-    "\"SELECT\"",
-    "<QUANTIFIER>",
-    "\"TOP\"",
-    "\"FROM\"",
-    "\"AS\"",
-    "\"NATURAL\"",
-    "\"INNER\"",
-    "\"OUTER\"",
-    "\"RIGHT\"",
-    "\"LEFT\"",
-    "\"FULL\"",
-    "\"JOIN\"",
-    "\"ON\"",
-    "\"USING\"",
-    "\"WHERE\"",
-    "\"AND\"",
-    "\"OR\"",
-    "\"NOT\"",
-    "\"IS\"",
-    "\"NULL\"",
-    "\"BETWEEN\"",
-    "\"LIKE\"",
-    "\"IN\"",
-    "\"EXISTS\"",
-    "\"BY\"",
-    "\"GROUP\"",
-    "\"HAVING\"",
-    "\"ORDER\"",
-    "\"ASC\"",
-    "\"DESC\"",
-    "\"AVG\"",
-    "\"MAX\"",
-    "\"MIN\"",
-    "\"SUM\"",
-    "\"COUNT\"",
-    "\"BOX\"",
-    "\"CENTROID\"",
-    "\"CIRCLE\"",
-    "\"POINT\"",
-    "\"POLYGON\"",
-    "\"REGION\"",
-    "\"CONTAINS\"",
-    "\"INTERSECTS\"",
-    "\"AREA\"",
-    "\"COORD1\"",
-    "\"COORD2\"",
-    "\"COORDSYS\"",
-    "\"DISTANCE\"",
-    "\"ABS\"",
-    "\"CEILING\"",
-    "\"DEGREES\"",
-    "\"EXP\"",
-    "\"FLOOR\"",
-    "\"LOG\"",
-    "\"LOG10\"",
-    "\"MOD\"",
-    "\"PI\"",
-    "\"POWER\"",
-    "\"RADIANS\"",
-    "\"RAND\"",
-    "\"ROUND\"",
-    "\"SQRT\"",
-    "\"TRUNCATE\"",
-    "\"ACOS\"",
-    "\"ASIN\"",
-    "\"ATAN\"",
-    "\"ATAN2\"",
-    "\"COS\"",
-    "\"COT\"",
-    "\"SIN\"",
-    "\"TAN\"",
-    "<token of kind 90>",
-    "\"\\\'\"",
-    "<token of kind 92>",
-    "\"\\\'\"",
-    "<SCIENTIFIC_NUMBER>",
-    "<UNSIGNED_FLOAT>",
-    "<UNSIGNED_INTEGER>",
-    "<DIGIT>",
-    "\"\\\"\"",
-    "<token of kind 99>",
-    "\"\\\"\"",
-    "<REGULAR_IDENTIFIER_CANDIDATE>",
-    "<Letter>",
-  };
-
-}
diff --git a/src/adql/parser/ADQLParserFactory.java b/src/adql/parser/ADQLParserFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..735a370bf41fb127e71f8558a59f5cdacd51e403
--- /dev/null
+++ b/src/adql/parser/ADQLParserFactory.java
@@ -0,0 +1,370 @@
+package adql.parser;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import adql.db.exception.UnresolvedIdentifiersException;
+import adql.query.ADQLQuery;
+import adql.translator.PostgreSQLTranslator;
+import adql.translator.TranslationException;
+
+/**
+ * Factory of ADQL parsers.
+ *
+ * <h3>ADQL versions</h3>
+ *
+ * <p>
+ * 	It is able to deal with all versions of the ADQL grammar supported by this
+ * 	library. All these versions are listed in the enumeration
+ * 	{@link ADQLVersion}.
+ * </p>
+ *
+ * <p>
+ * 	To create a such factory, an ADQL version must be provided. If none is
+ * 	given, the default one will be used (<i>see {@link #DEFAULT_VERSION}</i>).
+ * </p>
+ *
+ * <h3>Runnable class</h3>
+ *
+ * <p>
+ * 	This class includes a main function and thus, it can be executed directly.
+ * 	Its execution allows to parse an ADQL query. Then, in function of the passed
+ * 	parameters, it is possible to just check its syntax, translate it into SQL
+ * 	or try to fix the query.
+ * </p>
+ * <p><i>
+ * 	To get help about this program, just run it with the argument
+ * 	<code>-h</code> or <code>--help</code>.
+ * </i></p>
+ *
+ * @author Gr&eacute;gory Mantelet (CDS)
+ * @version 2.0 (04/2019)
+ * @since 2.0
+ */
+public class ADQLParserFactory {
+
+	/* **********************************************************************
+	 *                         VERSION MANAGEMENT
+	 * ********************************************************************** */
+
+	/**
+	 * Enumeration of all supported versions of the ADQL grammar.
+	 *
+	 * @author Gr&eacute;gory Mantelet (CDS)
+	 * @version 2.0 (04/2019)
+	 * @since 2.0
+	 */
+	public static enum ADQLVersion {
+		/** Version REC-2.0 - <a href="http://www.ivoa.net/documents/cover/ADQL-20081030.html">http://www.ivoa.net/documents/cover/ADQL-20081030.html</a>. */
+		V2_0,
+		/** Version PR-2.1 - <a href="http://www.ivoa.net/documents/ADQL/20180112/index.html">http://www.ivoa.net/documents/ADQL/20180112/index.html</a>. */
+		V2_1; // TODO Move 2.1 as default when it becomes REC
+
+		@Override
+		public String toString() {
+			return name().toLowerCase().replace('_', '.');
+		}
+
+		/** TODO JUnit for ADQLVersion.parse(String)
+		 * Parse the given string as an ADQL version number.
+		 *
+		 * <p>This function should work with the following syntaxes:</p>
+		 * <ul>
+		 * 	<li><code>2.0</code></li>
+		 * 	<li><code>2_0</code></li>
+		 * 	<li><code>v2.0</code> or <code>V2.0</code></li>
+		 * 	<li><code>v2_0</code> or <code>V2_0</code></li>
+		 * </ul>
+		 *
+		 * @param str	String to parse as an ADQL version specification.
+		 *
+		 * @return	The identified ADQL version.
+		 */
+		public static ADQLVersion parse(String str) {
+			if (str == null)
+				return null;
+
+			str = str.trim().toUpperCase();
+
+			if (str.isEmpty())
+				return null;
+
+			if (str.charAt(0) != 'V')
+				str = 'V' + str;
+
+			try {
+				return ADQLVersion.valueOf(str.replaceAll("\\.", "_"));
+			} catch(IllegalArgumentException iae) {
+				return null;
+			}
+		}
+	}
+
+	/** Version of the ADQL grammar to use when none is specified:
+	 * {@link ADQLVersion#V2_0 2.0}. */
+	public final static ADQLVersion DEFAULT_VERSION = ADQLVersion.V2_0; // TODO Move 2.1 as default when it becomes REC
+
+	/**
+	 * Get the list of all supported ADQL grammar versions.
+	 *
+	 * @return	List of all supported ADQL versions.
+	 *
+	 * @see ADQLVersion#values()
+	 */
+	public static ADQLVersion[] getSupportedVersions() {
+		return ADQLVersion.values();
+	}
+
+	/**
+	 * Build on the fly a human list of all supported ADQL grammar versions.
+	 *
+	 * <p><i><b>Example:</b> <code>v2.0</code>, <code>v2.1</code>.</i></p>
+	 *
+	 * @return	List of all supported ADQL versions.
+	 */
+	public static String getSupportedVersionsAsString() {
+		StringBuilder buf = new StringBuilder();
+		for(ADQLVersion v : ADQLVersion.values()) {
+			if (buf.length() > 0)
+				buf.append(", ");
+			buf.append(v.toString());
+			if (v == DEFAULT_VERSION)
+				buf.append(" (default)");
+		}
+		return buf.toString();
+	}
+
+	/* **********************************************************************
+	 *                          PARSER CREATION
+	 * ********************************************************************** */
+
+	/**
+	 * Builds a parser whose the query to parse will have to be given as a
+	 * String in parameter of
+	 * {@link ADQLParser#parseQuery(java.lang.String) parseQuery(String)}.
+	 */
+	public final ADQLParser createParser() {
+		return createParser(DEFAULT_VERSION);
+	}
+
+	/**
+	 * Builds a parser whose the query to parse will have to be given as a
+	 * String in parameter of
+	 * {@link ADQLParser#parseQuery(java.lang.String) parseQuery(String)}.
+	 *
+	 * @param version	Version of the ADQL grammar that the parser must
+	 *               	implement.
+	 *               	<i>If NULL, the {@link #DEFAULT_VERSION} will be used.</i>
+	 */
+	public ADQLParser createParser(ADQLVersion version) {
+		// Prevent the NULL value by setting the default version if necessary:
+		if (version == null)
+			version = DEFAULT_VERSION;
+
+		// Create the appropriate parser in function of the specified version:
+		switch(version) {
+			case V2_0:
+				return new ADQLParser200();
+			case V2_1:
+			default:
+				return new ADQLParser201();
+		}
+	}
+
+	/* **********************************************************************
+	 *                       STATIC PARSER CREATION
+	 * ********************************************************************** */
+
+	/** Factory to use only when a default parser is asked without any
+	 * {@link ADQLParserFactory} instance.
+	 * @see #createDefaultParser() */
+	private static volatile ADQLParserFactory defaultFactory = null;
+
+	/**
+	 * Create an ADQL parser with the default ADQL grammar version (see
+	 * {@link #DEFAULT_VERSION}).
+	 *
+	 * @return	A new parser implementing the default version supported by this
+	 *        	library.
+	 */
+	public final static ADQLParser createDefaultParser() {
+		// Create the default factory, if not already done:
+		if (defaultFactory == null) {
+			synchronized (ADQLParserFactory.class) {
+				if (defaultFactory == null)
+					defaultFactory = new ADQLParserFactory();
+			}
+		}
+
+		// Create a parser implementing the default version of the ADQL grammar:
+		return defaultFactory.createParser(DEFAULT_VERSION);
+	}
+
+	/* **********************************************************************
+	 *                           MAIN FUNCTION
+	 * ********************************************************************** */
+
+	/**
+	* Parses the given ADQL query.
+	*
+	* <p>The result of the parsing depends of the parameters:</p>
+	*
+	* <p>
+	*     <b>ONLY the syntax is checked: the query is NOT EXECUTED !</b>
+	* </p>
+	*/
+	public static final void main(String[] args) throws Exception {
+		final String USAGE = "Usage:\n    adqlParser.jar [-version=...] [-h] [-d] [-v] [-e] [-a|-s] [-f] [<FILE>|<URL>]\n\nNOTE: If no file or URL is given, the ADQL query is expected in the standard\n      input. This query must end with a ';' or <Ctrl+D>!\n\nParameters:\n    -version=...    : Set the version of the ADQL grammar to follow.\n                      It must be one among: " + getSupportedVersionsAsString() + "\n    -h or --help    : Display this help.\n    -v or --verbose : Print the main steps of the parsing\n    -d or --debug   : Print stack traces when a grave error occurs\n    -e or --explain : Explain the ADQL parsing (or Expand the parsing tree)\n    -a or --adql    : Display the understood ADQL query\n    -s or --sql     : Ask the SQL translation of the given ADQL query\n                      (SQL compatible with PostgreSQL)\n    -f or --try-fix : Try fixing the most common ADQL query issues before\n                      attempting to parse the query.\n\nReturn:\n    By default: nothing if the query is correct. Otherwise a message explaining\n                why the query is not correct is displayed.\n    With the -s option, the SQL translation of the given ADQL query will be\n    returned.\n    With the -a option, the ADQL query is returned as it has been understood.\n\nExit status:\n    0  OK !\n    1  Parameter error (missing or incorrect parameter)\n    2  File error (incorrect file/url, reading error, ...)\n    3  Parsing error (syntactic or semantic error)\n    4  Translation error (a problem has occurred during the translation of the\n       given ADQL query in SQL).";
+		final String NEED_HELP_MSG = "Try -h or --help to get more help about the usage of this program.";
+		final String urlRegex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
+
+		ADQLParser parser;
+
+		short mode = -1;
+		String file = null;
+		ADQLVersion version = DEFAULT_VERSION;
+		boolean verbose = false, debug = false, explain = false, tryFix = false;
+
+		// Parameters reading:
+		for(int i = 0; i < args.length; i++) {
+			if (args[i].startsWith("-version=")) {
+				String[] parts = args[i].split("=");
+				if (parts.length <= 1) {
+					System.err.println("((!)) Missing ADQL version! It must be one among: " + getSupportedVersionsAsString() + ". ((!))\n" + NEED_HELP_MSG);
+					System.exit(1);
+				}
+				String strVersion = parts[1].replaceAll("\\.", "_");
+				version = ADQLVersion.parse(strVersion);
+				if (version == null) {
+					System.err.println("((!)) Incorrect ADQL version: \"" + args[i].split("=")[1] + "\"! It must be one among: " + getSupportedVersionsAsString() + ". ((!))\n" + NEED_HELP_MSG);
+					System.exit(1);
+				}
+			} else if (args[i].equalsIgnoreCase("-d") || args[i].equalsIgnoreCase("--debug"))
+				debug = true;
+			else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("--verbose"))
+				verbose = true;
+			else if (args[i].equalsIgnoreCase("-e") || args[i].equalsIgnoreCase("--explain"))
+				explain = true;
+			else if (args[i].equalsIgnoreCase("-a") || args[i].equalsIgnoreCase("--adql")) {
+				if (mode != -1) {
+					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\n" + NEED_HELP_MSG);
+					System.exit(1);
+				} else
+					mode = 1;
+			} else if (args[i].equalsIgnoreCase("-s") || args[i].equalsIgnoreCase("--sql")) {
+				if (mode != -1) {
+					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\n" + NEED_HELP_MSG);
+					System.exit(1);
+				} else
+					mode = 2;
+			} else if (args[i].equalsIgnoreCase("-f") || args[i].equalsIgnoreCase("--try-fix"))
+				tryFix = true;
+			else if (args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")) {
+				System.out.println(USAGE);
+				System.exit(0);
+			} else if (args[i].startsWith("-")) {
+				System.err.println("((!)) Unknown parameter: \"" + args[i] + "\" ((!))\u005cn" + NEED_HELP_MSG);
+				System.exit(1);
+			} else
+				file = args[i].trim();
+		}
+
+		try {
+
+			// Get the parser for the specified ADQL version:
+			parser = (new ADQLParserFactory()).createParser(version);
+
+			// Try fixing the query, if asked:
+			InputStream in = null;
+			if (tryFix) {
+				if (verbose)
+					System.out.println("((i)) Trying to automatically fix the query...");
+
+				String query;
+				try {
+					// get the input stream...
+					if (file == null || file.length() == 0)
+						in = System.in;
+					else if (file.matches(urlRegex))
+						in = (new java.net.URL(file)).openStream();
+					else
+						in = new java.io.FileInputStream(file);
+
+					// ...and try fixing the query:
+					query = parser.tryQuickFix(in);
+				} finally {
+					// close the stream (if opened):
+					if (in != null)
+						in.close();
+					in = null;
+				}
+
+				if (verbose)
+					System.out.println("((i)) SUGGESTED QUERY:\n" + query);
+
+				// Initialise the parser with this fixed query:
+				in = new java.io.ByteArrayInputStream(query.getBytes());
+			}
+			// Otherwise, take the query as provided:
+			else {
+				// Initialise the parser with the specified input:
+				if (file == null || file.length() == 0)
+					in = System.in;
+				else if (file.matches(urlRegex))
+					in = (new java.net.URL(file)).openStream();
+				else
+					in = new java.io.FileInputStream(file);
+			}
+
+			// Enable/Disable the debugging in function of the parameters:
+			parser.setDebug(explain);
+
+			// Query parsing:
+			try {
+				if (verbose)
+					System.out.print("((i)) Parsing ADQL query...");
+				ADQLQuery q = parser.parseQuery(in);
+				if (verbose)
+					System.out.println("((i)) CORRECT ADQL QUERY ((i))");
+				if (mode == 2) {
+					PostgreSQLTranslator translator = new PostgreSQLTranslator();
+					if (verbose)
+						System.out.print("((i)) Translating in SQL...");
+					String sql = translator.translate(q);
+					if (verbose)
+						System.out.println("ok");
+					System.out.println(sql);
+				} else if (mode == 1) {
+					System.out.println(q.toADQL());
+				}
+			} catch(UnresolvedIdentifiersException uie) {
+				System.err.println("((X)) " + uie.getNbErrors() + " unresolved identifiers:");
+				for(ParseException pe : uie)
+					System.err.println("\t - at " + pe.getPosition() + ": " + uie.getMessage());
+				if (debug)
+					uie.printStackTrace(System.err);
+				System.exit(3);
+			} catch(ParseException pe) {
+				System.err.println("((X)) Syntax error: " + pe.getMessage() + " ((X))");
+				if (debug)
+					pe.printStackTrace(System.err);
+				System.exit(3);
+			} catch(TranslationException te) {
+				if (verbose)
+					System.out.println("error");
+				System.err.println("((X)) Translation error: " + te.getMessage() + " ((X))");
+				if (debug)
+					te.printStackTrace(System.err);
+				System.exit(4);
+			}
+
+		} catch(IOException ioe) {
+			System.err.println("\n((X)) Error while reading the file \"" + file + "\": " + ioe.getMessage() + " ((X))");
+			if (debug)
+				ioe.printStackTrace(System.err);
+			System.exit(2);
+		}
+
+	}
+
+}
diff --git a/src/adql/parser/ADQLParserTokenManager.java b/src/adql/parser/ADQLParserTokenManager.java
deleted file mode 100644
index 7f47aa7d68da959f0f403295cee287f9a7a84c9e..0000000000000000000000000000000000000000
--- a/src/adql/parser/ADQLParserTokenManager.java
+++ /dev/null
@@ -1,8154 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ADQLParserTokenManager.java */
-package adql.parser;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.io.FileReader;
-import java.io.IOException;
-import adql.db.exception.UnresolvedIdentifiersException;
-import adql.parser.IdentifierItems.IdentifierItem;
-import adql.parser.ADQLQueryFactory.JoinType;
-import adql.query.*;
-import adql.query.from.*;
-import adql.query.constraint.*;
-import adql.query.operand.*;
-import adql.query.operand.function.*;
-import adql.query.operand.function.geometry.*;
-import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;
-import adql.translator.PostgreSQLTranslator;
-import adql.translator.TranslationException;
-
-/** Token Manager. */
-public class ADQLParserTokenManager implements ADQLParserConstants
-{
-
-  /** Debug output. */
-  public  java.io.PrintStream debugStream = System.out;
-  /** Set debug output. */
-  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_2(int pos, long active0, long active1)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_2(int pos, long active0, long active1)
-{
-   return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0, active1), pos + 1);
-}
-private int jjStopAtPos(int pos, int kind)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   return pos + 1;
-}
-private int jjMoveStringLiteralDfa0_2()
-{
-   switch(curChar)
-   {
-      case 34:
-         return jjStartNfaWithStates_2(0, 100, 1);
-      default :
-         return jjMoveNfa_2(0, 0);
-   }
-}
-private int jjStartNfaWithStates_2(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_2(state, pos + 1);
-}
-static final long[] jjbitVec0 = {
-   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-private int jjMoveNfa_2(int startState, int curPos)
-{
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0xfffffffbffffffffL & l) != 0L)
-                  {
-                     if (kind > 99)
-                        kind = 99;
-                  }
-                  else if (curChar == 34)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (curChar == 34 && kind > 99)
-                     kind = 99;
-                  break;
-               case 2:
-                  if (curChar == 34)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  kind = 99;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 99)
-                     kind = 99;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1)
-{
-   switch (pos)
-   {
-      case 0:
-         if ((active0 & 0x600000000000000L) != 0L || (active1 & 0x1800L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 491;
-         }
-         if ((active0 & 0x10010000000L) != 0L || (active1 & 0x300L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 404;
-         }
-         if ((active0 & 0x200000L) != 0L || (active1 & 0x2020000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 670;
-         }
-         if ((active0 & 0x5001000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 439;
-         }
-         if ((active0 & 0x2000022002000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 332;
-         }
-         if ((active0 & 0x4002800400800000L) != 0L || (active1 & 0x3c0008L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 910;
-         }
-         if ((active0 & 0x40000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 965;
-         }
-         if ((active0 & 0x20L) != 0L)
-            return 966;
-         if ((active0 & 0x100000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 752;
-         }
-         if ((active0 & 0x1000000000000L) != 0L || (active1 & 0x24L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 813;
-         }
-         if ((active0 & 0x100000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 315;
-         }
-         if ((active0 & 0x18000L) != 0L)
-            return 17;
-         if ((active0 & 0x400L) != 0L)
-            return 22;
-         if ((active0 & 0x40088000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 33;
-         }
-         if ((active0 & 0x20400000L) != 0L || (active1 & 0x80L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 295;
-         }
-         if ((active0 & 0xc000000000000L) != 0L || (active1 & 0x400L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 424;
-         }
-         if ((active0 & 0x91a0000000000000L) != 0L || (active1 & 0xc00013L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 52;
-         }
-         if ((active0 & 0x800000008000000L) != 0L || (active1 & 0xe000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 550;
-         }
-         if ((active0 & 0x10000000080000L) != 0L || (active1 & 0x1010000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 590;
-         }
-         if ((active0 & 0x40000000000L) != 0L || (active1 & 0x40L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 249;
-         }
-         if ((active0 & 0x200000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 797;
-         }
-         if ((active0 & 0x400884000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 471;
-         }
-         if ((active0 & 0x200000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            return 5;
-         }
-         return -1;
-      case 1:
-         if ((active0 & 0x2000020002000000L) != 0L)
-            return 345;
-         if ((active0 & 0x40000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 45;
-         }
-         if ((active1 & 0x40000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 913;
-         }
-         if ((active1 & 0x2000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 669;
-         }
-         if ((active0 & 0x8000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 32;
-         }
-         if ((active0 & 0x1000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 438;
-         }
-         if ((active0 & 0x10000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 656;
-         }
-         if ((active0 & 0x100000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 770;
-         }
-         if ((active0 & 0x800000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 549;
-         }
-         if ((active0 & 0x2000000000L) != 0L)
-            return 396;
-         if ((active1 & 0x400L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 431;
-         }
-         if ((active1 & 0x10000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 637;
-         }
-         if ((active0 & 0x4000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 967;
-         }
-         if ((active0 & 0x4000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 482;
-         }
-         if ((active0 & 0x400000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 968;
-         }
-         if ((active1 & 0x300L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 416;
-         }
-         if ((active0 & 0x600000000000000L) != 0L || (active1 & 0x1000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 501;
-         }
-         if ((active1 & 0x8L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 909;
-         }
-         if ((active0 & 0x200000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 796;
-         }
-         if ((active0 & 0x8000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 427;
-         }
-         if ((active0 & 0x182210068400000L) != 0L || (active1 & 0x6010L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 965;
-         }
-         if ((active0 & 0x10000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 410;
-         }
-         if ((active0 & 0x1000000000000L) != 0L || (active1 & 0x20L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 821;
-         }
-         if ((active1 & 0x4L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 877;
-         }
-         if ((active0 & 0x480800000000L) != 0L || (active1 & 0x800L) != 0L)
-            return 965;
-         if ((active1 & 0x20000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 717;
-         }
-         if ((active1 & 0x80L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 303;
-         }
-         if ((active0 & 0x40000000000L) != 0L || (active1 & 0x40L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 264;
-         }
-         if ((active1 & 0x8000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 581;
-         }
-         if ((active0 & 0x80000000L) != 0L)
-            return 472;
-         if ((active0 & 0x4000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 423;
-         }
-         if ((active0 & 0x1000200000L) != 0L || (active1 & 0x300000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 2;
-               jjmatchedPos = 1;
-            }
-            return 965;
-         }
-         if ((active0 & 0x4000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 454;
-         }
-         if ((active0 & 0x100000000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 324;
-         }
-         if ((active0 & 0x800000800000L) != 0L || (active1 & 0x80000L) != 0L)
-            return 932;
-         if ((active1 & 0x1000000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 620;
-         }
-         if ((active0 & 0x80000L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 597;
-         }
-         if ((active0 & 0x9020000000000000L) != 0L || (active1 & 0xc00003L) != 0L)
-         {
-            if (jjmatchedPos != 1)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 1;
-            }
-            return 113;
-         }
-         return -1;
-      case 2:
-         if ((active0 & 0x56801400200000L) != 0L || (active1 & 0x3c00340L) != 0L)
-            return 965;
-         if ((active0 & 0x8fa075817a480000L) != 0L || (active1 & 0x3df033L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 965;
-         }
-         if ((active0 & 0x1000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 859;
-         }
-         if ((active0 & 0x8000000000000L) != 0L)
-            return 426;
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 2;
-               jjmatchedPos = 2;
-            }
-            return 373;
-         }
-         if ((active0 & 0x4000000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 453;
-         }
-         if ((active1 & 0x4L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 884;
-         }
-         if ((active1 & 0x400L) != 0L)
-            return 430;
-         if ((active1 & 0x8L) != 0L)
-            return 908;
-         if ((active0 & 0x200000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 801;
-         }
-         if ((active0 & 0x4000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 481;
-         }
-         if ((active1 & 0x20000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 967;
-         }
-         if ((active0 & 0x4000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 2;
-               jjmatchedPos = 2;
-            }
-            return 965;
-         }
-         if ((active0 & 0x1000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 443;
-         }
-         if ((active0 & 0x1000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 137;
-         }
-         if ((active1 & 0x80L) != 0L)
-         {
-            if (jjmatchedPos != 2)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 2;
-            }
-            return 302;
-         }
-         return -1;
-      case 3:
-         if ((active1 & 0x4L) != 0L)
-         {
-            if (jjmatchedPos != 3)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 3;
-            }
-            return 900;
-         }
-         if ((active0 & 0x8fa074830f080000L) != 0L || (active1 & 0x2b0b3L) != 0L)
-         {
-            if (jjmatchedPos != 3)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 3;
-            }
-            return 965;
-         }
-         if ((active0 & 0x1000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 3)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 3;
-            }
-            return 168;
-         }
-         if ((active0 & 0x4000000000L) != 0L)
-            return 452;
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            if (jjmatchedPos != 3)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 3;
-            }
-            return 372;
-         }
-         if ((active0 & 0x4000010070400000L) != 0L || (active1 & 0x3d4000L) != 0L)
-            return 965;
-         if ((active1 & 0x200L) != 0L)
-         {
-            if (jjmatchedPos != 3)
-            {
-               jjmatchedKind = 101;
-               jjmatchedPos = 3;
-            }
-            return 28;
-         }
-         if ((active0 & 0x1000000000000L) != 0L)
-            return 858;
-         return -1;
-      case 4:
-         if ((active0 & 0x9d80248001080000L) != 0L || (active1 & 0x22037L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 4;
-            return 965;
-         }
-         if ((active1 & 0x200200L) != 0L)
-            return 28;
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 4;
-            return 378;
-         }
-         if ((active0 & 0x22050030e000000L) != 0L || (active1 & 0x9080L) != 0L)
-            return 965;
-         return -1;
-      case 5:
-         if ((active0 & 0x8000000000000000L) != 0L || (active1 & 0x1L) != 0L)
-            return 28;
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 5;
-            return 377;
-         }
-         if ((active0 & 0x900240000080000L) != 0L)
-            return 965;
-         if ((active0 & 0x1480008001000000L) != 0L || (active1 & 0x22036L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 5;
-            return 965;
-         }
-         return -1;
-      case 6:
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 6;
-            return 376;
-         }
-         if ((active0 & 0x1080000000000000L) != 0L || (active1 & 0x20006L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 6;
-            return 965;
-         }
-         if ((active0 & 0x400008001000000L) != 0L || (active1 & 0x2030L) != 0L)
-            return 965;
-         return -1;
-      case 7:
-         if ((active0 & 0x1080000000000000L) != 0L || (active1 & 0x20006L) != 0L)
-            return 965;
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            jjmatchedKind = 101;
-            jjmatchedPos = 7;
-            return 969;
-         }
-         return -1;
-      case 8:
-         if ((active0 & 0x2000000000000000L) != 0L)
-         {
-            jjmatchedKind = 2;
-            jjmatchedPos = 8;
-            return 965;
-         }
-         return -1;
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_0(int pos, long active0, long active1)
-{
-   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1);
-}
-private int jjMoveStringLiteralDfa0_0()
-{
-   switch(curChar)
-   {
-      case 34:
-         return jjStopAtPos(0, 98);
-      case 39:
-         return jjStopAtPos(0, 91);
-      case 40:
-         return jjStopAtPos(0, 3);
-      case 41:
-         return jjStopAtPos(0, 4);
-      case 42:
-         return jjStopAtPos(0, 11);
-      case 43:
-         return jjStopAtPos(0, 9);
-      case 44:
-         return jjStopAtPos(0, 6);
-      case 45:
-         return jjStartNfaWithStates_0(0, 10, 22);
-      case 46:
-         return jjStartNfaWithStates_0(0, 5, 966);
-      case 47:
-         return jjStopAtPos(0, 12);
-      case 59:
-         return jjStopAtPos(0, 7);
-      case 60:
-         jjmatchedKind = 15;
-         return jjMoveStringLiteralDfa1_0(0x10000L, 0x0L);
-      case 61:
-         return jjStopAtPos(0, 13);
-      case 62:
-         jjmatchedKind = 17;
-         return jjMoveStringLiteralDfa1_0(0x40000L, 0x0L);
-      case 65:
-      case 97:
-         return jjMoveStringLiteralDfa1_0(0x4002800400800000L, 0x3c0008L);
-      case 66:
-      case 98:
-         return jjMoveStringLiteralDfa1_0(0x40088000000000L, 0x0L);
-      case 67:
-      case 99:
-         return jjMoveStringLiteralDfa1_0(0x91a0000000000000L, 0xc00013L);
-      case 68:
-      case 100:
-         return jjMoveStringLiteralDfa1_0(0x1000000000000L, 0x24L);
-      case 69:
-      case 101:
-         return jjMoveStringLiteralDfa1_0(0x40000000000L, 0x40L);
-      case 70:
-      case 102:
-         return jjMoveStringLiteralDfa1_0(0x20400000L, 0x80L);
-      case 71:
-      case 103:
-         return jjMoveStringLiteralDfa1_0(0x100000000000L, 0x0L);
-      case 72:
-      case 104:
-         return jjMoveStringLiteralDfa1_0(0x200000000000L, 0x0L);
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa1_0(0x2000022002000000L, 0x0L);
-      case 74:
-      case 106:
-         return jjMoveStringLiteralDfa1_0(0x40000000L, 0x0L);
-      case 76:
-      case 108:
-         return jjMoveStringLiteralDfa1_0(0x10010000000L, 0x300L);
-      case 77:
-      case 109:
-         return jjMoveStringLiteralDfa1_0(0xc000000000000L, 0x400L);
-      case 78:
-      case 110:
-         return jjMoveStringLiteralDfa1_0(0x5001000000L, 0x0L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa1_0(0x400884000000L, 0x0L);
-      case 80:
-      case 112:
-         return jjMoveStringLiteralDfa1_0(0x600000000000000L, 0x1800L);
-      case 82:
-      case 114:
-         return jjMoveStringLiteralDfa1_0(0x800000008000000L, 0xe000L);
-      case 83:
-      case 115:
-         return jjMoveStringLiteralDfa1_0(0x10000000080000L, 0x1010000L);
-      case 84:
-      case 116:
-         return jjMoveStringLiteralDfa1_0(0x200000L, 0x2020000L);
-      case 85:
-      case 117:
-         return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L);
-      case 87:
-      case 119:
-         return jjMoveStringLiteralDfa1_0(0x200000000L, 0x0L);
-      case 124:
-         return jjMoveStringLiteralDfa1_0(0x100L, 0x0L);
-      default :
-         return jjMoveNfa_0(0, 0);
-   }
-}
-private int jjMoveStringLiteralDfa1_0(long active0, long active1)
-{
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(0, active0, active1);
-      return 1;
-   }
-   switch(curChar)
-   {
-      case 61:
-         if ((active0 & 0x10000L) != 0L)
-            return jjStopAtPos(1, 16);
-         else if ((active0 & 0x40000L) != 0L)
-            return jjStopAtPos(1, 18);
-         break;
-      case 65:
-      case 97:
-         return jjMoveStringLiteralDfa2_0(active0, 0x4200001000000L, active1, 0x2006000L);
-      case 66:
-      case 98:
-         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x8L);
-      case 67:
-      case 99:
-         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x40000L);
-      case 69:
-      case 101:
-         return jjMoveStringLiteralDfa2_0(active0, 0x881008010080000L, active1, 0x30L);
-      case 72:
-      case 104:
-         return jjMoveStringLiteralDfa2_0(active0, 0x200000000L, active1, 0L);
-      case 73:
-      case 105:
-         if ((active1 & 0x800L) != 0L)
-            return jjStartNfaWithStates_0(1, 75, 965);
-         return jjMoveStringLiteralDfa2_0(active0, 0x108010008000000L, active1, 0x1000004L);
-      case 76:
-      case 108:
-         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x80L);
-      case 78:
-      case 110:
-         if ((active0 & 0x80000000L) != 0L)
-            return jjStartNfaWithStates_0(1, 31, 472);
-         else if ((active0 & 0x20000000000L) != 0L)
-         {
-            jjmatchedKind = 41;
-            jjmatchedPos = 1;
-         }
-         return jjMoveStringLiteralDfa2_0(active0, 0x2000000402000000L, active1, 0L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa2_0(active0, 0x9660001040200000L, active1, 0xc09703L);
-      case 81:
-      case 113:
-         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000L);
-      case 82:
-      case 114:
-         if ((active0 & 0x800000000L) != 0L)
-         {
-            jjmatchedKind = 35;
-            jjmatchedPos = 1;
-         }
-         return jjMoveStringLiteralDfa2_0(active0, 0x4000500000400000L, active1, 0x20000L);
-      case 83:
-      case 115:
-         if ((active0 & 0x800000L) != 0L)
-         {
-            jjmatchedKind = 23;
-            jjmatchedPos = 1;
-         }
-         else if ((active0 & 0x2000000000L) != 0L)
-            return jjStartNfaWithStates_0(1, 37, 396);
-         return jjMoveStringLiteralDfa2_0(active0, 0x800100000000L, active1, 0x80000L);
-      case 84:
-      case 116:
-         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x300000L);
-      case 85:
-      case 117:
-         return jjMoveStringLiteralDfa2_0(active0, 0x10004024000000L, active1, 0L);
-      case 86:
-      case 118:
-         return jjMoveStringLiteralDfa2_0(active0, 0x2000000000000L, active1, 0L);
-      case 88:
-      case 120:
-         return jjMoveStringLiteralDfa2_0(active0, 0x40000000000L, active1, 0x40L);
-      case 89:
-      case 121:
-         if ((active0 & 0x80000000000L) != 0L)
-            return jjStartNfaWithStates_0(1, 43, 965);
-         break;
-      case 124:
-         if ((active0 & 0x100L) != 0L)
-            return jjStopAtPos(1, 8);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(0, active0, active1);
-}
-private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(0, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(1, active0, active1);
-      return 2;
-   }
-   switch(curChar)
-   {
-      case 65:
-      case 97:
-         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x300000L);
-      case 67:
-      case 99:
-         if ((active0 & 0x800000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 47, 965);
-         break;
-      case 68:
-      case 100:
-         if ((active0 & 0x400000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 34, 965);
-         else if ((active1 & 0x400L) != 0L)
-            return jjStartNfaWithStates_0(2, 74, 430);
-         return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0x2000L);
-      case 69:
-      case 101:
-         return jjMoveStringLiteralDfa3_0(active0, 0x4000000200000000L, active1, 0L);
-      case 70:
-      case 102:
-         return jjMoveStringLiteralDfa3_0(active0, 0x10000000L, active1, 0L);
-      case 71:
-      case 103:
-         if ((active0 & 0x2000000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 49, 965);
-         else if ((active1 & 0x100L) != 0L)
-         {
-            jjmatchedKind = 72;
-            jjmatchedPos = 2;
-         }
-         return jjMoveStringLiteralDfa3_0(active0, 0x800000008000000L, active1, 0x220L);
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa3_0(active0, 0x200040140000000L, active1, 0x80010L);
-      case 75:
-      case 107:
-         return jjMoveStringLiteralDfa3_0(active0, 0x10000000000L, active1, 0L);
-      case 76:
-      case 108:
-         return jjMoveStringLiteralDfa3_0(active0, 0x400004020080000L, active1, 0L);
-      case 77:
-      case 109:
-         if ((active0 & 0x10000000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 52, 965);
-         break;
-      case 78:
-      case 110:
-         if ((active0 & 0x8000000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 51, 426);
-         else if ((active1 & 0x1000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 88, 965);
-         else if ((active1 & 0x2000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 89, 965);
-         return jjMoveStringLiteralDfa3_0(active0, 0x1080000002000000L, active1, 0x4000L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa3_0(active0, 0x8000100000400000L, active1, 0x40083L);
-      case 80:
-      case 112:
-         if ((active0 & 0x200000L) != 0L)
-            return jjStartNfaWithStates_0(2, 21, 965);
-         else if ((active1 & 0x40L) != 0L)
-            return jjStartNfaWithStates_0(2, 70, 965);
-         break;
-      case 82:
-      case 114:
-         return jjMoveStringLiteralDfa3_0(active0, 0x100000000000000L, active1, 0x10000L);
-      case 83:
-      case 115:
-         if ((active1 & 0x8L) != 0L)
-            return jjStartNfaWithStates_0(2, 67, 908);
-         else if ((active1 & 0x400000L) != 0L)
-            return jjStartNfaWithStates_0(2, 86, 965);
-         return jjMoveStringLiteralDfa3_0(active0, 0x1000000000000L, active1, 0x4L);
-      case 84:
-      case 116:
-         if ((active0 & 0x1000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 36, 965);
-         else if ((active1 & 0x800000L) != 0L)
-            return jjStartNfaWithStates_0(2, 87, 965);
-         return jjMoveStringLiteralDfa3_0(active0, 0x2000008005000000L, active1, 0L);
-      case 85:
-      case 117:
-         return jjMoveStringLiteralDfa3_0(active0, 0x20000000000000L, active1, 0x28000L);
-      case 86:
-      case 118:
-         return jjMoveStringLiteralDfa3_0(active0, 0x200000000000L, active1, 0L);
-      case 87:
-      case 119:
-         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x1000L);
-      case 88:
-      case 120:
-         if ((active0 & 0x4000000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 50, 965);
-         else if ((active0 & 0x40000000000000L) != 0L)
-            return jjStartNfaWithStates_0(2, 54, 965);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(1, active0, active1);
-}
-private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(1, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(2, active0, active1);
-      return 3;
-   }
-   switch(curChar)
-   {
-      case 49:
-         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x200L);
-      case 65:
-      case 97:
-         if ((active0 & 0x4000000000000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 62, 965);
-         break;
-      case 67:
-      case 99:
-         if ((active0 & 0x1000000000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 48, 858);
-         return jjMoveStringLiteralDfa4_0(active0, 0x100000000000000L, active1, 0L);
-      case 68:
-      case 100:
-         if ((active1 & 0x4000L) != 0L)
-            return jjStartNfaWithStates_0(3, 78, 965);
-         break;
-      case 69:
-      case 101:
-         if ((active0 & 0x10000000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 40, 965);
-         return jjMoveStringLiteralDfa4_0(active0, 0x2000400006080000L, active1, 0x1000L);
-      case 72:
-      case 104:
-         return jjMoveStringLiteralDfa4_0(active0, 0x8000000L, active1, 0L);
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa4_0(active0, 0x800200000000000L, active1, 0x2000L);
-      case 76:
-      case 108:
-         if ((active0 & 0x20000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 29, 965);
-         else if ((active0 & 0x4000000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 38, 452);
-         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x10L);
-      case 77:
-      case 109:
-         if ((active0 & 0x400000L) != 0L)
-            return jjStartNfaWithStates_0(3, 22, 965);
-         break;
-      case 78:
-      case 110:
-         if ((active0 & 0x40000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 30, 965);
-         else if ((active1 & 0x80000L) != 0L)
-            return jjStartNfaWithStates_0(3, 83, 965);
-         else if ((active1 & 0x100000L) != 0L)
-         {
-            jjmatchedKind = 84;
-            jjmatchedPos = 3;
-         }
-         return jjMoveStringLiteralDfa4_0(active0, 0x220000100000000L, active1, 0x228000L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x80L);
-      case 82:
-      case 114:
-         return jjMoveStringLiteralDfa4_0(active0, 0x8000000200000000L, active1, 0x23L);
-      case 83:
-      case 115:
-         if ((active1 & 0x40000L) != 0L)
-            return jjStartNfaWithStates_0(3, 82, 965);
-         return jjMoveStringLiteralDfa4_0(active0, 0x40000000000L, active1, 0L);
-      case 84:
-      case 116:
-         if ((active0 & 0x10000000L) != 0L)
-            return jjStartNfaWithStates_0(3, 28, 965);
-         else if ((active1 & 0x10000L) != 0L)
-            return jjStartNfaWithStates_0(3, 80, 965);
-         return jjMoveStringLiteralDfa4_0(active0, 0x1080000000000000L, active1, 0x4L);
-      case 85:
-      case 117:
-         return jjMoveStringLiteralDfa4_0(active0, 0x100001000000L, active1, 0L);
-      case 87:
-      case 119:
-         return jjMoveStringLiteralDfa4_0(active0, 0x8000000000L, active1, 0L);
-      case 89:
-      case 121:
-         return jjMoveStringLiteralDfa4_0(active0, 0x400000000000000L, active1, 0L);
-      default :
-         break;
-   }
-   return jjStartNfa_0(2, active0, active1);
-}
-private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(2, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(3, active0, active1);
-      return 4;
-   }
-   switch(curChar)
-   {
-      case 48:
-         if ((active1 & 0x200L) != 0L)
-            return jjStartNfaWithStates_0(4, 73, 28);
-         break;
-      case 50:
-         if ((active1 & 0x200000L) != 0L)
-            return jjStartNfaWithStates_0(4, 85, 28);
-         break;
-      case 65:
-      case 97:
-         return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000000L, active1, 0x2004L);
-      case 67:
-      case 99:
-         return jjMoveStringLiteralDfa5_0(active0, 0x80000L, active1, 0x20000L);
-      case 68:
-      case 100:
-         if ((active1 & 0x8000L) != 0L)
-            return jjStartNfaWithStates_0(4, 79, 965);
-         return jjMoveStringLiteralDfa5_0(active0, 0x8000000000000000L, active1, 0x3L);
-      case 69:
-      case 101:
-         if ((active0 & 0x200000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 33, 965);
-         return jjMoveStringLiteralDfa5_0(active0, 0x8000000000L, active1, 0x20L);
-      case 71:
-      case 103:
-         if ((active0 & 0x100000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 32, 965);
-         return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0L);
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x10L);
-      case 76:
-      case 108:
-         return jjMoveStringLiteralDfa5_0(active0, 0x100000000000000L, active1, 0L);
-      case 78:
-      case 110:
-         return jjMoveStringLiteralDfa5_0(active0, 0x200000000000L, active1, 0L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa5_0(active0, 0x800000000000000L, active1, 0L);
-      case 80:
-      case 112:
-         if ((active0 & 0x100000000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 44, 965);
-         break;
-      case 82:
-      case 114:
-         if ((active0 & 0x2000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 25, 965);
-         else if ((active0 & 0x4000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 26, 965);
-         else if ((active0 & 0x400000000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 46, 965);
-         else if ((active1 & 0x80L) != 0L)
-            return jjStartNfaWithStates_0(4, 71, 965);
-         else if ((active1 & 0x1000L) != 0L)
-            return jjStartNfaWithStates_0(4, 76, 965);
-         return jjMoveStringLiteralDfa5_0(active0, 0x2080000001000000L, active1, 0L);
-      case 84:
-      case 116:
-         if ((active0 & 0x8000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 27, 965);
-         else if ((active0 & 0x20000000000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 53, 965);
-         else if ((active0 & 0x200000000000000L) != 0L)
-            return jjStartNfaWithStates_0(4, 57, 965);
-         return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L);
-      default :
-         break;
-   }
-   return jjStartNfa_0(3, active0, active1);
-}
-private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(3, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(4, active0, active1);
-      return 5;
-   }
-   switch(curChar)
-   {
-      case 49:
-         if ((active0 & 0x8000000000000000L) != 0L)
-            return jjStartNfaWithStates_0(5, 63, 28);
-         break;
-      case 50:
-         if ((active1 & 0x1L) != 0L)
-            return jjStartNfaWithStates_0(5, 64, 28);
-         break;
-      case 65:
-      case 97:
-         return jjMoveStringLiteralDfa6_0(active0, 0x1000000L, active1, 0x20000L);
-      case 69:
-      case 101:
-         if ((active0 & 0x100000000000000L) != 0L)
-            return jjStartNfaWithStates_0(5, 56, 965);
-         return jjMoveStringLiteralDfa6_0(active0, 0x8000000000L, active1, 0x20L);
-      case 71:
-      case 103:
-         if ((active0 & 0x200000000000L) != 0L)
-            return jjStartNfaWithStates_0(5, 45, 965);
-         break;
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa6_0(active0, 0x1000000000000000L, active1, 0L);
-      case 78:
-      case 110:
-         if ((active0 & 0x800000000000000L) != 0L)
-            return jjStartNfaWithStates_0(5, 59, 965);
-         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2014L);
-      case 79:
-      case 111:
-         return jjMoveStringLiteralDfa6_0(active0, 0x480000000000000L, active1, 0L);
-      case 83:
-      case 115:
-         if ((active0 & 0x40000000000L) != 0L)
-            return jjStartNfaWithStates_0(5, 42, 965);
-         return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000000L, active1, 0x2L);
-      case 84:
-      case 116:
-         if ((active0 & 0x80000L) != 0L)
-            return jjStartNfaWithStates_0(5, 19, 965);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(4, active0, active1);
-}
-private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(4, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(5, active0, active1);
-      return 6;
-   }
-   switch(curChar)
-   {
-      case 67:
-      case 99:
-         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x4L);
-      case 69:
-      case 101:
-         return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000000L, active1, 0L);
-      case 71:
-      case 103:
-         if ((active1 & 0x10L) != 0L)
-            return jjStartNfaWithStates_0(6, 68, 965);
-         break;
-      case 73:
-      case 105:
-         return jjMoveStringLiteralDfa7_0(active0, 0x80000000000000L, active1, 0L);
-      case 76:
-      case 108:
-         if ((active0 & 0x1000000L) != 0L)
-            return jjStartNfaWithStates_0(6, 24, 965);
-         break;
-      case 78:
-      case 110:
-         if ((active0 & 0x8000000000L) != 0L)
-            return jjStartNfaWithStates_0(6, 39, 965);
-         else if ((active0 & 0x400000000000000L) != 0L)
-            return jjStartNfaWithStates_0(6, 58, 965);
-         return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000000L, active1, 0L);
-      case 83:
-      case 115:
-         if ((active1 & 0x20L) != 0L)
-            return jjStartNfaWithStates_0(6, 69, 965);
-         else if ((active1 & 0x2000L) != 0L)
-            return jjStartNfaWithStates_0(6, 77, 965);
-         break;
-      case 84:
-      case 116:
-         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x20000L);
-      case 89:
-      case 121:
-         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x2L);
-      default :
-         break;
-   }
-   return jjStartNfa_0(5, active0, active1);
-}
-private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(5, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(6, active0, active1);
-      return 7;
-   }
-   switch(curChar)
-   {
-      case 67:
-      case 99:
-         return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000000L, active1, 0L);
-      case 68:
-      case 100:
-         if ((active0 & 0x80000000000000L) != 0L)
-            return jjStartNfaWithStates_0(7, 55, 965);
-         break;
-      case 69:
-      case 101:
-         if ((active1 & 0x4L) != 0L)
-            return jjStartNfaWithStates_0(7, 66, 965);
-         else if ((active1 & 0x20000L) != 0L)
-            return jjStartNfaWithStates_0(7, 81, 965);
-         break;
-      case 83:
-      case 115:
-         if ((active0 & 0x1000000000000000L) != 0L)
-            return jjStartNfaWithStates_0(7, 60, 965);
-         else if ((active1 & 0x2L) != 0L)
-            return jjStartNfaWithStates_0(7, 65, 965);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(6, active0, active1);
-}
-private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1)
-{
-   if (((active0 &= old0) | (active1 &= old1)) == 0L)
-      return jjStartNfa_0(6, old0, old1);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(7, active0, 0L);
-      return 8;
-   }
-   switch(curChar)
-   {
-      case 84:
-      case 116:
-         return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000000L);
-      default :
-         break;
-   }
-   return jjStartNfa_0(7, active0, 0L);
-}
-private int jjMoveStringLiteralDfa9_0(long old0, long active0)
-{
-   if (((active0 &= old0)) == 0L)
-      return jjStartNfa_0(7, old0, 0L);
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(8, active0, 0L);
-      return 9;
-   }
-   switch(curChar)
-   {
-      case 83:
-      case 115:
-         if ((active0 & 0x2000000000000000L) != 0L)
-            return jjStartNfaWithStates_0(9, 61, 965);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(8, active0, 0L);
-}
-private int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_0(state, pos + 1);
-}
-private int jjMoveNfa_0(int startState, int curPos)
-{
-   int startsAt = 0;
-   jjnewStateCnt = 965;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 590:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 620:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 656:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 373:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 376:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 966:
-                  if ((0x3ff000000000000L & l) != 0L)
-                  {
-                     if (kind > 95)
-                        kind = 95;
-                     jjCheckNAdd(952);
-                  }
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(948, 949);
-                  break;
-               case 303:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 431:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 5:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 168:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 669:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 137:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 324:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 910:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 295:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 33:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 877:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 423:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 908:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 932:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 249:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 821:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 491:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 637:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 967:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 813:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 501:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 481:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 452:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 410:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 372:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 752:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 969:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 859:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 315:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 32:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 52:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 426:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 0:
-                  if ((0x3ff000000000000L & l) != 0L)
-                  {
-                     if (kind > 96)
-                        kind = 96;
-                     jjCheckNAddStates(0, 8);
-                  }
-                  else if ((0x100002600L & l) != 0L)
-                  {
-                     if (kind > 1)
-                        kind = 1;
-                  }
-                  else if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  else if (curChar == 46)
-                     jjCheckNAddTwoStates(948, 952);
-                  else if (curChar == 45)
-                     jjstateSet[jjnewStateCnt++] = 22;
-                  else if (curChar == 60)
-                     jjstateSet[jjnewStateCnt++] = 17;
-                  if (curChar == 33)
-                     jjstateSet[jjnewStateCnt++] = 19;
-                  else if (curChar == 13)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 332:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 377:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 404:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 45:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 717:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 345:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 909:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 378:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 302:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 454:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 416:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 670:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 797:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 482:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 453:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 439:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 396:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 550:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 597:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 471:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 770:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 549:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 430:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 965:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 438:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 801:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 581:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 858:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 472:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 913:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 796:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 427:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 443:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 424:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 900:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 264:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 968:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 113:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 884:
-                  if ((0x83ff001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x8000001a00000000L & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 1:
-                  if (curChar == 10 && kind > 1)
-                     kind = 1;
-                  break;
-               case 2:
-                  if (curChar == 13)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 17:
-                  if (curChar == 62 && kind > 14)
-                     kind = 14;
-                  break;
-               case 18:
-                  if (curChar == 60)
-                     jjstateSet[jjnewStateCnt++] = 17;
-                  break;
-               case 19:
-                  if (curChar == 61 && kind > 14)
-                     kind = 14;
-                  break;
-               case 20:
-                  if (curChar == 33)
-                     jjstateSet[jjnewStateCnt++] = 19;
-                  break;
-               case 21:
-                  if (curChar == 45)
-                     jjstateSet[jjnewStateCnt++] = 22;
-                  break;
-               case 22:
-                  if (curChar != 45)
-                     break;
-                  if (kind > 90)
-                     kind = 90;
-                  jjCheckNAddStates(9, 11);
-                  break;
-               case 23:
-                  if ((0xffffffffffffdbffL & l) == 0L)
-                     break;
-                  if (kind > 90)
-                     kind = 90;
-                  jjCheckNAddStates(9, 11);
-                  break;
-               case 24:
-                  if ((0x2400L & l) != 0L && kind > 90)
-                     kind = 90;
-                  break;
-               case 25:
-                  if (curChar == 10 && kind > 90)
-                     kind = 90;
-                  break;
-               case 26:
-                  if (curChar == 13)
-                     jjstateSet[jjnewStateCnt++] = 25;
-                  break;
-               case 27:
-                  if ((0x8000001a00000000L & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAddTwoStates(27, 28);
-                  break;
-               case 28:
-                  if ((0x83ff001a00000000L & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAdd(28);
-                  break;
-               case 255:
-                  if (curChar == 45)
-                     jjstateSet[jjnewStateCnt++] = 254;
-                  break;
-               case 947:
-                  if (curChar == 46)
-                     jjCheckNAddTwoStates(948, 952);
-                  break;
-               case 948:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(948, 949);
-                  break;
-               case 950:
-                  if ((0x280000000000L & l) != 0L)
-                     jjCheckNAdd(951);
-                  break;
-               case 951:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 94)
-                     kind = 94;
-                  jjCheckNAdd(951);
-                  break;
-               case 952:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 95)
-                     kind = 95;
-                  jjCheckNAdd(952);
-                  break;
-               case 953:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 96)
-                     kind = 96;
-                  jjCheckNAddStates(0, 8);
-                  break;
-               case 954:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(954, 949);
-                  break;
-               case 955:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(955, 956);
-                  break;
-               case 956:
-                  if (curChar == 46)
-                     jjCheckNAddTwoStates(957, 949);
-                  break;
-               case 957:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(957, 949);
-                  break;
-               case 958:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(958, 959);
-                  break;
-               case 959:
-                  if (curChar != 46)
-                     break;
-                  if (kind > 95)
-                     kind = 95;
-                  jjCheckNAdd(960);
-                  break;
-               case 960:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 95)
-                     kind = 95;
-                  jjCheckNAdd(960);
-                  break;
-               case 961:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 96)
-                     kind = 96;
-                  jjCheckNAdd(961);
-                  break;
-               case 962:
-                  if ((0x3ff000000000000L & l) != 0L)
-                     jjCheckNAddTwoStates(962, 963);
-                  break;
-               case 963:
-                  if ((0x8000001a00000000L & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAdd(964);
-                  break;
-               case 964:
-                  if ((0x83ff001a00000000L & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAdd(964);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 590:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 665;
-                  else if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 656;
-                  else if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 649;
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 631;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 628;
-                  else if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 626;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 620;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(34);
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 593;
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 643;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 617;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 589;
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 637;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 607;
-                  if ((0x2000000020000L & l) != 0L)
-                     jjCheckNAdd(280);
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 602;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 597;
-                  break;
-               case 620:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004000000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 656:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 655;
-                  break;
-               case 373:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 385;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 379;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 372;
-                  break;
-               case 376:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 303:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 302;
-                  break;
-               case 431:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 433;
-                  else if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 430;
-                  break;
-               case 5:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 4;
-                  break;
-               case 168:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 167;
-                  break;
-               case 669:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 668;
-                  break;
-               case 137:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 173;
-                  else if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 168;
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 162;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 144;
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 152;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 136;
-                  break;
-               case 324:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 323;
-                  break;
-               case 910:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 945;
-                  else if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 943;
-                  else if ((0x10000000100000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 932;
-                  else if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  else if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  else if ((0x1000000010L & l) != 0L)
-                     jjCheckNAdd(53);
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 913;
-                  else if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 909;
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 923;
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 920;
-                  break;
-               case 295:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 312;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 303;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 300;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 297;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 294;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 309;
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 33:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 45;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 43;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 32;
-                  if ((0x20000000200L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 877:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 901;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 876;
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 884;
-                  break;
-               case 423:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 422;
-                  break;
-               case 908:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 907;
-                  break;
-               case 932:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 931;
-                  break;
-               case 249:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 290;
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 260;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 256;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 248;
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 285;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(53);
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 278;
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 273;
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 271;
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 264;
-                  break;
-               case 821:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 867;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 853;
-                  else if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 849;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 830;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 820;
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 859;
-                  else if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 843;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 825;
-                  if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 835;
-                  break;
-               case 491:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 546;
-                  else if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 542;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 501;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 495;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 535;
-                  else if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(53);
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 527;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 524;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 519;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 513;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 508;
-                  break;
-               case 637:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 648;
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 642;
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 636;
-                  if ((0x100000001000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 967:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x2000000020L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 813:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 902;
-                  else if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 895;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 893;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 868;
-                  else if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(7);
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 889;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 885;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 860;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 812;
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 877;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 854;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 850;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 844;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 836;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 831;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 826;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 821;
-                  break;
-               case 501:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 500;
-                  break;
-               case 481:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 480;
-                  break;
-               case 452:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200L & l) != 0L)
-                     jjCheckNAdd(451);
-                  break;
-               case 410:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 412;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 409;
-                  break;
-               case 372:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 384;
-                  else if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 371;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 378;
-                  break;
-               case 752:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 772;
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 767;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 760;
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 770;
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 764;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 755;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 751;
-                  break;
-               case 969:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 859:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 866;
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 858;
-                  break;
-               case 315:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 324;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 321;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 318;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(34);
-                  if ((0x800000008000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 32:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 31;
-                  break;
-               case 52:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 245;
-                  else if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 190;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 186;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 107;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 104;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 68;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 241;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 175;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 100;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 62;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 231;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 170;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 86;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 60;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 215;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 164;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 77;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 58;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 205;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 154;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 70;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 51;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 195;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 146;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 138;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 133;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 129;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 125;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 118;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 113;
-                  break;
-               case 426:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 425;
-                  break;
-               case 0:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAddStates(12, 22);
-                  else if ((0x1000000010L & l) != 0L)
-                     jjAddStates(23, 39);
-                  else if ((0x80000000800000L & l) != 0L)
-                     jjAddStates(40, 44);
-                  else if ((0x40000000400000L & l) != 0L)
-                     jjAddStates(45, 49);
-                  else if ((0x20000000200000L & l) != 0L)
-                     jjAddStates(50, 56);
-                  else if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAddStates(57, 70);
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjAddStates(71, 87);
-                  else if ((0x4000000040000L & l) != 0L)
-                     jjAddStates(88, 95);
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjAddStates(96, 106);
-                  else if ((0x800000008000L & l) != 0L)
-                     jjCheckNAddStates(107, 113);
-                  else if ((0x400000004000L & l) != 0L)
-                     jjCheckNAddStates(114, 120);
-                  else if ((0x200000002000L & l) != 0L)
-                     jjAddStates(121, 124);
-                  else if ((0x100000001000L & l) != 0L)
-                     jjAddStates(125, 130);
-                  else if ((0x20000000200L & l) != 0L)
-                     jjAddStates(131, 143);
-                  else if ((0x8000000080L & l) != 0L)
-                     jjCheckNAddStates(144, 148);
-                  else if ((0x4000000040L & l) != 0L)
-                     jjAddStates(149, 155);
-                  else if ((0x2000000020L & l) != 0L)
-                     jjAddStates(156, 165);
-                  else if ((0x800000008L & l) != 0L)
-                     jjAddStates(166, 195);
-                  else if ((0x400000004L & l) != 0L)
-                     jjAddStates(196, 199);
-                  else if ((0x400000004000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 15;
-                  else if ((0x200000002000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 11;
-                  else if ((0x80000000800L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 8;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 5;
-                  break;
-               case 332:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 396;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 389;
-                  else if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 338;
-                  else if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 331;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 387;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 381;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 374;
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 368;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 364;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 355;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 352;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 345;
-                  break;
-               case 377:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 376;
-                  break;
-               case 404:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 419;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 413;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 405;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 416;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 410;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 403;
-                  break;
-               case 45:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(36);
-                  break;
-               case 717:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 744;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 741;
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 732;
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 725;
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 716;
-                  break;
-               case 345:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(320);
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 367;
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 354;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 351;
-                  else if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 344;
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 386;
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 363;
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 380;
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 373;
-                  if ((0x10000000100000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 909:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 908;
-                  break;
-               case 378:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 383;
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 377;
-                  break;
-               case 302:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 454:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 458;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 453;
-                  break;
-               case 416:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x80000000800000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 418;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 415;
-                  break;
-               case 670:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 747;
-                  else if ((0x800000008000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 711;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 678;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 676;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 669;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 745;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 698;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 742;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 687;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 733;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 680;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 726;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 717;
-                  break;
-               case 797:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 809;
-                  else if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 806;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 804;
-                  else if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 802;
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 796;
-                  break;
-               case 482:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 481;
-                  break;
-               case 453:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 452;
-                  break;
-               case 439:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 459;
-                  else if ((0x800000008000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 449;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 447;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 444;
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 454;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 438;
-                  break;
-               case 396:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 395;
-                  break;
-               case 550:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 583;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 575;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 581;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 571;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 565;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 559;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 551;
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 549;
-                  break;
-               case 597:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 616;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 601;
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 606;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 596;
-                  break;
-               case 471:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 488;
-                  else if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 482;
-                  else if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 478;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 472;
-                  else if ((0x4000000040L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 470;
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 474;
-                  break;
-               case 770:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(3);
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 769;
-                  break;
-               case 549:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 574;
-                  else if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 570;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 564;
-                  else if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 558;
-                  else if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(280);
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(53);
-                  break;
-               case 430:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 429;
-                  break;
-               case 965:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  break;
-               case 438:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 443;
-                  else if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 437;
-                  break;
-               case 801:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 800;
-                  if ((0x400000004000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 581:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x80000000800000L & l) != 0L)
-                     jjCheckNAdd(156);
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 580;
-                  break;
-               case 858:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 865;
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 857;
-                  break;
-               case 472:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x100000001000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 913:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 912;
-                  break;
-               case 796:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 801;
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 427:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 426;
-                  break;
-               case 443:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 442;
-                  break;
-               case 424:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 434;
-                  else if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 427;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 423;
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 431;
-                  break;
-               case 900:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 899;
-                  break;
-               case 264:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 289;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 277;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 270;
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 284;
-                  else if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(251);
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 263;
-                  break;
-               case 968:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x200000002000000L & l) != 0L)
-                  {
-                     if (kind > 2)
-                        kind = 2;
-                  }
-                  break;
-               case 113:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 185;
-                  else if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 174;
-                  else if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 132;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 128;
-                  else if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 112;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 169;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 124;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 163;
-                  else if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 117;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 153;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 145;
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 137;
-                  break;
-               case 884:
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAdd(28);
-                  }
-                  if ((0x6fffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 101)
-                        kind = 101;
-                     jjCheckNAddTwoStates(27, 28);
-                  }
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 900;
-                  else if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 883;
-                  break;
-               case 3:
-                  if ((0x4000000040000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 4:
-               case 689:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 6:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 5;
-                  break;
-               case 7:
-                  if ((0x200000002000000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 8:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 9:
-                  if ((0x80000000800L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 8;
-                  break;
-               case 10:
-               case 70:
-               case 446:
-               case 782:
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 11:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 10;
-                  break;
-               case 12:
-                  if ((0x200000002000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 11;
-                  break;
-               case 13:
-                  if ((0x2000000020L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 14:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 15:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 14;
-                  break;
-               case 16:
-                  if ((0x400000004000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 15;
-                  break;
-               case 23:
-                  if (kind > 90)
-                     kind = 90;
-                  jjAddStates(9, 11);
-                  break;
-               case 27:
-                  if ((0x6fffffffefffffffL & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAddTwoStates(27, 28);
-                  break;
-               case 28:
-                  if ((0x6fffffffefffffffL & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAdd(28);
-                  break;
-               case 29:
-                  if ((0x400000004L & l) != 0L)
-                     jjAddStates(196, 199);
-                  break;
-               case 30:
-                  if ((0x400000004000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 31:
-               case 887:
-                  if ((0x20000000200L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 34:
-                  if ((0x10000000100000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 35:
-               case 131:
-                  if ((0x20000000200L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 36:
-                  if ((0x10000000100L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 37:
-               case 79:
-               case 88:
-               case 433:
-               case 462:
-               case 804:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(36);
-                  break;
-               case 38:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 37;
-                  break;
-               case 39:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 38;
-                  break;
-               case 40:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 39;
-                  break;
-               case 41:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 40;
-                  break;
-               case 42:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 41;
-                  break;
-               case 43:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 42;
-                  break;
-               case 44:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 43;
-                  break;
-               case 46:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 45;
-                  break;
-               case 47:
-                  if ((0x800000008L & l) != 0L)
-                     jjAddStates(166, 195);
-                  break;
-               case 48:
-               case 634:
-                  if ((0x1000000010L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 49:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 48;
-                  break;
-               case 50:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 49;
-                  break;
-               case 51:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 50;
-                  break;
-               case 53:
-                  if ((0x1000000010L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 54:
-               case 846:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(53);
-                  break;
-               case 55:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 54;
-                  break;
-               case 56:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 55;
-                  break;
-               case 57:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 56;
-                  break;
-               case 58:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 57;
-                  break;
-               case 59:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 58;
-                  break;
-               case 60:
-               case 106:
-               case 248:
-               case 293:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 61:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 60;
-                  break;
-               case 62:
-               case 299:
-               case 405:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 63:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 62;
-                  break;
-               case 64:
-                  if ((0x8000000080L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 65:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(64);
-                  break;
-               case 66:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 65;
-                  break;
-               case 67:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 66;
-                  break;
-               case 68:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 67;
-                  break;
-               case 69:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 68;
-                  break;
-               case 71:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 70;
-                  break;
-               case 72:
-               case 233:
-               case 371:
-               case 418:
-               case 609:
-               case 658:
-               case 766:
-               case 798:
-               case 922:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 73:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 72;
-                  break;
-               case 74:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 73;
-                  break;
-               case 75:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 74;
-                  break;
-               case 76:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 75;
-                  break;
-               case 77:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 76;
-                  break;
-               case 78:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 77;
-                  break;
-               case 80:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 79;
-                  break;
-               case 81:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 80;
-                  break;
-               case 82:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 81;
-                  break;
-               case 83:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 82;
-                  break;
-               case 84:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 83;
-                  break;
-               case 85:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 84;
-                  break;
-               case 86:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 85;
-                  break;
-               case 87:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 86;
-                  break;
-               case 89:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 88;
-                  break;
-               case 90:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 89;
-                  break;
-               case 91:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 90;
-                  break;
-               case 92:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 91;
-                  break;
-               case 93:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 92;
-                  break;
-               case 94:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 93;
-                  break;
-               case 95:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 94;
-                  break;
-               case 96:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 95;
-                  break;
-               case 97:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 96;
-                  break;
-               case 98:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 97;
-                  break;
-               case 99:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 98;
-                  break;
-               case 100:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 99;
-                  break;
-               case 101:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 100;
-                  break;
-               case 102:
-                  if ((0x80000000800L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 103:
-               case 577:
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(102);
-                  break;
-               case 104:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 103;
-                  break;
-               case 105:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 104;
-                  break;
-               case 107:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 106;
-                  break;
-               case 108:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 107;
-                  break;
-               case 109:
-               case 630:
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 110:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 109;
-                  break;
-               case 111:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 110;
-                  break;
-               case 112:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 111;
-                  break;
-               case 114:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 113;
-                  break;
-               case 115:
-               case 188:
-               case 197:
-               case 275:
-               case 333:
-               case 425:
-               case 645:
-               case 700:
-               case 728:
-               case 762:
-               case 808:
-               case 812:
-               case 815:
-               case 852:
-               case 905:
-               case 916:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 116:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 115;
-                  break;
-               case 117:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 116;
-                  break;
-               case 118:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 117;
-                  break;
-               case 119:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 118;
-                  break;
-               case 120:
-               case 140:
-               case 266:
-               case 391:
-               case 476:
-               case 497:
-               case 503:
-               case 599:
-               case 604:
-               case 719:
-               case 735:
-               case 750:
-               case 911:
-               case 927:
-               case 934:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 121:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 120;
-                  break;
-               case 122:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 121;
-                  break;
-               case 123:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 122;
-                  break;
-               case 124:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 123;
-                  break;
-               case 125:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 124;
-                  break;
-               case 126:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 125;
-                  break;
-               case 127:
-                  if ((0x200000002000L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 128:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 127;
-                  break;
-               case 129:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 128;
-                  break;
-               case 130:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 129;
-                  break;
-               case 132:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 131;
-                  break;
-               case 133:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 132;
-                  break;
-               case 134:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 133;
-                  break;
-               case 135:
-               case 287:
-               case 567:
-               case 879:
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 136:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 135;
-                  break;
-               case 138:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 137;
-                  break;
-               case 139:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 138;
-                  break;
-               case 141:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 140;
-                  break;
-               case 142:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 141;
-                  break;
-               case 143:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 142;
-                  break;
-               case 144:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 143;
-                  break;
-               case 145:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 144;
-                  break;
-               case 146:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 145;
-                  break;
-               case 147:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 146;
-                  break;
-               case 148:
-               case 192:
-               case 323:
-               case 622:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 149:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 148;
-                  break;
-               case 150:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 149;
-                  break;
-               case 151:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 150;
-                  break;
-               case 152:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 151;
-                  break;
-               case 153:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 152;
-                  break;
-               case 154:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 153;
-                  break;
-               case 155:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 154;
-                  break;
-               case 156:
-                  if ((0x8000000080000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 157:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(156);
-                  break;
-               case 158:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 157;
-                  break;
-               case 159:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 158;
-                  break;
-               case 160:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 159;
-                  break;
-               case 161:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 160;
-                  break;
-               case 162:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 161;
-                  break;
-               case 163:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 162;
-                  break;
-               case 164:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 163;
-                  break;
-               case 165:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 164;
-                  break;
-               case 166:
-               case 753:
-               case 775:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 167:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 166;
-                  break;
-               case 169:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 168;
-                  break;
-               case 170:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 169;
-                  break;
-               case 171:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 170;
-                  break;
-               case 172:
-               case 366:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 173:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 172;
-                  break;
-               case 174:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 173;
-                  break;
-               case 175:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 174;
-                  break;
-               case 176:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 175;
-                  break;
-               case 177:
-               case 407:
-               case 651:
-               case 713:
-               case 787:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(64);
-                  break;
-               case 178:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 177;
-                  break;
-               case 179:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 178;
-                  break;
-               case 180:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 179;
-                  break;
-               case 181:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 180;
-                  break;
-               case 182:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 181;
-                  break;
-               case 183:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 182;
-                  break;
-               case 184:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 183;
-                  break;
-               case 185:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 184;
-                  break;
-               case 186:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 185;
-                  break;
-               case 187:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 186;
-                  break;
-               case 189:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 188;
-                  break;
-               case 190:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 189;
-                  break;
-               case 191:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 190;
-                  break;
-               case 193:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 192;
-                  break;
-               case 194:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 193;
-                  break;
-               case 195:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 194;
-                  break;
-               case 196:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 195;
-                  break;
-               case 198:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 197;
-                  break;
-               case 199:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 198;
-                  break;
-               case 200:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 199;
-                  break;
-               case 201:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 200;
-                  break;
-               case 202:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 201;
-                  break;
-               case 203:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 202;
-                  break;
-               case 204:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 203;
-                  break;
-               case 205:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 204;
-                  break;
-               case 206:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 205;
-                  break;
-               case 207:
-               case 628:
-               case 680:
-                  if ((0x200000002000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 208:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 207;
-                  break;
-               case 209:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 208;
-                  break;
-               case 210:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 209;
-                  break;
-               case 211:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 210;
-                  break;
-               case 212:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 211;
-                  break;
-               case 213:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 212;
-                  break;
-               case 214:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 213;
-                  break;
-               case 215:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 214;
-                  break;
-               case 216:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 215;
-                  break;
-               case 217:
-                  if ((0x1000000010000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 218:
-               case 682:
-                  if ((0x200000002000L & l) != 0L)
-                     jjCheckNAdd(217);
-                  break;
-               case 219:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 218;
-                  break;
-               case 220:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 219;
-                  break;
-               case 221:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 220;
-                  break;
-               case 222:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 221;
-                  break;
-               case 223:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 222;
-                  break;
-               case 224:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 223;
-                  break;
-               case 225:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 224;
-                  break;
-               case 226:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 225;
-                  break;
-               case 227:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 226;
-                  break;
-               case 228:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 227;
-                  break;
-               case 229:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 228;
-                  break;
-               case 230:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 229;
-                  break;
-               case 231:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 230;
-                  break;
-               case 232:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 231;
-                  break;
-               case 234:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 233;
-                  break;
-               case 235:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 234;
-                  break;
-               case 236:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 235;
-                  break;
-               case 237:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 236;
-                  break;
-               case 238:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 237;
-                  break;
-               case 239:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 238;
-                  break;
-               case 240:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 239;
-                  break;
-               case 241:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 240;
-                  break;
-               case 242:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 241;
-                  break;
-               case 243:
-               case 340:
-               case 526:
-               case 639:
-               case 862:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 244:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 243;
-                  break;
-               case 245:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 244;
-                  break;
-               case 246:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 245;
-                  break;
-               case 247:
-                  if ((0x2000000020L & l) != 0L)
-                     jjAddStates(156, 165);
-                  break;
-               case 250:
-               case 311:
-               case 595:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(53);
-                  break;
-               case 251:
-                  if ((0x800000008L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 252:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(251);
-                  break;
-               case 253:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 252;
-                  break;
-               case 254:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 253;
-                  break;
-               case 256:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 255;
-                  break;
-               case 257:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 256;
-                  break;
-               case 258:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 259:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 258;
-                  break;
-               case 260:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 259;
-                  break;
-               case 261:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 260;
-                  break;
-               case 262:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 263:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 262;
-                  break;
-               case 265:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 264;
-                  break;
-               case 267:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 266;
-                  break;
-               case 268:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 267;
-                  break;
-               case 269:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 268;
-                  break;
-               case 270:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 269;
-                  break;
-               case 271:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 270;
-                  break;
-               case 272:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 271;
-                  break;
-               case 273:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(251);
-                  break;
-               case 274:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 273;
-                  break;
-               case 276:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 275;
-                  break;
-               case 277:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 276;
-                  break;
-               case 278:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 277;
-                  break;
-               case 279:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 278;
-                  break;
-               case 280:
-                  if ((0x100000001000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 281:
-               case 316:
-               case 383:
-               case 415:
-               case 440:
-               case 492:
-               case 823:
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(280);
-                  break;
-               case 282:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 281;
-                  break;
-               case 283:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 282;
-                  break;
-               case 284:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 283;
-                  break;
-               case 285:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 284;
-                  break;
-               case 286:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 285;
-                  break;
-               case 288:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 287;
-                  break;
-               case 289:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 288;
-                  break;
-               case 290:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 289;
-                  break;
-               case 291:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 290;
-                  break;
-               case 292:
-                  if ((0x4000000040L & l) != 0L)
-                     jjAddStates(149, 155);
-                  break;
-               case 294:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 293;
-                  break;
-               case 296:
-               case 422:
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(36);
-                  break;
-               case 297:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 296;
-                  break;
-               case 298:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 297;
-                  break;
-               case 300:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 299;
-                  break;
-               case 301:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 300;
-                  break;
-               case 304:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 303;
-                  break;
-               case 305:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 306:
-                  if ((0x8000000080L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 307:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 306;
-                  break;
-               case 308:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 307;
-                  break;
-               case 309:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 308;
-                  break;
-               case 310:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 309;
-                  break;
-               case 312:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 311;
-                  break;
-               case 313:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 312;
-                  break;
-               case 314:
-                  if ((0x8000000080L & l) != 0L)
-                     jjCheckNAddStates(144, 148);
-                  break;
-               case 317:
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 316;
-                  break;
-               case 318:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 317;
-                  break;
-               case 319:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 318;
-                  break;
-               case 320:
-                  if ((0x800000008000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 321:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(320);
-                  break;
-               case 322:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 321;
-                  break;
-               case 325:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 324;
-                  break;
-               case 326:
-                  if ((0x20000000200L & l) != 0L)
-                     jjAddStates(131, 143);
-                  break;
-               case 327:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 328:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 327;
-                  break;
-               case 329:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 328;
-                  break;
-               case 330:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 329;
-                  break;
-               case 331:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 330;
-                  break;
-               case 334:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 333;
-                  break;
-               case 335:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 334;
-                  break;
-               case 336:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 335;
-                  break;
-               case 337:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 336;
-                  break;
-               case 338:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 337;
-                  break;
-               case 339:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 338;
-                  break;
-               case 341:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 340;
-                  break;
-               case 342:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 341;
-                  break;
-               case 343:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 342;
-                  break;
-               case 344:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 343;
-                  break;
-               case 346:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 345;
-                  break;
-               case 347:
-                  if ((0x100000001000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 348:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 347;
-                  break;
-               case 349:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 348;
-                  break;
-               case 350:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 349;
-                  break;
-               case 351:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 350;
-                  break;
-               case 352:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 351;
-                  break;
-               case 353:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 352;
-                  break;
-               case 354:
-               case 480:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 355:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 354;
-                  break;
-               case 356:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 355;
-                  break;
-               case 357:
-               case 515:
-               case 561:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 358:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 357;
-                  break;
-               case 359:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 358;
-                  break;
-               case 360:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 359;
-                  break;
-               case 361:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 360;
-                  break;
-               case 362:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 361;
-                  break;
-               case 363:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 362;
-                  break;
-               case 364:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 363;
-                  break;
-               case 365:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 364;
-                  break;
-               case 367:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 366;
-                  break;
-               case 368:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 367;
-                  break;
-               case 369:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 368;
-                  break;
-               case 370:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 374:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 373;
-                  break;
-               case 375:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 374;
-                  break;
-               case 379:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 378;
-                  break;
-               case 380:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 379;
-                  break;
-               case 381:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 380;
-                  break;
-               case 382:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 381;
-                  break;
-               case 384:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 383;
-                  break;
-               case 385:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 384;
-                  break;
-               case 386:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 385;
-                  break;
-               case 387:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 386;
-                  break;
-               case 388:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 387;
-                  break;
-               case 389:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAdd(320);
-                  break;
-               case 390:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 389;
-                  break;
-               case 392:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 391;
-                  break;
-               case 393:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 392;
-                  break;
-               case 394:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 393;
-                  break;
-               case 395:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 394;
-                  break;
-               case 397:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 396;
-                  break;
-               case 398:
-                  if ((0x100000001000L & l) != 0L)
-                     jjAddStates(125, 130);
-                  break;
-               case 399:
-               case 769:
-                  if ((0x8000000080L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 400:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 399;
-                  break;
-               case 401:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 400;
-                  break;
-               case 402:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 401;
-                  break;
-               case 403:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 402;
-                  break;
-               case 406:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 405;
-                  break;
-               case 408:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 407;
-                  break;
-               case 409:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 408;
-                  break;
-               case 411:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 410;
-                  break;
-               case 412:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(280);
-                  break;
-               case 413:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 412;
-                  break;
-               case 414:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 413;
-                  break;
-               case 417:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 416;
-                  break;
-               case 419:
-                  if ((0x80000000800000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 418;
-                  break;
-               case 420:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 419;
-                  break;
-               case 421:
-                  if ((0x200000002000L & l) != 0L)
-                     jjAddStates(121, 124);
-                  break;
-               case 428:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 427;
-                  break;
-               case 429:
-               case 668:
-               case 838:
-               case 891:
-                  if ((0x100000001000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 432:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 431;
-                  break;
-               case 434:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 433;
-                  break;
-               case 435:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 434;
-                  break;
-               case 436:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAddStates(114, 120);
-                  break;
-               case 437:
-               case 529:
-               case 553:
-               case 778:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(156);
-                  break;
-               case 441:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 440;
-                  break;
-               case 442:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 441;
-                  break;
-               case 444:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 443;
-                  break;
-               case 445:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 444;
-                  break;
-               case 447:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 446;
-                  break;
-               case 448:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 447;
-                  break;
-               case 449:
-                  if ((0x100000001000000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 450:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 449;
-                  break;
-               case 451:
-                  if ((0x4000000040L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 455:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 454;
-                  break;
-               case 456:
-               case 544:
-                  if ((0x20000000200L & l) != 0L)
-                     jjCheckNAdd(251);
-                  break;
-               case 457:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 456;
-                  break;
-               case 458:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 457;
-                  break;
-               case 459:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 458;
-                  break;
-               case 460:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 459;
-                  break;
-               case 461:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAddStates(107, 113);
-                  break;
-               case 463:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 462;
-                  break;
-               case 464:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 463;
-                  break;
-               case 465:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 464;
-                  break;
-               case 466:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 465;
-                  break;
-               case 467:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 466;
-                  break;
-               case 468:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 467;
-                  break;
-               case 469:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 468;
-                  break;
-               case 470:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 469;
-                  break;
-               case 473:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 472;
-                  break;
-               case 474:
-               case 678:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 475:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 474;
-                  break;
-               case 477:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 476;
-                  break;
-               case 478:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 477;
-                  break;
-               case 479:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 478;
-                  break;
-               case 483:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 482;
-                  break;
-               case 484:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjCheckNAdd(156);
-                  break;
-               case 485:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 484;
-                  break;
-               case 486:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 485;
-                  break;
-               case 487:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 486;
-                  break;
-               case 488:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 487;
-                  break;
-               case 489:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 488;
-                  break;
-               case 490:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjAddStates(96, 106);
-                  break;
-               case 493:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 492;
-                  break;
-               case 494:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 493;
-                  break;
-               case 495:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 494;
-                  break;
-               case 496:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 495;
-                  break;
-               case 498:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 497;
-                  break;
-               case 499:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 498;
-                  break;
-               case 500:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 499;
-                  break;
-               case 502:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 501;
-                  break;
-               case 504:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 503;
-                  break;
-               case 505:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 504;
-                  break;
-               case 506:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 505;
-                  break;
-               case 507:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 506;
-                  break;
-               case 508:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 507;
-                  break;
-               case 509:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 508;
-                  break;
-               case 510:
-               case 537:
-               case 828:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 511:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 510;
-                  break;
-               case 512:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 511;
-                  break;
-               case 513:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 512;
-                  break;
-               case 514:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 513;
-                  break;
-               case 516:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 515;
-                  break;
-               case 517:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 516;
-                  break;
-               case 518:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 517;
-                  break;
-               case 519:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 518;
-                  break;
-               case 520:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 519;
-                  break;
-               case 521:
-               case 671:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 522:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 521;
-                  break;
-               case 523:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 522;
-                  break;
-               case 524:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 523;
-                  break;
-               case 525:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 524;
-                  break;
-               case 527:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 526;
-                  break;
-               case 528:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 527;
-                  break;
-               case 530:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 529;
-                  break;
-               case 531:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 530;
-                  break;
-               case 532:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 531;
-                  break;
-               case 533:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 532;
-                  break;
-               case 534:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 533;
-                  break;
-               case 535:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 534;
-                  break;
-               case 536:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 535;
-                  break;
-               case 538:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 537;
-                  break;
-               case 539:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 538;
-                  break;
-               case 540:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 539;
-                  break;
-               case 541:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 540;
-                  break;
-               case 542:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 541;
-                  break;
-               case 543:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 542;
-                  break;
-               case 545:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 544;
-                  break;
-               case 546:
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 545;
-                  break;
-               case 547:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 546;
-                  break;
-               case 548:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjAddStates(88, 95);
-                  break;
-               case 551:
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(280);
-                  break;
-               case 552:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 551;
-                  break;
-               case 554:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 553;
-                  break;
-               case 555:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 554;
-                  break;
-               case 556:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 555;
-                  break;
-               case 557:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 556;
-                  break;
-               case 558:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 557;
-                  break;
-               case 559:
-                  if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 558;
-                  break;
-               case 560:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 559;
-                  break;
-               case 562:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 561;
-                  break;
-               case 563:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 562;
-                  break;
-               case 564:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 563;
-                  break;
-               case 565:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 564;
-                  break;
-               case 566:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 565;
-                  break;
-               case 568:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 567;
-                  break;
-               case 569:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 568;
-                  break;
-               case 570:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 569;
-                  break;
-               case 571:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 570;
-                  break;
-               case 572:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 571;
-                  break;
-               case 573:
-                  if ((0x80000000800L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 574:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 573;
-                  break;
-               case 575:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 574;
-                  break;
-               case 576:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 575;
-                  break;
-               case 578:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 577;
-                  break;
-               case 579:
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 578;
-                  break;
-               case 580:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 579;
-                  break;
-               case 582:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 581;
-                  break;
-               case 583:
-                  if ((0x80000000800000L & l) != 0L)
-                     jjCheckNAdd(156);
-                  break;
-               case 584:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 583;
-                  break;
-               case 585:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjAddStates(71, 87);
-                  break;
-               case 586:
-                  if ((0x200000002L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 587:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 586;
-                  break;
-               case 588:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 587;
-                  break;
-               case 589:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 588;
-                  break;
-               case 591:
-                  if ((0x100000001000L & l) != 0L)
-                     jjCheckNAdd(280);
-                  break;
-               case 592:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 591;
-                  break;
-               case 593:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 592;
-                  break;
-               case 594:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 593;
-                  break;
-               case 596:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 595;
-                  break;
-               case 598:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 597;
-                  break;
-               case 600:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 599;
-                  break;
-               case 601:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 600;
-                  break;
-               case 602:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 601;
-                  break;
-               case 603:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 602;
-                  break;
-               case 605:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 604;
-                  break;
-               case 606:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 605;
-                  break;
-               case 607:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 606;
-                  break;
-               case 608:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 607;
-                  break;
-               case 610:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 609;
-                  break;
-               case 611:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 610;
-                  break;
-               case 612:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 611;
-                  break;
-               case 613:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 612;
-                  break;
-               case 614:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 613;
-                  break;
-               case 615:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 614;
-                  break;
-               case 616:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 615;
-                  break;
-               case 617:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 616;
-                  break;
-               case 618:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 617;
-                  break;
-               case 619:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 621:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 620;
-                  break;
-               case 623:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 622;
-                  break;
-               case 624:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 623;
-                  break;
-               case 625:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 624;
-                  break;
-               case 626:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 625;
-                  break;
-               case 627:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 626;
-                  break;
-               case 629:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 628;
-                  break;
-               case 631:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 630;
-                  break;
-               case 632:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 631;
-                  break;
-               case 633:
-                  if ((0x2000000020000L & l) != 0L)
-                     jjCheckNAdd(280);
-                  break;
-               case 635:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 634;
-                  break;
-               case 636:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 635;
-                  break;
-               case 638:
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 637;
-                  break;
-               case 640:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 639;
-                  break;
-               case 641:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 640;
-                  break;
-               case 642:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 641;
-                  break;
-               case 643:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 642;
-                  break;
-               case 644:
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 643;
-                  break;
-               case 646:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 645;
-                  break;
-               case 647:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 646;
-                  break;
-               case 648:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 647;
-                  break;
-               case 649:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 648;
-                  break;
-               case 650:
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 649;
-                  break;
-               case 652:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 651;
-                  break;
-               case 653:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 652;
-                  break;
-               case 654:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 653;
-                  break;
-               case 655:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 654;
-                  break;
-               case 657:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 656;
-                  break;
-               case 659:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 658;
-                  break;
-               case 660:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 659;
-                  break;
-               case 661:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 660;
-                  break;
-               case 662:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 661;
-                  break;
-               case 663:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 662;
-                  break;
-               case 664:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 663;
-                  break;
-               case 665:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 664;
-                  break;
-               case 666:
-                  if ((0x200000002000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 665;
-                  break;
-               case 667:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjCheckNAddStates(57, 70);
-                  break;
-               case 672:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 671;
-                  break;
-               case 673:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 672;
-                  break;
-               case 674:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 673;
-                  break;
-               case 675:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 674;
-                  break;
-               case 676:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 675;
-                  break;
-               case 677:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 676;
-                  break;
-               case 679:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 678;
-                  break;
-               case 681:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 680;
-                  break;
-               case 683:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 682;
-                  break;
-               case 684:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 683;
-                  break;
-               case 685:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 684;
-                  break;
-               case 686:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 685;
-                  break;
-               case 687:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 686;
-                  break;
-               case 688:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 687;
-                  break;
-               case 690:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 689;
-                  break;
-               case 691:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 690;
-                  break;
-               case 692:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 691;
-                  break;
-               case 693:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 692;
-                  break;
-               case 694:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 693;
-                  break;
-               case 695:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 694;
-                  break;
-               case 696:
-                  if ((0x400000004000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 695;
-                  break;
-               case 697:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 696;
-                  break;
-               case 698:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 697;
-                  break;
-               case 699:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 698;
-                  break;
-               case 701:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 700;
-                  break;
-               case 702:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 701;
-                  break;
-               case 703:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 702;
-                  break;
-               case 704:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 703;
-                  break;
-               case 705:
-                  if (curChar == 95)
-                     jjstateSet[jjnewStateCnt++] = 704;
-                  break;
-               case 706:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 705;
-                  break;
-               case 707:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 706;
-                  break;
-               case 708:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 707;
-                  break;
-               case 709:
-                  if ((0x400000004000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 708;
-                  break;
-               case 710:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 709;
-                  break;
-               case 711:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 710;
-                  break;
-               case 712:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 711;
-                  break;
-               case 714:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 713;
-                  break;
-               case 715:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 714;
-                  break;
-               case 716:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 715;
-                  break;
-               case 718:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 717;
-                  break;
-               case 720:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 719;
-                  break;
-               case 721:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 720;
-                  break;
-               case 722:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 721;
-                  break;
-               case 723:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 722;
-                  break;
-               case 724:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 723;
-                  break;
-               case 725:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 724;
-                  break;
-               case 726:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 725;
-                  break;
-               case 727:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 726;
-                  break;
-               case 729:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 728;
-                  break;
-               case 730:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 729;
-                  break;
-               case 731:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 730;
-                  break;
-               case 732:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 731;
-                  break;
-               case 733:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 732;
-                  break;
-               case 734:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 733;
-                  break;
-               case 736:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 735;
-                  break;
-               case 737:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 736;
-                  break;
-               case 738:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 737;
-                  break;
-               case 739:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 738;
-                  break;
-               case 740:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 739;
-                  break;
-               case 741:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 740;
-                  break;
-               case 742:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 741;
-                  break;
-               case 743:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 742;
-                  break;
-               case 744:
-                  if ((0x200000002000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 745:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 744;
-                  break;
-               case 746:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 745;
-                  break;
-               case 747:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 748:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 747;
-                  break;
-               case 749:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjAddStates(50, 56);
-                  break;
-               case 751:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 750;
-                  break;
-               case 754:
-                  if ((0x2000000020000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 753;
-                  break;
-               case 755:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 754;
-                  break;
-               case 756:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 755;
-                  break;
-               case 757:
-                  if ((0x80000000800000L & l) != 0L)
-                     jjCheckNAdd(30);
-                  break;
-               case 758:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 757;
-                  break;
-               case 759:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 758;
-                  break;
-               case 760:
-                  if ((0x80000000800L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 759;
-                  break;
-               case 761:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 760;
-                  break;
-               case 763:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 762;
-                  break;
-               case 764:
-                  if ((0x1000000010L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 763;
-                  break;
-               case 765:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 764;
-                  break;
-               case 767:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 766;
-                  break;
-               case 768:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 767;
-                  break;
-               case 771:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 770;
-                  break;
-               case 772:
-                  if ((0x2000000020L & l) != 0L)
-                     jjCheckNAdd(3);
-                  break;
-               case 773:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 772;
-                  break;
-               case 774:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjAddStates(45, 49);
-                  break;
-               case 776:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 775;
-                  break;
-               case 777:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 776;
-                  break;
-               case 779:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 778;
-                  break;
-               case 780:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 779;
-                  break;
-               case 781:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 780;
-                  break;
-               case 783:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 782;
-                  break;
-               case 784:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 783;
-                  break;
-               case 785:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 784;
-                  break;
-               case 786:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 785;
-                  break;
-               case 788:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 787;
-                  break;
-               case 789:
-                  if ((0x200000002000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 788;
-                  break;
-               case 790:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 789;
-                  break;
-               case 791:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 790;
-                  break;
-               case 792:
-                  if ((0x80000000800000L & l) != 0L && kind > 2)
-                     kind = 2;
-                  break;
-               case 793:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 792;
-                  break;
-               case 794:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 793;
-                  break;
-               case 795:
-                  if ((0x80000000800000L & l) != 0L)
-                     jjAddStates(40, 44);
-                  break;
-               case 799:
-                  if ((0x40000000400000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 798;
-                  break;
-               case 800:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 799;
-                  break;
-               case 802:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 801;
-                  break;
-               case 803:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 802;
-                  break;
-               case 805:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 804;
-                  break;
-               case 806:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(102);
-                  break;
-               case 807:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 806;
-                  break;
-               case 809:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 808;
-                  break;
-               case 810:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 809;
-                  break;
-               case 811:
-                  if ((0x1000000010L & l) != 0L)
-                     jjAddStates(23, 39);
-                  break;
-               case 814:
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 816:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 815;
-                  break;
-               case 817:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 816;
-                  break;
-               case 818:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 817;
-                  break;
-               case 819:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 818;
-                  break;
-               case 820:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 819;
-                  break;
-               case 822:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 821;
-                  break;
-               case 824:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 823;
-                  break;
-               case 825:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 824;
-                  break;
-               case 826:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 825;
-                  break;
-               case 827:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 826;
-                  break;
-               case 829:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 828;
-                  break;
-               case 830:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 829;
-                  break;
-               case 831:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 830;
-                  break;
-               case 832:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 831;
-                  break;
-               case 833:
-                  if ((0x100000001000L & l) != 0L)
-                     jjCheckNAdd(34);
-                  break;
-               case 834:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 833;
-                  break;
-               case 835:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 834;
-                  break;
-               case 836:
-                  if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 835;
-                  break;
-               case 837:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 836;
-                  break;
-               case 839:
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 838;
-                  break;
-               case 840:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 839;
-                  break;
-               case 841:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 840;
-                  break;
-               case 842:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 841;
-                  break;
-               case 843:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 842;
-                  break;
-               case 844:
-                  if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 843;
-                  break;
-               case 845:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 844;
-                  break;
-               case 847:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 846;
-                  break;
-               case 848:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 847;
-                  break;
-               case 849:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 848;
-                  break;
-               case 850:
-                  if ((0x4000000040L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 849;
-                  break;
-               case 851:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 850;
-                  break;
-               case 853:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 852;
-                  break;
-               case 854:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 853;
-                  break;
-               case 855:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 854;
-                  break;
-               case 856:
-                  if ((0x400000004L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 857:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 856;
-                  break;
-               case 860:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 859;
-                  break;
-               case 861:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 860;
-                  break;
-               case 863:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 862;
-                  break;
-               case 864:
-                  if ((0x1000000010000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 863;
-                  break;
-               case 865:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 864;
-                  break;
-               case 866:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 865;
-                  break;
-               case 867:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 866;
-                  break;
-               case 868:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 867;
-                  break;
-               case 869:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 868;
-                  break;
-               case 870:
-                  if ((0x800000008L & l) != 0L)
-                     jjCheckNAdd(156);
-                  break;
-               case 871:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 870;
-                  break;
-               case 872:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 871;
-                  break;
-               case 873:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 872;
-                  break;
-               case 874:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 873;
-                  break;
-               case 875:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 874;
-                  break;
-               case 876:
-                  if ((0x8000000080L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 875;
-                  break;
-               case 878:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 877;
-                  break;
-               case 880:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 879;
-                  break;
-               case 881:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 880;
-                  break;
-               case 882:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 881;
-                  break;
-               case 883:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 882;
-                  break;
-               case 885:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 884;
-                  break;
-               case 886:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 885;
-                  break;
-               case 888:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 887;
-                  break;
-               case 889:
-                  if ((0x200000002000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 888;
-                  break;
-               case 890:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 889;
-                  break;
-               case 892:
-                  if ((0x400000004L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 891;
-                  break;
-               case 893:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 892;
-                  break;
-               case 894:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 893;
-                  break;
-               case 895:
-                  if ((0x800000008000L & l) != 0L)
-                     jjCheckNAdd(217);
-                  break;
-               case 896:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 895;
-                  break;
-               case 897:
-                  if ((0x10000000100000L & l) != 0L && kind > 20)
-                     kind = 20;
-                  break;
-               case 898:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 897;
-                  break;
-               case 899:
-                  if ((0x400000004000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 898;
-                  break;
-               case 901:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 900;
-                  break;
-               case 902:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 901;
-                  break;
-               case 903:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 902;
-                  break;
-               case 904:
-                  if ((0x200000002L & l) != 0L)
-                     jjCheckNAddStates(12, 22);
-                  break;
-               case 906:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 905;
-                  break;
-               case 907:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 906;
-                  break;
-               case 912:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 911;
-                  break;
-               case 914:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 913;
-                  break;
-               case 915:
-                  if ((0x1000000010L & l) != 0L)
-                     jjCheckNAdd(53);
-                  break;
-               case 917:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 916;
-                  break;
-               case 918:
-                  if ((0x800000008L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 917;
-                  break;
-               case 919:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 918;
-                  break;
-               case 920:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 919;
-                  break;
-               case 921:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 920;
-                  break;
-               case 923:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 922;
-                  break;
-               case 924:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 923;
-                  break;
-               case 925:
-                  if ((0x400000004000L & l) != 0L)
-                     jjCheckNAdd(7);
-                  break;
-               case 926:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjCheckNAdd(13);
-                  break;
-               case 928:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 927;
-                  break;
-               case 929:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 928;
-                  break;
-               case 930:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 929;
-                  break;
-               case 931:
-                  if ((0x2000000020L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 930;
-                  break;
-               case 933:
-                  if ((0x8000000080000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 932;
-                  break;
-               case 935:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 934;
-                  break;
-               case 936:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 935;
-                  break;
-               case 937:
-                  if ((0x200000002L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 936;
-                  break;
-               case 938:
-                  if ((0x400000004000000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 937;
-                  break;
-               case 939:
-                  if ((0x20000000200L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 938;
-                  break;
-               case 940:
-                  if ((0x4000000040000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 939;
-                  break;
-               case 941:
-                  if ((0x800000008000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 940;
-                  break;
-               case 942:
-                  if ((0x10000000100L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 941;
-                  break;
-               case 943:
-                  if ((0x10000000100000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 942;
-                  break;
-               case 944:
-                  if ((0x20000000200000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 943;
-                  break;
-               case 945:
-                  if ((0x100000001000L & l) != 0L && kind > 20)
-                     kind = 20;
-                  break;
-               case 946:
-                  if ((0x100000001000L & l) != 0L)
-                     jjstateSet[jjnewStateCnt++] = 945;
-                  break;
-               case 949:
-                  if ((0x2000000020L & l) != 0L)
-                     jjAddStates(200, 201);
-                  break;
-               case 963:
-               case 964:
-                  if ((0x6fffffffefffffffL & l) == 0L)
-                     break;
-                  if (kind > 101)
-                     kind = 101;
-                  jjCheckNAdd(964);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 23:
-                  if ((jjbitVec0[i2] & l2) == 0L)
-                     break;
-                  if (kind > 90)
-                     kind = 90;
-                  jjAddStates(9, 11);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 965 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_1(int pos, long active0, long active1)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_1(int pos, long active0, long active1)
-{
-   return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0, active1), pos + 1);
-}
-private int jjMoveStringLiteralDfa0_1()
-{
-   switch(curChar)
-   {
-      case 39:
-         return jjStartNfaWithStates_1(0, 93, 1);
-      default :
-         return jjMoveNfa_1(0, 0);
-   }
-}
-private int jjStartNfaWithStates_1(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_1(state, pos + 1);
-}
-private int jjMoveNfa_1(int startState, int curPos)
-{
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0xffffff7fffffffffL & l) != 0L)
-                  {
-                     if (kind > 92)
-                        kind = 92;
-                  }
-                  else if (curChar == 39)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (curChar == 39 && kind > 92)
-                     kind = 92;
-                  break;
-               case 2:
-                  if (curChar == 39)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  kind = 92;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 92)
-                     kind = 92;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-static final int[] jjnextStates = {
-   954, 955, 956, 949, 958, 959, 961, 962, 963, 23, 24, 26, 910, 914, 915, 921, 
-   924, 925, 926, 933, 34, 944, 946, 813, 814, 822, 827, 832, 837, 845, 851, 855, 
-   861, 869, 878, 886, 890, 894, 896, 903, 797, 803, 805, 807, 810, 777, 781, 786, 
-   791, 794, 752, 756, 761, 765, 768, 771, 773, 670, 677, 679, 681, 688, 699, 712, 
-   320, 718, 727, 734, 743, 746, 748, 590, 594, 598, 603, 608, 618, 619, 621, 627, 
-   629, 632, 633, 638, 644, 650, 657, 666, 550, 552, 560, 566, 572, 576, 582, 584, 
-   491, 496, 502, 509, 514, 520, 525, 528, 536, 543, 547, 471, 451, 473, 475, 479, 
-   483, 489, 439, 445, 448, 450, 320, 455, 460, 424, 428, 432, 435, 404, 406, 411, 
-   414, 417, 420, 332, 339, 346, 353, 356, 365, 369, 370, 375, 382, 388, 390, 397, 
-   315, 319, 320, 322, 325, 295, 298, 301, 304, 305, 310, 313, 249, 250, 257, 261, 
-   265, 272, 274, 279, 286, 291, 52, 59, 61, 63, 69, 71, 78, 87, 101, 105, 
-   108, 114, 119, 126, 130, 134, 139, 147, 155, 165, 171, 176, 187, 191, 196, 206, 
-   216, 232, 242, 246, 33, 35, 44, 46, 950, 951, 
-};
-
-/** Token literal values. */
-public static final String[] jjstrLiteralImages = {
-"", null, null, "\50", "\51", "\56", "\54", "\73", "\174\174", "\53", "\55", 
-"\52", "\57", "\75", null, "\74", "\74\75", "\76", "\76\75", null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, };
-
-/** Lexer state names. */
-public static final String[] lexStateNames = {
-   "DEFAULT",
-   "WithinString",
-   "WithinDelimitedId",
-};
-
-/** Lex State array. */
-public static final int[] jjnewLexState = {
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 0, -1, -1, -1, -1, 2, -1, 
-   0, -1, -1, 
-};
-static final long[] jjtoToken = {
-   0xfffffffffffffffdL, 0x31e3ffffffL, 
-};
-static final long[] jjtoSkip = {
-   0x2L, 0x4000000L, 
-};
-static final long[] jjtoMore = {
-   0x0L, 0xc18000000L, 
-};
-protected SimpleCharStream input_stream;
-private final int[] jjrounds = new int[965];
-private final int[] jjstateSet = new int[1930];
-protected char curChar;
-/** Constructor. */
-public ADQLParserTokenManager(SimpleCharStream stream){
-   if (SimpleCharStream.staticFlag)
-      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
-   input_stream = stream;
-}
-
-/** Constructor. */
-public ADQLParserTokenManager(SimpleCharStream stream, int lexState){
-   this(stream);
-   SwitchTo(lexState);
-}
-
-/** Reinitialise parser. */
-public void ReInit(SimpleCharStream stream)
-{
-   jjmatchedPos = jjnewStateCnt = 0;
-   curLexState = defaultLexState;
-   input_stream = stream;
-   ReInitRounds();
-}
-private void ReInitRounds()
-{
-   int i;
-   jjround = 0x80000001;
-   for (i = 965; i-- > 0;)
-      jjrounds[i] = 0x80000000;
-}
-
-/** Reinitialise parser. */
-public void ReInit(SimpleCharStream stream, int lexState)
-{
-   ReInit(stream);
-   SwitchTo(lexState);
-}
-
-/** Switch to specified lex state. */
-public void SwitchTo(int lexState)
-{
-   if (lexState >= 3 || lexState < 0)
-      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-   else
-      curLexState = lexState;
-}
-
-protected Token jjFillToken()
-{
-   final Token t;
-   final String curTokenImage;
-   final int beginLine;
-   final int endLine;
-   final int beginColumn;
-   final int endColumn;
-   String im = jjstrLiteralImages[jjmatchedKind];
-   curTokenImage = (im == null) ? input_stream.GetImage() : im;
-   beginLine = input_stream.getBeginLine();
-   beginColumn = input_stream.getBeginColumn();
-   endLine = input_stream.getEndLine();
-   endColumn = input_stream.getEndColumn();
-   t = Token.newToken(jjmatchedKind, curTokenImage);
-
-   t.beginLine = beginLine;
-   t.endLine = endLine;
-   t.beginColumn = beginColumn;
-   t.endColumn = endColumn;
-
-   return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-/** Get the next Token. */
-public Token getNextToken() 
-{
-  Token matchedToken;
-  int curPos = 0;
-
-  EOFLoop :
-  for (;;)
-  {
-   try
-   {
-      curChar = input_stream.BeginToken();
-   }
-   catch(java.io.IOException e)
-   {
-      jjmatchedKind = 0;
-      matchedToken = jjFillToken();
-      return matchedToken;
-   }
-
-   for (;;)
-   {
-     switch(curLexState)
-     {
-       case 0:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_0();
-         break;
-       case 1:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_1();
-         break;
-       case 2:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_2();
-         break;
-     }
-     if (jjmatchedKind != 0x7fffffff)
-     {
-        if (jjmatchedPos + 1 < curPos)
-           input_stream.backup(curPos - jjmatchedPos - 1);
-        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           matchedToken = jjFillToken();
-       if (jjnewLexState[jjmatchedKind] != -1)
-         curLexState = jjnewLexState[jjmatchedKind];
-           return matchedToken;
-        }
-        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-         if (jjnewLexState[jjmatchedKind] != -1)
-           curLexState = jjnewLexState[jjmatchedKind];
-           continue EOFLoop;
-        }
-      if (jjnewLexState[jjmatchedKind] != -1)
-        curLexState = jjnewLexState[jjmatchedKind];
-        curPos = 0;
-        jjmatchedKind = 0x7fffffff;
-        try {
-           curChar = input_stream.readChar();
-           continue;
-        }
-        catch (java.io.IOException e1) { }
-     }
-     int error_line = input_stream.getEndLine();
-     int error_column = input_stream.getEndColumn();
-     String error_after = null;
-     boolean EOFSeen = false;
-     try { input_stream.readChar(); input_stream.backup(1); }
-     catch (java.io.IOException e1) {
-        EOFSeen = true;
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-        if (curChar == '\n' || curChar == '\r') {
-           error_line++;
-           error_column = 0;
-        }
-        else
-           error_column++;
-     }
-     if (!EOFSeen) {
-        input_stream.backup(1);
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-     }
-     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-   }
-  }
-}
-
-private void jjCheckNAdd(int state)
-{
-   if (jjrounds[state] != jjround)
-   {
-      jjstateSet[jjnewStateCnt++] = state;
-      jjrounds[state] = jjround;
-   }
-}
-private void jjAddStates(int start, int end)
-{
-   do {
-      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-   } while (start++ != end);
-}
-private void jjCheckNAddTwoStates(int state1, int state2)
-{
-   jjCheckNAdd(state1);
-   jjCheckNAdd(state2);
-}
-
-private void jjCheckNAddStates(int start, int end)
-{
-   do {
-      jjCheckNAdd(jjnextStates[start]);
-   } while (start++ != end);
-}
-
-}
diff --git a/src/adql/parser/ADQLQueryFactory.java b/src/adql/parser/ADQLQueryFactory.java
index b6f8e445d9785534de21b11035e47f770dcff82d..655b32fd125f04772bef8e4ddb16acfaa11060ea 100644
--- a/src/adql/parser/ADQLQueryFactory.java
+++ b/src/adql/parser/ADQLQueryFactory.java
@@ -2,21 +2,21 @@ package adql.parser;
 
 /*
  * This file is part of ADQLLibrary.
- * 
+ *
  * ADQLLibrary is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * ADQLLibrary is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public License
  * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *
+ * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -76,41 +76,46 @@ import adql.query.operand.function.geometry.IntersectsFunction;
 import adql.query.operand.function.geometry.PointFunction;
 import adql.query.operand.function.geometry.PolygonFunction;
 import adql.query.operand.function.geometry.RegionFunction;
+import adql.query.operand.function.string.LowerFunction;
 
 /**
- * <p>This class lets the {@link ADQLParser} to build an object representation of an ADQL query.</p>
- * 
- * <p>To customize the object representation you merely have to extends the appropriate functions of this class.</p>
- * 
+ * This class lets the {@link ADQLParser} to build an object representation of
+ * an ADQL query.
+ *
+ * <p>
+ * 	To customize the object representation you merely have to extends the
+ * 	appropriate functions of this class.
+ * </p>
+ *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.4 (04/2017)
- * 
+ * @version 2.0 (04/2019)
+ *
  * @see ADQLParser
  */
 public class ADQLQueryFactory {
 
 	/**
 	 * Type of table JOIN.
-	 * 
+	 *
 	 * @author Gr&eacute;gory Mantelet (CDS)
 	 * @version 1.0 (08/2011)
 	 */
-	public static enum JoinType{
+	public static enum JoinType {
 		CROSS, INNER, OUTER_LEFT, OUTER_RIGHT, OUTER_FULL;
 	}
 
 	/**
 	 * Create a query factory.
 	 */
-	public ADQLQueryFactory(){
+	public ADQLQueryFactory() {
 		;
 	}
 
-	public ADQLQuery createQuery() throws Exception{
+	public ADQLQuery createQuery() throws Exception {
 		return new ADQLQuery();
 	}
 
-	public ADQLTable createTable(final IdentifierItems idItems, final IdentifierItem alias) throws Exception{
+	public ADQLTable createTable(final IdentifierItems idItems, final IdentifierItem alias) throws Exception {
 		ADQLTable t = new ADQLTable(idItems.getCatalog(), idItems.getSchema(), idItems.getTable());
 
 		// Set the table alias:
@@ -126,10 +131,10 @@ public class ADQLQueryFactory {
 		return t;
 	}
 
-	public ADQLTable createTable(ADQLQuery query, IdentifierItem alias) throws Exception{
+	public ADQLTable createTable(ADQLQuery query, IdentifierItem alias) throws Exception {
 		ADQLTable t = new ADQLTable(query);
 
-		if (alias != null){
+		if (alias != null) {
 			// Set the table alias:
 			t.setAlias(alias.identifier);
 			// Set the case sensitivity:
@@ -139,8 +144,8 @@ public class ADQLQueryFactory {
 		return t;
 	}
 
-	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable) throws Exception{
-		switch(type){
+	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable) throws Exception {
+		switch(type) {
 			case CROSS:
 				return new CrossJoin(leftTable, rightTable);
 			case INNER:
@@ -156,8 +161,8 @@ public class ADQLQueryFactory {
 		}
 	}
 
-	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable, ClauseConstraints condition) throws Exception{
-		switch(type){
+	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable, ClauseConstraints condition) throws Exception {
+		switch(type) {
 			case CROSS:
 				throw new Exception("A cross join must have no condition (that's to say: no part ON) !");
 			default:
@@ -167,8 +172,8 @@ public class ADQLQueryFactory {
 		}
 	}
 
-	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable, Collection<ADQLColumn> lstColumns) throws Exception{
-		switch(type){
+	public ADQLJoin createJoin(JoinType type, FromContent leftTable, FromContent rightTable, Collection<ADQLColumn> lstColumns) throws Exception {
+		switch(type) {
 			case CROSS:
 				throw new Exception("A cross join must have no columns list (that's to say: no part USING) !");
 			default:
@@ -178,11 +183,11 @@ public class ADQLQueryFactory {
 		}
 	}
 
-	public SelectItem createSelectItem(ADQLOperand operand, String alias) throws Exception{
+	public SelectItem createSelectItem(ADQLOperand operand, String alias) throws Exception {
 		return new SelectItem(operand, alias);
 	}
 
-	public ADQLColumn createColumn(final IdentifierItems idItems) throws Exception{
+	public ADQLColumn createColumn(final IdentifierItems idItems) throws Exception {
 		ADQLColumn col = new ADQLColumn(idItems.getCatalog(), idItems.getSchema(), idItems.getTable(), idItems.getColumn());
 
 		// Set the case sensitivity:
@@ -194,7 +199,7 @@ public class ADQLQueryFactory {
 		return col;
 	}
 
-	public ADQLColumn createColumn(final IdentifierItem columnName) throws Exception{
+	public ADQLColumn createColumn(final IdentifierItem columnName) throws Exception {
 		ADQLColumn col = new ADQLColumn(null, null, null, columnName.identifier);
 
 		// Set the case sensitivity:
@@ -205,182 +210,194 @@ public class ADQLQueryFactory {
 		return col;
 	}
 
-	public NumericConstant createNumericConstant(String value) throws Exception{
+	public NumericConstant createNumericConstant(String value) throws Exception {
 		return new NumericConstant(value, true);
 	}
 
-	public StringConstant createStringConstant(String value) throws Exception{
+	public StringConstant createStringConstant(String value) throws Exception {
 		return new StringConstant(value);
 	}
 
-	public Operation createOperation(ADQLOperand leftOp, OperationType op, ADQLOperand rightOp) throws Exception{
+	public Operation createOperation(ADQLOperand leftOp, OperationType op, ADQLOperand rightOp) throws Exception {
 		return new Operation(leftOp, op, rightOp);
 	}
 
-	public NegativeOperand createNegativeOperand(ADQLOperand opToNegativate) throws Exception{
+	public NegativeOperand createNegativeOperand(ADQLOperand opToNegativate) throws Exception {
 		return new NegativeOperand(opToNegativate);
 	}
 
-	public Concatenation createConcatenation() throws Exception{
+	public Concatenation createConcatenation() throws Exception {
 		return new Concatenation();
 	}
 
-	public WrappedOperand createWrappedOperand(ADQLOperand opToWrap) throws Exception{
+	public WrappedOperand createWrappedOperand(ADQLOperand opToWrap) throws Exception {
 		return new WrappedOperand(opToWrap);
 	}
 
-	public ConstraintsGroup createGroupOfConstraints() throws Exception{
+	public ConstraintsGroup createGroupOfConstraints() throws Exception {
 		return new ConstraintsGroup();
 	}
 
-	public NotConstraint createNot(ADQLConstraint constraintToNot) throws Exception{
+	public NotConstraint createNot(ADQLConstraint constraintToNot) throws Exception {
 		return new NotConstraint(constraintToNot);
 	}
 
-	public Comparison createComparison(ADQLOperand leftOp, ComparisonOperator op, ADQLOperand rightOp) throws Exception{
+	public Comparison createComparison(ADQLOperand leftOp, ComparisonOperator op, ADQLOperand rightOp) throws Exception {
 		return new Comparison(leftOp, op, rightOp);
 	}
 
-	public Between createBetween(boolean not, ADQLOperand value, ADQLOperand min, ADQLOperand max) throws Exception{
+	public Between createBetween(boolean not, ADQLOperand value, ADQLOperand min, ADQLOperand max) throws Exception {
 		return new Between(value, min, max, not);
 	}
 
-	public IsNull createIsNull(boolean notNull, ADQLColumn column) throws Exception{
+	public IsNull createIsNull(boolean notNull, ADQLColumn column) throws Exception {
 		return new IsNull(column, notNull);
 	}
 
-	public Exists createExists(ADQLQuery query) throws Exception{
+	public Exists createExists(ADQLQuery query) throws Exception {
 		return new Exists(query);
 	}
 
-	public In createIn(ADQLOperand leftOp, ADQLQuery query, boolean notIn) throws Exception{
+	public In createIn(ADQLOperand leftOp, ADQLQuery query, boolean notIn) throws Exception {
 		return new In(leftOp, query, notIn);
 	}
 
-	public In createIn(ADQLOperand leftOp, ADQLOperand[] valuesList, boolean notIn) throws Exception{
+	public In createIn(ADQLOperand leftOp, ADQLOperand[] valuesList, boolean notIn) throws Exception {
 		return new In(leftOp, valuesList, notIn);
 	}
 
-	public SQLFunction createSQLFunction(SQLFunctionType type, ADQLOperand op, boolean distinctValues) throws Exception{
+	public SQLFunction createSQLFunction(SQLFunctionType type, ADQLOperand op, boolean distinctValues) throws Exception {
 		return new SQLFunction(type, op, distinctValues);
 	}
 
-	public MathFunction createMathFunction(MathFunctionType type, ADQLOperand param1, ADQLOperand param2) throws Exception{
+	/** @since 2.0 */
+	public LowerFunction createLowerFunction(ADQLOperand op) throws Exception {
+		return new LowerFunction(op);
+	}
+
+	public MathFunction createMathFunction(MathFunctionType type, ADQLOperand param1, ADQLOperand param2) throws Exception {
 		return new MathFunction(type, param1, param2);
 	}
 
 	/**
-	 * <p>Creates the user defined functions called as the given name and with the given parameters.</p>
-	 * 
+	 * Creates the user defined functions called as the given name and with
+	 * the given parameters.
+	 *
 	 * <p>
-	 * 	By default, this function returns a {@link DefaultUDF} instance. It is generic enough to cover every kind of functions.
-	 * 	But you can of course override this function in order to return your own instance of {@link UserDefinedFunction}.
-	 * 	In this case, you may not forget to call the super function (super.createUserDefinedFunction(name, params)) so that
-	 * 	all other unknown functions are still returned as {@link DefaultUDF} instances.
+	 * 	By default, this function returns a {@link DefaultUDF} instance. It is
+	 * 	generic enough to cover every kind of functions. But you can of course
+	 * 	override this function in order to return your own instance of
+	 * 	{@link UserDefinedFunction}. In this case, you may not forget to call
+	 * 	the super function (super.createUserDefinedFunction(name, params)) so
+	 * 	that all other unknown functions are still returned as
+	 * 	{@link DefaultUDF} instances.
 	 * </p>
-	 * 
+	 *
 	 * <p><i><b>IMPORTANT:</b>
-	 * 	The tests done to check whether a user defined function is allowed/managed in this implementation, is done later by the parser.
-	 * 	Only declared UDF will pass the test of the parser. For that, you should give it a list of allowed UDFs (each UDF will be then
-	 * 	represented by a {@link FunctionDef} object).
+	 * 	The tests done to check whether a user defined function is
+	 * 	allowed/managed in this implementation, is done later by the parser.
+	 * 	Only declared UDF will pass the test of the parser. For that, you should
+	 * 	give it a list of allowed UDFs (each UDF will be then represented by a
+	 * 	{@link FunctionDef} object).
 	 * </i></p>
-	 * 
+	 *
 	 * @param name			Name of the user defined function to create.
 	 * @param params		Parameters of the user defined function to create.
-	 * 
-	 * @return				The corresponding user defined function (by default an instance of {@link DefaultUDF}).
-	 * 
+	 *
+	 * @return				The corresponding user defined function (by default
+	 *        				an instance of {@link DefaultUDF}).
+	 *
 	 * @throws Exception	If there is a problem while creating the function.
 	 */
-	public UserDefinedFunction createUserDefinedFunction(String name, ADQLOperand[] params) throws Exception{
+	public UserDefinedFunction createUserDefinedFunction(String name, ADQLOperand[] params) throws Exception {
 		return new DefaultUDF(name, params);
 	}
 
-	public DistanceFunction createDistance(PointFunction point1, PointFunction point2) throws Exception{
+	public DistanceFunction createDistance(PointFunction point1, PointFunction point2) throws Exception {
 		return new DistanceFunction(new GeometryValue<PointFunction>(point1), new GeometryValue<PointFunction>(point2));
 	}
 
-	public DistanceFunction createDistance(GeometryValue<PointFunction> point1, GeometryValue<PointFunction> point2) throws Exception{
+	public DistanceFunction createDistance(GeometryValue<PointFunction> point1, GeometryValue<PointFunction> point2) throws Exception {
 		return new DistanceFunction(point1, point2);
 	}
 
-	public PointFunction createPoint(ADQLOperand coordSys, ADQLOperand coords, ADQLOperand coords2) throws Exception{
+	public PointFunction createPoint(ADQLOperand coordSys, ADQLOperand coords, ADQLOperand coords2) throws Exception {
 		return new PointFunction(coordSys, coords, coords2);
 	}
 
-	public BoxFunction createBox(ADQLOperand coordinateSystem, ADQLOperand firstCoord, ADQLOperand secondCoord, ADQLOperand boxWidth, ADQLOperand boxHeight) throws Exception{
+	public BoxFunction createBox(ADQLOperand coordinateSystem, ADQLOperand firstCoord, ADQLOperand secondCoord, ADQLOperand boxWidth, ADQLOperand boxHeight) throws Exception {
 		return new BoxFunction(coordinateSystem, firstCoord, secondCoord, boxWidth, boxHeight);
 	}
 
-	public CircleFunction createCircle(ADQLOperand coordSys, ADQLOperand coord1, ADQLOperand coord2, ADQLOperand radius) throws Exception{
+	public CircleFunction createCircle(ADQLOperand coordSys, ADQLOperand coord1, ADQLOperand coord2, ADQLOperand radius) throws Exception {
 		return new CircleFunction(coordSys, coord1, coord2, radius);
 	}
 
-	public CentroidFunction createCentroid(GeometryFunction param) throws Exception{
+	public CentroidFunction createCentroid(GeometryFunction param) throws Exception {
 		return new CentroidFunction(new GeometryValue<GeometryFunction>(param));
 	}
 
-	public CentroidFunction createCentroid(GeometryValue<GeometryFunction> param) throws Exception{
+	public CentroidFunction createCentroid(GeometryValue<GeometryFunction> param) throws Exception {
 		return new CentroidFunction(param);
 	}
 
-	public RegionFunction createRegion(ADQLOperand param) throws Exception{
+	public RegionFunction createRegion(ADQLOperand param) throws Exception {
 		return new RegionFunction(param);
 	}
 
-	public PolygonFunction createPolygon(ADQLOperand coordSys, Collection<? extends ADQLOperand> coords) throws Exception{
+	public PolygonFunction createPolygon(ADQLOperand coordSys, Collection<? extends ADQLOperand> coords) throws Exception {
 		return new PolygonFunction(coordSys, coords);
 	}
 
-	public AreaFunction createArea(GeometryFunction param) throws Exception{
+	public AreaFunction createArea(GeometryFunction param) throws Exception {
 		return new AreaFunction(new GeometryValue<GeometryFunction>(param));
 	}
 
-	public AreaFunction createArea(GeometryValue<GeometryFunction> param) throws Exception{
+	public AreaFunction createArea(GeometryValue<GeometryFunction> param) throws Exception {
 		return new AreaFunction(param);
 	}
 
-	public ExtractCoord createCoord1(PointFunction point) throws Exception{
+	public ExtractCoord createCoord1(PointFunction point) throws Exception {
 		return new ExtractCoord(1, new GeometryValue<PointFunction>(point));
 	}
 
-	public ExtractCoord createCoord1(ADQLColumn point) throws Exception{
+	public ExtractCoord createCoord1(ADQLColumn point) throws Exception {
 		return new ExtractCoord(1, new GeometryValue<PointFunction>(point));
 	}
 
-	public ExtractCoord createCoord2(PointFunction point) throws Exception{
+	public ExtractCoord createCoord2(PointFunction point) throws Exception {
 		return new ExtractCoord(2, new GeometryValue<PointFunction>(point));
 	}
 
-	public ExtractCoord createCoord2(ADQLColumn point) throws Exception{
+	public ExtractCoord createCoord2(ADQLColumn point) throws Exception {
 		return new ExtractCoord(2, new GeometryValue<PointFunction>(point));
 	}
 
-	public ExtractCoordSys createExtractCoordSys(GeometryFunction param) throws Exception{
+	public ExtractCoordSys createExtractCoordSys(GeometryFunction param) throws Exception {
 		return new ExtractCoordSys(new GeometryValue<GeometryFunction>(param));
 	}
 
-	public ExtractCoordSys createExtractCoordSys(ADQLColumn param) throws Exception{
+	public ExtractCoordSys createExtractCoordSys(ADQLColumn param) throws Exception {
 		return new ExtractCoordSys(new GeometryValue<GeometryFunction>(param));
 	}
 
-	public ExtractCoordSys createExtractCoordSys(GeometryValue<GeometryFunction> param) throws Exception{
+	public ExtractCoordSys createExtractCoordSys(GeometryValue<GeometryFunction> param) throws Exception {
 		return new ExtractCoordSys(new GeometryValue<GeometryFunction>(param));
 	}
 
-	public ContainsFunction createContains(GeometryFunction left, GeometryFunction right) throws Exception{
+	public ContainsFunction createContains(GeometryFunction left, GeometryFunction right) throws Exception {
 		return new ContainsFunction(new GeometryValue<GeometryFunction>(left), new GeometryValue<GeometryFunction>(right));
 	}
 
-	public ContainsFunction createContains(GeometryValue<GeometryFunction> left, GeometryValue<GeometryFunction> right) throws Exception{
+	public ContainsFunction createContains(GeometryValue<GeometryFunction> left, GeometryValue<GeometryFunction> right) throws Exception {
 		return new ContainsFunction(left, right);
 	}
 
-	public IntersectsFunction createIntersects(GeometryFunction left, GeometryFunction right) throws Exception{
+	public IntersectsFunction createIntersects(GeometryFunction left, GeometryFunction right) throws Exception {
 		return new IntersectsFunction(new GeometryValue<GeometryFunction>(left), new GeometryValue<GeometryFunction>(right));
 	}
 
-	public IntersectsFunction createIntersects(GeometryValue<GeometryFunction> left, GeometryValue<GeometryFunction> right) throws Exception{
+	public IntersectsFunction createIntersects(GeometryValue<GeometryFunction> left, GeometryValue<GeometryFunction> right) throws Exception {
 		return new IntersectsFunction(left, right);
 	}
 
@@ -388,7 +405,7 @@ public class ADQLQueryFactory {
 	 * Replace {@link #createOrder(int, boolean, TextPosition)}.
 	 * @since 1.4
 	 */
-	public ADQLOrder createOrder(final int ind, final boolean desc) throws Exception{
+	public ADQLOrder createOrder(final int ind, final boolean desc) throws Exception {
 		return new ADQLOrder(ind, desc);
 	}
 
@@ -396,14 +413,14 @@ public class ADQLQueryFactory {
 	 * @deprecated since 1.4 ; Replaced by {@link #createOrder(int, boolean)}
 	 */
 	@Deprecated
-	public ADQLOrder createOrder(final int ind, final boolean desc, final TextPosition position) throws Exception{
+	public ADQLOrder createOrder(final int ind, final boolean desc, final TextPosition position) throws Exception {
 		ADQLOrder order = new ADQLOrder(ind, desc);
 		if (order != null)
 			order.setPosition(position);
 		return order;
 	}
 
-	public ADQLOrder createOrder(final IdentifierItem colName, final boolean desc) throws Exception{
+	public ADQLOrder createOrder(final IdentifierItem colName, final boolean desc) throws Exception {
 		ADQLOrder order = new ADQLOrder(colName.identifier, desc);
 		if (order != null)
 			order.setCaseSensitive(colName.caseSensitivity);
@@ -411,35 +428,39 @@ public class ADQLQueryFactory {
 	}
 
 	/**
-	 * @deprecated since 1.4 ; Former version's mistake: an ORDER BY item is either a regular/delimited column name or an integer, not a qualified column name ; Replaced by {@link #createOrder(adql.parser.IdentifierItems.IdentifierItem, boolean)} ; This function is no longer used by ADQLParser.
+	 * @deprecated since 1.4 ; Former version's mistake: an ORDER BY item is
+	 *                         either a regular/delimited column name or an
+	 *                         integer, not a qualified column name ; Replaced
+	 *                         by {@link #createOrder(adql.parser.IdentifierItems.IdentifierItem, boolean)} ;
+	 *                         This function is no longer used by ADQLParser.
 	 */
 	@Deprecated
-	public ADQLOrder createOrder(final IdentifierItems idItems, final boolean desc) throws Exception{
+	public ADQLOrder createOrder(final IdentifierItems idItems, final boolean desc) throws Exception {
 		ADQLOrder order = new ADQLOrder(idItems.join("."), desc);
 		if (order != null)
 			order.setCaseSensitive(idItems.getColumnCaseSensitivity());
 		return order;
 	}
 
-	public ColumnReference createColRef(final IdentifierItem idItem) throws Exception{
+	public ColumnReference createColRef(final IdentifierItem idItem) throws Exception {
 		ColumnReference colRef = new ColumnReference(idItem.identifier);
-		if (colRef != null){
+		if (colRef != null) {
 			colRef.setPosition(idItem.position);
 			colRef.setCaseSensitive(idItem.caseSensitivity);
 		}
 		return colRef;
 	}
 
-	public ColumnReference createColRef(final IdentifierItems idItems) throws Exception{
+	public ColumnReference createColRef(final IdentifierItems idItems) throws Exception {
 		ColumnReference colRef = new ColumnReference(idItems.join("."));
-		if (colRef != null){
+		if (colRef != null) {
 			colRef.setPosition(idItems.getPosition());
 			colRef.setCaseSensitive(idItems.getColumnCaseSensitivity());
 		}
 		return colRef;
 	}
 
-	public ColumnReference createColRef(final int index, final TextPosition position) throws Exception{
+	public ColumnReference createColRef(final int index, final TextPosition position) throws Exception {
 		ColumnReference colRef = new ColumnReference(index);
 		if (colRef != null)
 			colRef.setPosition(position);
diff --git a/src/adql/parser/ParseException.java b/src/adql/parser/ParseException.java
index 0d7065125cc484d1cae8c5b3961778b2b161ce0a..96370d8a6224fb0890e26af86e57d4f8e4f09230 100644
--- a/src/adql/parser/ParseException.java
+++ b/src/adql/parser/ParseException.java
@@ -20,6 +20,11 @@
  *     - addition of a constructor with a TokenMgrError which adds a piece of
  *       advice to fix the token issue (see buildExpandedMessage(...))
  *
+ * Modified by Gr&eacute;gory Mantelet (ARI), on April 2019
+ * Modifications:
+ *     - change the way ADQL and SQL reserved keywords are identified for the
+ *       generation of the appropriate HINT in the error message
+ *
  * /!\ DO NOT RE-GENERATE THIS FILE /!\
  * In case of re-generation, replace it by ParseException.java.backup (but maybe
  * after a diff in case of significant modifications have been done by a new
@@ -53,7 +58,7 @@ public class ParseException extends Exception {
 	 * a new object of this type with the fields "currentToken",
 	 * "expectedTokenSequences", and "tokenImage" set.
 	 */
-	public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal){
+	public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal) {
 		super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
 		currentToken = currentTokenVal;
 		expectedTokenSequences = expectedTokenSequencesVal;
@@ -72,25 +77,25 @@ public class ParseException extends Exception {
 	 * these constructors.
 	 */
 
-	public ParseException(){
+	public ParseException() {
 		super();
 	}
 
 	/** Constructor with message. */
-	public ParseException(String message){
+	public ParseException(String message) {
 		super(message);
 	}
 
-	public ParseException(String message, TextPosition errorPosition){
+	public ParseException(String message, TextPosition errorPosition) {
 		this(message);
 		position = errorPosition;
 	}
 
-	public ParseException(TokenMgrError err){
+	public ParseException(TokenMgrError err) {
 		this(buildExpandedMessage(err), new TextPosition(err.getErrorLine(), err.getErrorColumn()));
 	}
 
-	private final static String buildExpandedMessage(final TokenMgrError err){
+	private final static String buildExpandedMessage(final TokenMgrError err) {
 		if (err.getMessage().indexOf("<EOF>") > 0)
 			return err.getMessage() + "! Possible cause: a string between single or double quotes which is never closed (solution: well...just close it!).";
 		else
@@ -121,44 +126,12 @@ public class ParseException extends Exception {
 	/** Line in the ADQL query where the exception occurs. */
 	protected TextPosition position = null;
 
-	/** Regular expression listing all ADQL reserved words.
-	 *
-	 * <p><i>Note 1:
-	 * 	This list is built NOT from the list given in the ADQL-2.0 standard,
-	 * 	but from the collation of all words potentially used in an ADQL query
-	 * 	(including standard function names).
-	 * </i></p>
-	 *
-	 * <p><i>Note 2:
-	 * 	This regular expression is only used to display an appropriate hint
-	 * 	to the user in the error message if a such word is at the origin of
-	 * 	the error. (see {@link #initialise(Token, int[][], String[])} for more
-	 * 	details).
-	 * </i></p> */
-	private final static String ADQL_RESERVED_WORDS_REGEX = "(ABS|ACOS|AREA|ASIN|ATAN|ATAN2|BOX|CEILING|CENTROID|CIRCLE|CONTAINS|COORD1|COORD2|COORDSYS|COS|DEGREES|DISTANCE|EXP|FLOOR|INTERSECTS|LOG|LOG10|MOD|PI|POINT|POLYGON|POWER|RADIANS|REGION|RAND|ROUND|SIN|SQRT|TOP|TAN|TRUNCATE|SELECT|TOP|DISTINCT|ALL|AS|COUNT|AVG|MAX|MIN|SUM|FROM|JOIN|CROSS|INNER|OUTER|LEFT|RIGHT|FULL|NATURAL|USING|ON|WHERE|IS|NOT|AND|OR|EXISTS|IN|LIKE|NULL|BETWEEN|ORDER|ASC|DESC|GROUP|BY|HAVING)";
-
-	/** Regular expression listing all SQL reserved words.
-	 *
-	 * <p><i>Note 1:
-	 * 	This list is built from the list given in the ADQL-2.0 standard,
-	 * 	after removal of all words potentially used in an ADQL query
-	 * 	(see {@link #ADQL_RESERVED_WORDS_REGEX}).
-	 * </i></p>
-	 *
-	 * <p><i>Note 2:
-	 * 	This regular expression is only used to display an appropriate hint
-	 * 	to the user in the error message if a such word is at the origin of
-	 * 	the error. (see {@link #initialise(Token, int[][], String[])} for more
-	 * 	details).
-	 * </i></p> */
-	private final static String SQL_RESERVED_WORDS_REGEX = "(ABSOLUTE|ACTION|ADD|ALLOCATE|ALTER|ANY|ARE|ASSERTION|AT|AUTHORIZATION|BEGIN|BIT|BIT_LENGTH|BOTH|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FOUND|GET|GLOBAL|GO|GOTO|GRANT|HOUR|IDENTITY|IMMEDIATE|INDICATOR|INITIALLY|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|ISOLATION|KEY|LANGUAGE|LAST|LEADING|LEVEL|LOCAL|LOWER|MATCH|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NCHAR|NEXT|NO|NULLIF|NUMERIC|OCTET_LENGTH|OF|ONLY|OPEN|OPTION|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|SUBSTRING|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WITH|WORK|WRITE|YEAR|ZONE)";
-
 	/**
 	 * Gets the position in the ADQL query of the token which generates this exception.
 	 *
 	 * @return Position or <code>null</code> if unknown.
 	 */
-	public final TextPosition getPosition(){
+	public final TextPosition getPosition() {
 		return position;
 	}
 
@@ -169,16 +142,16 @@ public class ParseException extends Exception {
 	 * from the parser) the correct error message
 	 * gets displayed.
 	 */
-	private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage){
+	private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage) {
 		int maxSize = 0;
 
 		// Build the list of expected tokens:
 		StringBuffer expected = new StringBuffer();
-		for(int i = 0; i < expectedTokenSequences.length; i++){
-			if (maxSize < expectedTokenSequences[i].length){
+		for(int i = 0; i < expectedTokenSequences.length; i++) {
+			if (maxSize < expectedTokenSequences[i].length) {
 				maxSize = expectedTokenSequences[i].length;
 			}
-			for(int j = 0; j < expectedTokenSequences[i].length; j++){
+			for(int j = 0; j < expectedTokenSequences[i].length; j++) {
 				expected.append(tokenImage[expectedTokenSequences[i][j]]);
 			}
 			expected.append(" ");
@@ -189,10 +162,10 @@ public class ParseException extends Exception {
 		msg.append(" Encountered \"");
 		Token tok = currentToken.next;
 		StringBuffer tokenName = new StringBuffer();
-		for(int i = 0; i < maxSize; i++){
+		for(int i = 0; i < maxSize; i++) {
 			if (i != 0)
 				tokenName.append(' ');
-			if (tok.kind == 0){
+			if (tok.kind == 0) {
 				tokenName.append(tokenImage[0]);
 				break;
 			}
@@ -202,19 +175,21 @@ public class ParseException extends Exception {
 		msg.append(tokenName.toString()).append("\".");
 
 		// Append the expected tokens list:
-		if (expectedTokenSequences.length == 1){
+		if (expectedTokenSequences.length == 1) {
 			msg.append(" Was expecting: ");
-		}else{
+		} else {
 			msg.append(" Was expecting one of: ");
 		}
 		msg.append(expected);
 
 		// Append a hint about reserved words if it is one:
-		String word = tokenName.toString().trim();
-		if (word.toUpperCase().matches(ADQL_RESERVED_WORDS_REGEX))
-			msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)");
-		else if (word.toUpperCase().matches(SQL_RESERVED_WORDS_REGEX))
-			msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)");
+		if (maxSize == 1) {
+			tok = currentToken.next;
+			if (tok.adqlReserved)
+				msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(tok.image).append("\" is a reserved ADQL word in " + currentToken.next.adqlVersion + ". To use it as a column/table/schema name/alias, write it between double quotes.)");
+			else if (tok.sqlReserved)
+				msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(tok.image).append("\" is not supported in ADQL " + currentToken.next.adqlVersion + ", but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)");
+		}
 
 		return msg.toString();
 		/*String eol = System.getProperty("line.separator", "\n");
@@ -267,11 +242,11 @@ public class ParseException extends Exception {
 	 * when these raw version cannot be used as part of an ASCII
 	 * string literal.
 	 */
-	static String add_escapes(String str){
+	static String add_escapes(String str) {
 		StringBuffer retval = new StringBuffer();
 		char ch;
-		for(int i = 0; i < str.length(); i++){
-			switch(str.charAt(i)){
+		for(int i = 0; i < str.length(); i++) {
+			switch(str.charAt(i)) {
 				case 0:
 					continue;
 				case '\b':
@@ -299,10 +274,10 @@ public class ParseException extends Exception {
 					retval.append("\\\\");
 					continue;
 				default:
-					if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e){
+					if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
 						String s = "0000" + Integer.toString(ch, 16);
 						retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-					}else{
+					} else {
 						retval.append(ch);
 					}
 					continue;
diff --git a/src/adql/parser/ParseException.java.backup b/src/adql/parser/ParseException.java.backup
index 0d7065125cc484d1cae8c5b3961778b2b161ce0a..96370d8a6224fb0890e26af86e57d4f8e4f09230 100644
--- a/src/adql/parser/ParseException.java.backup
+++ b/src/adql/parser/ParseException.java.backup
@@ -20,6 +20,11 @@
  *     - addition of a constructor with a TokenMgrError which adds a piece of
  *       advice to fix the token issue (see buildExpandedMessage(...))
  *
+ * Modified by Gr&eacute;gory Mantelet (ARI), on April 2019
+ * Modifications:
+ *     - change the way ADQL and SQL reserved keywords are identified for the
+ *       generation of the appropriate HINT in the error message
+ *
  * /!\ DO NOT RE-GENERATE THIS FILE /!\
  * In case of re-generation, replace it by ParseException.java.backup (but maybe
  * after a diff in case of significant modifications have been done by a new
@@ -53,7 +58,7 @@ public class ParseException extends Exception {
 	 * a new object of this type with the fields "currentToken",
 	 * "expectedTokenSequences", and "tokenImage" set.
 	 */
-	public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal){
+	public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal) {
 		super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
 		currentToken = currentTokenVal;
 		expectedTokenSequences = expectedTokenSequencesVal;
@@ -72,25 +77,25 @@ public class ParseException extends Exception {
 	 * these constructors.
 	 */
 
-	public ParseException(){
+	public ParseException() {
 		super();
 	}
 
 	/** Constructor with message. */
-	public ParseException(String message){
+	public ParseException(String message) {
 		super(message);
 	}
 
-	public ParseException(String message, TextPosition errorPosition){
+	public ParseException(String message, TextPosition errorPosition) {
 		this(message);
 		position = errorPosition;
 	}
 
-	public ParseException(TokenMgrError err){
+	public ParseException(TokenMgrError err) {
 		this(buildExpandedMessage(err), new TextPosition(err.getErrorLine(), err.getErrorColumn()));
 	}
 
-	private final static String buildExpandedMessage(final TokenMgrError err){
+	private final static String buildExpandedMessage(final TokenMgrError err) {
 		if (err.getMessage().indexOf("<EOF>") > 0)
 			return err.getMessage() + "! Possible cause: a string between single or double quotes which is never closed (solution: well...just close it!).";
 		else
@@ -121,44 +126,12 @@ public class ParseException extends Exception {
 	/** Line in the ADQL query where the exception occurs. */
 	protected TextPosition position = null;
 
-	/** Regular expression listing all ADQL reserved words.
-	 *
-	 * <p><i>Note 1:
-	 * 	This list is built NOT from the list given in the ADQL-2.0 standard,
-	 * 	but from the collation of all words potentially used in an ADQL query
-	 * 	(including standard function names).
-	 * </i></p>
-	 *
-	 * <p><i>Note 2:
-	 * 	This regular expression is only used to display an appropriate hint
-	 * 	to the user in the error message if a such word is at the origin of
-	 * 	the error. (see {@link #initialise(Token, int[][], String[])} for more
-	 * 	details).
-	 * </i></p> */
-	private final static String ADQL_RESERVED_WORDS_REGEX = "(ABS|ACOS|AREA|ASIN|ATAN|ATAN2|BOX|CEILING|CENTROID|CIRCLE|CONTAINS|COORD1|COORD2|COORDSYS|COS|DEGREES|DISTANCE|EXP|FLOOR|INTERSECTS|LOG|LOG10|MOD|PI|POINT|POLYGON|POWER|RADIANS|REGION|RAND|ROUND|SIN|SQRT|TOP|TAN|TRUNCATE|SELECT|TOP|DISTINCT|ALL|AS|COUNT|AVG|MAX|MIN|SUM|FROM|JOIN|CROSS|INNER|OUTER|LEFT|RIGHT|FULL|NATURAL|USING|ON|WHERE|IS|NOT|AND|OR|EXISTS|IN|LIKE|NULL|BETWEEN|ORDER|ASC|DESC|GROUP|BY|HAVING)";
-
-	/** Regular expression listing all SQL reserved words.
-	 *
-	 * <p><i>Note 1:
-	 * 	This list is built from the list given in the ADQL-2.0 standard,
-	 * 	after removal of all words potentially used in an ADQL query
-	 * 	(see {@link #ADQL_RESERVED_WORDS_REGEX}).
-	 * </i></p>
-	 *
-	 * <p><i>Note 2:
-	 * 	This regular expression is only used to display an appropriate hint
-	 * 	to the user in the error message if a such word is at the origin of
-	 * 	the error. (see {@link #initialise(Token, int[][], String[])} for more
-	 * 	details).
-	 * </i></p> */
-	private final static String SQL_RESERVED_WORDS_REGEX = "(ABSOLUTE|ACTION|ADD|ALLOCATE|ALTER|ANY|ARE|ASSERTION|AT|AUTHORIZATION|BEGIN|BIT|BIT_LENGTH|BOTH|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHAR_LENGTH|CHARACTER_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|CREATE|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FOUND|GET|GLOBAL|GO|GOTO|GRANT|HOUR|IDENTITY|IMMEDIATE|INDICATOR|INITIALLY|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|ISOLATION|KEY|LANGUAGE|LAST|LEADING|LEVEL|LOCAL|LOWER|MATCH|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NCHAR|NEXT|NO|NULLIF|NUMERIC|OCTET_LENGTH|OF|ONLY|OPEN|OPTION|OUTPUT|OVERLAPS|PAD|PARTIAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCODE|SQLERROR|SQLSTATE|SUBSTRING|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WITH|WORK|WRITE|YEAR|ZONE)";
-
 	/**
 	 * Gets the position in the ADQL query of the token which generates this exception.
 	 *
 	 * @return Position or <code>null</code> if unknown.
 	 */
-	public final TextPosition getPosition(){
+	public final TextPosition getPosition() {
 		return position;
 	}
 
@@ -169,16 +142,16 @@ public class ParseException extends Exception {
 	 * from the parser) the correct error message
 	 * gets displayed.
 	 */
-	private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage){
+	private static String initialise(Token currentToken, int[][] expectedTokenSequences, String[] tokenImage) {
 		int maxSize = 0;
 
 		// Build the list of expected tokens:
 		StringBuffer expected = new StringBuffer();
-		for(int i = 0; i < expectedTokenSequences.length; i++){
-			if (maxSize < expectedTokenSequences[i].length){
+		for(int i = 0; i < expectedTokenSequences.length; i++) {
+			if (maxSize < expectedTokenSequences[i].length) {
 				maxSize = expectedTokenSequences[i].length;
 			}
-			for(int j = 0; j < expectedTokenSequences[i].length; j++){
+			for(int j = 0; j < expectedTokenSequences[i].length; j++) {
 				expected.append(tokenImage[expectedTokenSequences[i][j]]);
 			}
 			expected.append(" ");
@@ -189,10 +162,10 @@ public class ParseException extends Exception {
 		msg.append(" Encountered \"");
 		Token tok = currentToken.next;
 		StringBuffer tokenName = new StringBuffer();
-		for(int i = 0; i < maxSize; i++){
+		for(int i = 0; i < maxSize; i++) {
 			if (i != 0)
 				tokenName.append(' ');
-			if (tok.kind == 0){
+			if (tok.kind == 0) {
 				tokenName.append(tokenImage[0]);
 				break;
 			}
@@ -202,19 +175,21 @@ public class ParseException extends Exception {
 		msg.append(tokenName.toString()).append("\".");
 
 		// Append the expected tokens list:
-		if (expectedTokenSequences.length == 1){
+		if (expectedTokenSequences.length == 1) {
 			msg.append(" Was expecting: ");
-		}else{
+		} else {
 			msg.append(" Was expecting one of: ");
 		}
 		msg.append(expected);
 
 		// Append a hint about reserved words if it is one:
-		String word = tokenName.toString().trim();
-		if (word.toUpperCase().matches(ADQL_RESERVED_WORDS_REGEX))
-			msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)");
-		else if (word.toUpperCase().matches(SQL_RESERVED_WORDS_REGEX))
-			msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(word).append("\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)");
+		if (maxSize == 1) {
+			tok = currentToken.next;
+			if (tok.adqlReserved)
+				msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(tok.image).append("\" is a reserved ADQL word in " + currentToken.next.adqlVersion + ". To use it as a column/table/schema name/alias, write it between double quotes.)");
+			else if (tok.sqlReserved)
+				msg.append(System.getProperty("line.separator", "\n")).append("(HINT: \"").append(tok.image).append("\" is not supported in ADQL " + currentToken.next.adqlVersion + ", but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)");
+		}
 
 		return msg.toString();
 		/*String eol = System.getProperty("line.separator", "\n");
@@ -267,11 +242,11 @@ public class ParseException extends Exception {
 	 * when these raw version cannot be used as part of an ASCII
 	 * string literal.
 	 */
-	static String add_escapes(String str){
+	static String add_escapes(String str) {
 		StringBuffer retval = new StringBuffer();
 		char ch;
-		for(int i = 0; i < str.length(); i++){
-			switch(str.charAt(i)){
+		for(int i = 0; i < str.length(); i++) {
+			switch(str.charAt(i)) {
 				case 0:
 					continue;
 				case '\b':
@@ -299,10 +274,10 @@ public class ParseException extends Exception {
 					retval.append("\\\\");
 					continue;
 				default:
-					if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e){
+					if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
 						String s = "0000" + Integer.toString(ch, 16);
 						retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-					}else{
+					} else {
 						retval.append(ch);
 					}
 					continue;
diff --git a/src/adql/parser/Token.java b/src/adql/parser/Token.java
index 261c569086bfaaf963feae8d6079ac51200c3354..afd727184904aba9fadc881227abaae31890b0fa 100644
--- a/src/adql/parser/Token.java
+++ b/src/adql/parser/Token.java
@@ -1,20 +1,23 @@
 /* Generated By:JavaCC: Do not edit this line. Token.java Version 6.0 */
 /* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true
- * 
- * Modified by Gr&eacute;gory Mantelet (CDS), on March 2017
- * Modification: addition of position (line and column) in the original text.
- *               /!\ DO NOT RE-GENERATE THIS FILE /!\
- *               In case of re-generation, replace it by
- *               Token.java.backup (but maybe after a diff
- *               in case of significant modifications have been done
- *               by a new version of JavaCC).
+ *
+ * Modified by Gr&eacute;gory Mantelet (CDS), on April 2019
+ * Modifications:
+ *     - addition of  the attributes: `adqlReserved`, `sqlReserved`,
+ *       `adqlVersion` and `isFunctionName`
+ *
+ * /!\ DO NOT RE-GENERATE THIS FILE /!\
+ * In case of re-generation, replace it by Token.java.backup (but maybe
+ * after a diff in case of significant modifications have been done by a new
+ * version of JavaCC).
  */
 package adql.parser;
 
+import adql.parser.ADQLParserFactory.ADQLVersion;
+
 /**
  * Describes the input token stream.
  */
-
 public class Token implements java.io.Serializable {
 
 	/**
@@ -69,6 +72,57 @@ public class Token implements java.io.Serializable {
 	 */
 	public Token specialToken;
 
+	/**
+	 * Indicate whether this token is a reserved ADQL function name.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used when attempting to fix an ADQL
+	 * 	query.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean isFunctionName = false;
+
+	/**
+	 * Indicate whether this token is a reserved keyword in the current version
+	 * of the ADQL language.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used to add a hint in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean adqlReserved = false;
+
+	/**
+	 * Indicate whether this token is a reserved keyword in the current version
+	 * of the ADQL language because it is a valid keyword in SQL (and may have
+	 * unexpected behavior if used because not explicitly defined in ADQL).
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used to add a hint in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean sqlReserved = false;
+
+	/**
+	 * Give the version of the ADQL language.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is used just for more clarity in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public ADQLVersion adqlVersion = null;
+
 	/**
 	 * An optional attribute value of the Token.
 	 * Tokens which are not used as syntactic sugar will often contain
@@ -77,26 +131,27 @@ public class Token implements java.io.Serializable {
 	 * Any subclass of Token that actually wants to return a non-null value can
 	 * override this method as appropriate.
 	 */
-	public Object getValue(){
+	public Object getValue() {
 		return null;
 	}
 
 	/**
 	 * No-argument constructor
 	 */
-	public Token(){}
+	public Token() {
+	}
 
 	/**
 	 * Constructs a new token for the specified Image.
 	 */
-	public Token(int kind){
+	public Token(int kind) {
 		this(kind, null);
 	}
 
 	/**
 	 * Constructs a new token for the specified Image and Kind.
 	 */
-	public Token(int kind, String image){
+	public Token(int kind, String image) {
 		this.kind = kind;
 		this.image = image;
 	}
@@ -105,7 +160,7 @@ public class Token implements java.io.Serializable {
 	 * Returns the image.
 	 */
 	@Override
-	public String toString(){
+	public String toString() {
 		return image;
 	}
 
@@ -121,14 +176,14 @@ public class Token implements java.io.Serializable {
 	 * to the following switch statement. Then you can cast matchedToken
 	 * variable to the appropriate type and use sit in your lexical actions.
 	 */
-	public static Token newToken(int ofKind, String image){
-		switch(ofKind){
+	public static Token newToken(int ofKind, String image) {
+		switch(ofKind) {
 			default:
 				return new Token(ofKind, image);
 		}
 	}
 
-	public static Token newToken(int ofKind){
+	public static Token newToken(int ofKind) {
 		return newToken(ofKind, null);
 	}
 
diff --git a/src/adql/parser/Token.java.backup b/src/adql/parser/Token.java.backup
index 261c569086bfaaf963feae8d6079ac51200c3354..afd727184904aba9fadc881227abaae31890b0fa 100644
--- a/src/adql/parser/Token.java.backup
+++ b/src/adql/parser/Token.java.backup
@@ -1,20 +1,23 @@
 /* Generated By:JavaCC: Do not edit this line. Token.java Version 6.0 */
 /* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true
- * 
- * Modified by Gr&eacute;gory Mantelet (CDS), on March 2017
- * Modification: addition of position (line and column) in the original text.
- *               /!\ DO NOT RE-GENERATE THIS FILE /!\
- *               In case of re-generation, replace it by
- *               Token.java.backup (but maybe after a diff
- *               in case of significant modifications have been done
- *               by a new version of JavaCC).
+ *
+ * Modified by Gr&eacute;gory Mantelet (CDS), on April 2019
+ * Modifications:
+ *     - addition of  the attributes: `adqlReserved`, `sqlReserved`,
+ *       `adqlVersion` and `isFunctionName`
+ *
+ * /!\ DO NOT RE-GENERATE THIS FILE /!\
+ * In case of re-generation, replace it by Token.java.backup (but maybe
+ * after a diff in case of significant modifications have been done by a new
+ * version of JavaCC).
  */
 package adql.parser;
 
+import adql.parser.ADQLParserFactory.ADQLVersion;
+
 /**
  * Describes the input token stream.
  */
-
 public class Token implements java.io.Serializable {
 
 	/**
@@ -69,6 +72,57 @@ public class Token implements java.io.Serializable {
 	 */
 	public Token specialToken;
 
+	/**
+	 * Indicate whether this token is a reserved ADQL function name.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used when attempting to fix an ADQL
+	 * 	query.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean isFunctionName = false;
+
+	/**
+	 * Indicate whether this token is a reserved keyword in the current version
+	 * of the ADQL language.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used to add a hint in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean adqlReserved = false;
+
+	/**
+	 * Indicate whether this token is a reserved keyword in the current version
+	 * of the ADQL language because it is a valid keyword in SQL (and may have
+	 * unexpected behavior if used because not explicitly defined in ADQL).
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is just used to add a hint in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public boolean sqlReserved = false;
+
+	/**
+	 * Give the version of the ADQL language.
+	 *
+	 * <p><i><b>Implementation note:</b>
+	 * 	This piece of information is used just for more clarity in
+	 * 	ParseException's messages.
+	 * </i></p>
+	 *
+	 * @since 2.0
+	 */
+	public ADQLVersion adqlVersion = null;
+
 	/**
 	 * An optional attribute value of the Token.
 	 * Tokens which are not used as syntactic sugar will often contain
@@ -77,26 +131,27 @@ public class Token implements java.io.Serializable {
 	 * Any subclass of Token that actually wants to return a non-null value can
 	 * override this method as appropriate.
 	 */
-	public Object getValue(){
+	public Object getValue() {
 		return null;
 	}
 
 	/**
 	 * No-argument constructor
 	 */
-	public Token(){}
+	public Token() {
+	}
 
 	/**
 	 * Constructs a new token for the specified Image.
 	 */
-	public Token(int kind){
+	public Token(int kind) {
 		this(kind, null);
 	}
 
 	/**
 	 * Constructs a new token for the specified Image and Kind.
 	 */
-	public Token(int kind, String image){
+	public Token(int kind, String image) {
 		this.kind = kind;
 		this.image = image;
 	}
@@ -105,7 +160,7 @@ public class Token implements java.io.Serializable {
 	 * Returns the image.
 	 */
 	@Override
-	public String toString(){
+	public String toString() {
 		return image;
 	}
 
@@ -121,14 +176,14 @@ public class Token implements java.io.Serializable {
 	 * to the following switch statement. Then you can cast matchedToken
 	 * variable to the appropriate type and use sit in your lexical actions.
 	 */
-	public static Token newToken(int ofKind, String image){
-		switch(ofKind){
+	public static Token newToken(int ofKind, String image) {
+		switch(ofKind) {
 			default:
 				return new Token(ofKind, image);
 		}
 	}
 
-	public static Token newToken(int ofKind){
+	public static Token newToken(int ofKind) {
 		return newToken(ofKind, null);
 	}
 
diff --git a/src/adql/parser/TokenMgrError.java.backup b/src/adql/parser/TokenMgrError.java.backup
index 61b4a9c384d64f169734169ee09dd7d17cef9fc4..fa5d8aaa60363bea7b3f223dac1488421a804663 100644
--- a/src/adql/parser/TokenMgrError.java.backup
+++ b/src/adql/parser/TokenMgrError.java.backup
@@ -4,7 +4,9 @@
  * Modified by Gr&eacute;gory Mantelet (CDS), on Sept. 2017
  * Modifications:
  *     - addition of position (line and column) in the original text
- *     - display the incorrect character as a character instead of an integer
+ *     - adapt the error message so that being more explicit for humans
+ *       and display the incorrect character as a character instead of an
+ *       integer value
  * 
  * /!\ DO NOT RE-GENERATE THIS FILE /!\
  * In case of re-generation, replace it by TokenMgrError.java.backup (but maybe
diff --git a/src/adql/parser/adqlGrammar.jj b/src/adql/parser/adqlGrammar200.jj
similarity index 83%
rename from src/adql/parser/adqlGrammar.jj
rename to src/adql/parser/adqlGrammar200.jj
index e9ea32d07cf145b5e66e2fbf4d365dfe3fd42870..3accb84f46950ec30e9d43f56b3d0d8f14369d40 100644
--- a/src/adql/parser/adqlGrammar.jj
+++ b/src/adql/parser/adqlGrammar200.jj
@@ -14,8 +14,7 @@
  * You should have received a copy of the GNU Lesser General Public License
  * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
  * 
- * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
- *                       Astronomisches Rechen Institute (ARI)
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
  */
 
 /*
@@ -30,8 +29,8 @@
 * If the syntax is not conform to the ADQL definition an error message is
 * printed else it will be the message "Correct syntax".
 *
-*  Author:  Gr&eacute;gory Mantelet (CDS;ARI)
-*  Version: 1.5 (03/2019)
+*  Author:  Gr&eacute;gory Mantelet (CDS)
+*  Version: 2.0 (04/2019)
 */
 
 							/* ########### */
@@ -41,15 +40,36 @@ options {
 	STATIC = false;
 	IGNORE_CASE = true;
 	DEBUG_PARSER = true;
+	KEEP_LINE_COLUMN = true;
+	COMMON_TOKEN_ACTION = true;
 }
 
 							/* ########## */
 							/* # PARSER # */
 							/* ########## */
-PARSER_BEGIN(ADQLParser)
+PARSER_BEGIN(ADQLParser200)
 
 package adql.parser;
 
+/*
+ * This file is part of ADQLLibrary.
+ * 
+ * ADQLLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * ADQLLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ */
+
 import java.util.Stack;
 import java.util.Vector;
 import java.util.ArrayList;
@@ -79,7 +99,7 @@ import adql.translator.PostgreSQLTranslator;
 import adql.translator.TranslationException;
 
 /**
-* Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.
+* Parses an ADQL-2.0 query thanks to the {@link ADQLParser200#Query() Query()} function.
 * 
 * <p>
 *   This parser is able, thanks to a {@link QueryChecker} object, to check each
@@ -118,10 +138,11 @@ import adql.translator.TranslationException;
 * @see QueryChecker
 * @see ADQLQueryFactory
 *
-* @author Gr&eacute;gory Mantelet (CDS;ARI)
-* @version 1.5 (03/2019)
+* @author Gr&eacute;gory Mantelet (CDS)
+* @version 2.0 (04/2019)
+* @since 2.0
 */
-public class ADQLParser {
+public class ADQLParser200 implements ADQLParser {
 	
 	/** Tools to build the object representation of the ADQL query. */
 	private ADQLQueryFactory queryFactory = new ADQLQueryFactory();
@@ -144,7 +165,7 @@ public class ADQLParser {
 	/**
 	* Builds an ADQL parser without a query to parse.
 	*/
-	public ADQLParser(){
+	public ADQLParser200(){
 		this(new java.io.ByteArrayInputStream("".getBytes()));
 		setDebug(false);
 	}
@@ -157,7 +178,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation of
 	*               	the given ADQL query.
 	*/
-	public ADQLParser(QueryChecker checker, ADQLQueryFactory factory) {
+	public ADQLParser200(QueryChecker checker, ADQLQueryFactory factory) {
 		this();
 		
 		queryChecker = checker;
@@ -172,7 +193,7 @@ public class ADQLParser {
 	*
 	* @param checker	The object to use to check each {@link ADQLQuery}.
 	*/
-	public ADQLParser(QueryChecker checker) {
+	public ADQLParser200(QueryChecker checker) {
 		this(checker, null);
 	}
 	
@@ -183,7 +204,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation of
 	*               	the given ADQL query.
 	*/
-	public ADQLParser(ADQLQueryFactory factory) {
+	public ADQLParser200(ADQLQueryFactory factory) {
 		this((QueryChecker)null, factory);
 	}
 	
@@ -195,7 +216,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation of
 	*               	the given ADQL query.
 	*/
-	public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) {
 		this(stream);
 		setDebug(false);
 		
@@ -213,7 +234,7 @@ public class ADQLParser {
 	* @param stream		The stream in which the ADQL query to parse is given.
 	* @param checker	The object to use to check each {@link ADQLQuery}.
 	*/
-	public ADQLParser(java.io.InputStream stream, QueryChecker checker) {
+	public ADQLParser200(java.io.InputStream stream, QueryChecker checker) {
 		this(stream, checker, null);
 	}
 	
@@ -224,7 +245,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation of
 	*               	the given ADQL query.
 	*/
-	public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.InputStream stream, ADQLQueryFactory factory) {
 		this(stream, (QueryChecker)null, factory);
 	}
 	
@@ -237,7 +258,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation
 	*               	of the given ADQL query.
 	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) {
 		this(stream, encoding);
 		setDebug(false);
 		
@@ -254,7 +275,7 @@ public class ADQLParser {
 	* @param encoding	The supplied encoding.
 	* @param checker	The object to use to check each {@link ADQLQuery}.
 	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker) {
+	public ADQLParser200(java.io.InputStream stream, String encoding, QueryChecker checker) {
 		this(stream, encoding, checker, null);
 	}
 	
@@ -266,7 +287,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation
 	*               	of the given ADQL query.
 	*/
-	public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.InputStream stream, String encoding, ADQLQueryFactory factory) {
 		this(stream, encoding, null, factory);
 	}
 	
@@ -278,7 +299,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation
 	*               	of the given ADQL query.
 	*/
-	public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory) {
 		this(reader);
 		setDebug(false);
 		
@@ -296,7 +317,7 @@ public class ADQLParser {
 	* @param reader		The reader in which the ADQL query to parse is given.
 	* @param checker	The object to use to check each {@link ADQLQuery}.
 	*/
-	public ADQLParser(java.io.Reader reader, QueryChecker checker) {
+	public ADQLParser200(java.io.Reader reader, QueryChecker checker) {
 		this(reader, checker, null);
 	}
 	
@@ -307,7 +328,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation
 	*               	of the given ADQL query.
 	*/
-	public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory) {
+	public ADQLParser200(java.io.Reader reader, ADQLQueryFactory factory) {
 		this(reader, null, factory);
 	}
 	
@@ -319,7 +340,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation
 	*               	of the given ADQL query.
 	*/
-	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory) {
+	public ADQLParser200(ADQLParser200TokenManager tm, QueryChecker checker, ADQLQueryFactory factory) {
 		this(tm);
 		setDebug(false);
 		
@@ -337,7 +358,7 @@ public class ADQLParser {
 	* @param tm			The manager which associates a token to a numeric code.
 	* @param checker	The object to use to check each {@link ADQLQuery}.
 	*/
-	public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker) {
+	public ADQLParser200(ADQLParser200TokenManager tm, QueryChecker checker) {
 		this(tm, checker, null);
 	}
 	
@@ -348,7 +369,7 @@ public class ADQLParser {
 	* @param factory	The object to use to build an object representation of
 	*               	the given ADQL query.
 	*/
-	public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory) {
+	public ADQLParser200(ADQLParser200TokenManager tm, ADQLQueryFactory factory) {
 		this(tm, null, factory);
 	}
 
@@ -445,7 +466,7 @@ public class ADQLParser {
 	* 
 	* @throws ParseException	If there is at least one syntactic error.
 	*
-	* @see ADQLParser#Query()
+	* @see ADQLParser200#Query()
 	*/
 	public final ADQLQuery parseQuery() throws ParseException {
 		stackQuery.clear();
@@ -466,9 +487,9 @@ public class ADQLParser {
 	* 
 	* @throws ParseException	If there is at least one syntactic error.
 	*
-	* @see ADQLParser#ReInit(java.io.InputStream)
-	* @see ADQLParser#setDebug(boolean)
-	* @see ADQLParser#Query()
+	* @see ADQLParser200#ReInit(java.io.InputStream)
+	* @see ADQLParser200#setDebug(boolean)
+	* @see ADQLParser200#Query()
 	*/
 	public final ADQLQuery parseQuery(String q) throws ParseException {
 		stackQuery.clear();
@@ -490,9 +511,9 @@ public class ADQLParser {
 	* 
 	* @throws ParseException	If there is at least one syntactic error.
 	*
-	* @see ADQLParser#ReInit(java.io.InputStream)
-	* @see ADQLParser#setDebug(boolean)
-	* @see ADQLParser#Query()
+	* @see ADQLParser200#ReInit(java.io.InputStream)
+	* @see ADQLParser200#setDebug(boolean)
+	* @see ADQLParser200#Query()
 	*/
 	public final ADQLQuery parseQuery(java.io.InputStream stream) throws ParseException {
 		stackQuery.clear();
@@ -505,6 +526,116 @@ public class ADQLParser {
 		}
 	}
 
+	@Override
+	public final ClauseSelect parseSelect(java.lang.String adql) throws ParseException {
+	    // Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a SELECT clause:
+			Select();
+
+			// Return what's just got parsed:
+			return query.getSelect();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final FromContent parseFrom(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a FROM clause:
+			From();
+
+			// Return what's just got parsed:
+			return query.getFrom();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseConstraints parseWhere(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a WHERE clause:
+			Where();
+
+			// Return what's just got parsed:
+			return query.getWhere();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseADQL<ADQLOrder> parseOrderBy(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a ORDER BY clause:
+			OrderBy();
+
+			// Return what's just got parsed:
+			return query.getOrderBy();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseADQL<ADQLColumn> parseGroupBy(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a GROUP BY clause:
+			GroupBy();
+
+			// Return what's just got parsed:
+			return query.getGroupBy();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+
 	/* CORRECTION SUGGESTION */
 
 	/**
@@ -618,7 +749,7 @@ public class ADQLParser {
 		adqlQuery = adqlQuery.replaceAll("(\r\n|\r|\n)", System.getProperty("line.separator")).replaceAll("\t", "    ");
 
 		// 2. Analyse the query token by token:
-		ADQLParserTokenManager parser = new ADQLParserTokenManager(new SimpleCharStream(new java.io.ByteArrayInputStream(adqlQuery.getBytes())));
+		ADQLParser200TokenManager parser = new ADQLParser200TokenManager(new SimpleCharStream(new java.io.ByteArrayInputStream(adqlQuery.getBytes())));
 		
 		final String[] lines = adqlQuery.split(System.getProperty("line.separator"));
 
@@ -767,7 +898,7 @@ public class ADQLParser {
 	 * @since 1.5
 	 */
 	protected boolean isEnd(final Token token){
-		return token.kind == ADQLParserConstants.EOF || token.kind == ADQLParserConstants.EOQ;
+		return token.kind == ADQLParser200Constants.EOF || token.kind == ADQLParser200Constants.EOQ;
 	}
 
 	/**
@@ -794,223 +925,28 @@ public class ADQLParser {
 	 */
 	protected boolean mustEscape(final Token token, final Token nextToken){
 		switch(token.kind){
-			case ADQLParserConstants.SQL_RESERVED_WORD:
+			case ADQLParser200Constants.SQL_RESERVED_WORD:
 				return true;
-			case ADQLParserConstants.REGULAR_IDENTIFIER_CANDIDATE:
+			case ADQLParser200Constants.REGULAR_IDENTIFIER_CANDIDATE:
 				return !isRegularIdentifier(token.image);
 			default:
-				return isFunctionName(token) && (nextToken == null || nextToken.kind != ADQLParserConstants.LEFT_PAR);
+				return token.isFunctionName && (nextToken == null || nextToken.kind != ADQLParser200Constants.LEFT_PAR);
 		}
 	}
+}
 
-	/**
-	 * Tell whether the given token matches to an ADQL function name.
-	 *
-	 * @param token	The token to analyze.
-	 *
-	 * @return	<code>true</code> if the given token is an ADQL function name,
-	 *        	<code>false</code> otherwise.
-	 *
-	 * @since 1.5
-	 */
-	protected boolean isFunctionName(final Token token){
-		switch(token.kind){
-			case ADQLParserConstants.COUNT:
-			case ADQLParserConstants.EXISTS:
-			case ADQLParserConstants.AVG:
-			case ADQLParserConstants.MAX:
-			case ADQLParserConstants.MIN:
-			case ADQLParserConstants.SUM:
-			case ADQLParserConstants.BOX:
-			case ADQLParserConstants.CENTROID:
-			case ADQLParserConstants.CIRCLE:
-			case ADQLParserConstants.POINT:
-			case ADQLParserConstants.POLYGON:
-			case ADQLParserConstants.REGION:
-			case ADQLParserConstants.CONTAINS:
-			case ADQLParserConstants.INTERSECTS:
-			case ADQLParserConstants.AREA:
-			case ADQLParserConstants.COORD1:
-			case ADQLParserConstants.COORD2:
-			case ADQLParserConstants.COORDSYS:
-			case ADQLParserConstants.DISTANCE:
-			case ADQLParserConstants.ABS:
-			case ADQLParserConstants.CEILING:
-			case ADQLParserConstants.DEGREES:
-			case ADQLParserConstants.EXP:
-			case ADQLParserConstants.FLOOR:
-			case ADQLParserConstants.LOG:
-			case ADQLParserConstants.LOG10:
-			case ADQLParserConstants.MOD:
-			case ADQLParserConstants.PI:
-			case ADQLParserConstants.POWER:
-			case ADQLParserConstants.RADIANS:
-			case ADQLParserConstants.RAND:
-			case ADQLParserConstants.ROUND:
-			case ADQLParserConstants.SQRT:
-			case ADQLParserConstants.TRUNCATE:
-			case ADQLParserConstants.ACOS:
-			case ADQLParserConstants.ASIN:
-			case ADQLParserConstants.ATAN:
-			case ADQLParserConstants.ATAN2:
-			case ADQLParserConstants.COS:
-			case ADQLParserConstants.COT:
-			case ADQLParserConstants.SIN:
-			case ADQLParserConstants.TAN:
-			case ADQLParserConstants.USING:
-				return true;
-			default:
-				return false;
-		}
-	}
-
-	/* MAIN PROGRAM */
-
-	/**
-	* Gets the specified ADQL query and parses the given ADQL query. The SQL
-	* translation is then printed if the syntax is correct.
-	* 
-	* <p>
-	*     <b>ONLY the syntax is checked: the query is NOT EXECUTED !</b>
-	* </p>
-	*
-	* @param args
-	
-	* @throws Exception
-	*/
-	public static final void main(String[] args) throws Exception {
-		final String USAGE = "Usage:\n    adqlParser.jar [-d] [-v] [-e] [-a|-s] [-f] [<FILE>|<URL>]\n\nNOTE: If no file or URL is given, the ADQL query is expected in the standard\n      input. This query must end with a ';' or <Ctrl+D>!\n\nParameters:\n    -v or --verbose : Print the main steps of the parsing\n    -d or --debug   : Print stack traces when a grave error occurs\n    -e or --explain : Explain the ADQL parsing (or Expand the parsing tree)\n    -a or --adql    : Display the understood ADQL query\n    -s or --sql     : Ask the SQL translation of the given ADQL query\n                      (SQL compatible with PostgreSQL)\n    -f or --try-fix : Try fixing the most common ADQL query issues before\n                      attempting to parse the query.\n\nReturn:\n    By default: nothing if the query is correct. Otherwise a message explaining\n                why the query is not correct is displayed.\n    With the -s option, the SQL translation of the given ADQL query will be\n    returned.\n    With the -a option, the ADQL query is returned as it has been understood.\n\nExit status:\n    0  OK !\n    1  Parameter error (missing or incorrect parameter)\n    2  File error (incorrect file/url, reading error, ...)\n    3  Parsing error (syntactic or semantic error)\n    4  Translation error (a problem has occurred during the translation of the\n       given ADQL query in SQL).";
-
-		ADQLParser parser;
-
-		final String urlRegex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
-
-		String file = null, metaFile = null;
-		short mode = -1;
-		boolean verbose=false, debug=false, explain=false, tryFix=false;
-
-		// Parameters reading:
-		for(int i=0; i<args.length; i++){
-			if (args[i].equalsIgnoreCase("-d") || args[i].equalsIgnoreCase("--debug"))
-				debug = true;
-			else if (args[i].equalsIgnoreCase("-v") || args[i].equalsIgnoreCase("--verbose"))
-				verbose = true;
-			else if (args[i].equalsIgnoreCase("-e") || args[i].equalsIgnoreCase("--explain"))
-				explain = true;
-			else if (args[i].equalsIgnoreCase("-a") || args[i].equalsIgnoreCase("--adql")){
-				if (mode != -1){
-					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\n"+USAGE);
-					System.exit(1);
-				}else
-					mode = 1;
-			}else if (args[i].equalsIgnoreCase("-s") || args[i].equalsIgnoreCase("--sql")){
-				if (mode != -1){
-					System.err.println("((!)) Too much parameter: you must choose between -s, -c, -a or nothing ((!))\n"+USAGE);
-					System.exit(1);
-				}else
-					mode = 2;
-			}else if (args[i].equalsIgnoreCase("-f") || args[i].equalsIgnoreCase("--try-fix"))
-				tryFix = true;
-			else if (args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")){
-				System.out.println(USAGE);
-				System.exit(0);
-			}else if (args[i].startsWith("-")){
-				System.err.println("((!)) Unknown parameter: \""+args[i]+"\" ((!))\u005cn"+USAGE);
-				System.exit(1);
-			}else
-				file = args[i].trim();
-		}
-
-		try{
-
-			// Try fixing the query, if asked:
-			if (tryFix) {
-				if (verbose)
-					System.out.println("((i)) Trying to automatically fix the query...");
-
-				String query;
-				java.io.InputStream in = null;
-				try {
-					// get the input stream...
-					if (file == null || file.length() == 0)
-						in = System.in;
-					else if (file.matches(urlRegex))
-						in = (new java.net.URL(file)).openStream();
-					else
-						in = new java.io.FileInputStream(file);
-					
-					// ...and try fixing the query:
-					query = (new ADQLParser()).tryQuickFix(in);
-				} finally {
-					// close the stream (if opened):
-					if (in != null)
-						in.close();
-					in = null;
-				}
-				
-				if (verbose)
-					System.out.println("((i)) SUGGESTED QUERY:\n" + query);
-
-				// Initialise the parser with this fixed query:
-				parser = new ADQLParser(new java.io.ByteArrayInputStream(query.getBytes()));	
-			}
-			// Otherwise, take the query as provided:
-			else {
-				// Initialise the parser with the specified input:
-				if (file == null || file.length() == 0)
-					parser = new ADQLParser(System.in);
-				else if (file.matches(urlRegex))
-					parser = new ADQLParser((new java.net.URL(file)).openStream());
-				else
-					parser = new ADQLParser(new java.io.FileInputStream(file));
-			}
-
-			// Enable/Disable the debugging in function of the parameters:
-			parser.setDebug(explain);
+PARSER_END(ADQLParser200)
 
-			// Query parsing:
-			try{
-				if (verbose)	System.out.print("((i)) Parsing ADQL query...");
-				ADQLQuery q = parser.parseQuery();
-				if (verbose)	System.out.println("((i)) CORRECT ADQL QUERY ((i))");
-				if (mode==2){
-					PostgreSQLTranslator translator = new PostgreSQLTranslator();
-					if (verbose)	System.out.print("((i)) Translating in SQL...");
-					String sql = translator.translate(q);
-					if (verbose)	System.out.println("ok");
-					System.out.println(sql);
-				}else if (mode==1){
-					System.out.println(q.toADQL());
-				}
-			}catch(UnresolvedIdentifiersException uie){
-				System.err.println("((X)) "+uie.getNbErrors()+" unresolved identifiers:");
-				for(ParseException pe : uie)
-					System.err.println("\t - at "+pe.getPosition()+": "+uie.getMessage());
-				if (debug)		uie.printStackTrace(System.err);
-				System.exit(3);
-			}catch(ParseException pe){
-				System.err.println("((X)) Syntax error: "+pe.getMessage()+" ((X))");
-				if (debug)		pe.printStackTrace(System.err);
-				System.exit(3);
-			}catch(TranslationException te){
-				if (verbose)	System.out.println("error");
-				System.err.println("((X)) Translation error: "+te.getMessage()+" ((X))");
-				if (debug)		te.printStackTrace(System.err);
-				System.exit(4);
-			}
+				/* ################################### */
+				/* # CUSTOMIZATION OF TOKEN CREATION # */
+				/* ################################### */
 
-		}catch(IOException ioe){
-			System.err.println("\n((X)) Error while reading the file \""+file+"\": "+ioe.getMessage()+" ((X))");
-			if (debug)		ioe.printStackTrace(System.err);
-			System.exit(2);
-		}
-    	
-    }
+TOKEN_MGR_DECLS: {
+	protected void CommonTokenAction(final Token t) {
+		t.adqlVersion = ADQLParserFactory.ADQLVersion.V2_0;
+	} 
 }
 
-PARSER_END(ADQLParser)
-
-
 							/* ########### */
 							/* # GRAMMAR # */
 							/* ########### */
@@ -1031,6 +967,7 @@ SKIP : { < " " | "\t" | "\n" | "\r" | "\r\n" > }
 
 TOKEN : {
 	< SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"LOWER"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"UPPER"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WITH"|"WORK"|"WRITE"|"YEAR"|"ZONE") >
+	{ matchedToken.sqlReserved = true; }
 }
 
 /* *********** */
@@ -1071,120 +1008,124 @@ TOKEN : {
 /* SELECT's tokens */
 /* *************** */
 TOKEN : {
-	< SELECT: "SELECT" >
-|	< QUANTIFIER: "DISTINCT" | "ALL" >
-|	< TOP: "TOP" >
+	< SELECT: "SELECT" >               { matchedToken.adqlReserved = true; }
+|	< QUANTIFIER: "DISTINCT" | "ALL" > { matchedToken.adqlReserved = true; }
+|	< TOP: "TOP" >                     { matchedToken.adqlReserved = true; }
 }
 
 /* ************* */
 /* FROM's tokens */
 /* ************* */
 TOKEN : {
-	< FROM: "FROM" >
-|	< AS: "AS" >
-|	< NATURAL: "NATURAL" >
-|	< INNER: "INNER" >
-|	< OUTER: "OUTER" >
-|	< RIGHT: "RIGHT" >
-|	< LEFT: "LEFT" >
-|	< FULL: "FULL" >
-|	< JOIN: "JOIN" >
-|	< ON: "ON" >
-|	< USING: "USING" >
+	< FROM: "FROM" >       { matchedToken.adqlReserved = true; }
+|	< AS: "AS" >           { matchedToken.adqlReserved = true; }
+|	< NATURAL: "NATURAL" > { matchedToken.adqlReserved = true; }
+|	< INNER: "INNER" >     { matchedToken.adqlReserved = true; }
+|	< OUTER: "OUTER" >     { matchedToken.adqlReserved = true; }
+|	< RIGHT: "RIGHT" >     { matchedToken.adqlReserved = true; }
+|	< LEFT: "LEFT" >       { matchedToken.adqlReserved = true; }
+|	< FULL: "FULL" >       { matchedToken.adqlReserved = true; }
+|	< JOIN: "JOIN" >       { matchedToken.adqlReserved = true; }
+|	< ON: "ON" >           { matchedToken.adqlReserved = true; }
+}
+TOKEN : { 
+	< USING: "USING" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ************** */
 /* WHERE's tokens */
 /* ************** */
 TOKEN : {
-	< WHERE: "WHERE" >
-|	< AND: "AND" >
-|	< OR: "OR" >
-|	< NOT: "NOT" >
-|	< IS: "IS" >
-|	< NULL: "NULL" >
-|	< BETWEEN: "BETWEEN" >
-|	< LIKE: "LIKE" >
-|	< IN: "IN" >
-|	< EXISTS: "EXISTS" >
+	< WHERE: "WHERE" >     { matchedToken.adqlReserved = true; }
+|	< AND: "AND" >         { matchedToken.adqlReserved = true; }
+|	< OR: "OR" >           { matchedToken.adqlReserved = true; }
+|	< NOT: "NOT" >         { matchedToken.adqlReserved = true; }
+|	< IS: "IS" >           { matchedToken.adqlReserved = true; }
+|	< NULL: "NULL" >       { matchedToken.adqlReserved = true; }
+|	< BETWEEN: "BETWEEN" > { matchedToken.adqlReserved = true; }
+|	< LIKE: "LIKE" >       { matchedToken.adqlReserved = true; }
+}
+TOKEN : { 
+	< IN: "IN" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< EXISTS: "EXISTS" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ********************* */
 /* Other clauses' tokens */
 /* ********************* */
 TOKEN : {
-	< BY: "BY" >
-|	< GROUP: "GROUP" >
-|	< HAVING: "HAVING" >
-|	< ORDER: "ORDER" >
-|	< ASC: "ASC" >
-|	< DESC: "DESC" >
+	< BY: "BY" >         { matchedToken.adqlReserved = true; }
+|	< GROUP: "GROUP" >   { matchedToken.adqlReserved = true; }
+|	< HAVING: "HAVING" > { matchedToken.adqlReserved = true; }
+|	< ORDER: "ORDER" >   { matchedToken.adqlReserved = true; }
+|	< ASC: "ASC" >       { matchedToken.adqlReserved = true; }
+|	< DESC: "DESC" >     { matchedToken.adqlReserved = true; }
 }
 
 /* ************* */
 /* SQL functions */
 /* ************* */
 TOKEN : {
-	< AVG: "AVG" >
-|	< MAX: "MAX" >
-|	< MIN: "MIN" >
-|	< SUM: "SUM" >
-|	< COUNT: "COUNT" >
+	< AVG: "AVG" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MAX: "MAX" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MIN: "MIN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SUM: "SUM" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COUNT: "COUNT" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ************** */
 /* ADQL functions */
 /* ************** */
 TOKEN : {
-	< BOX: "BOX" >
-|	< CENTROID: "CENTROID" >
-|	< CIRCLE: "CIRCLE" >
-|	< POINT: "POINT" >
-|	< POLYGON: "POLYGON" >
-|	< REGION: "REGION" >
-
-|	< CONTAINS: "CONTAINS" >
-|	< INTERSECTS: "INTERSECTS" >
-|	< AREA: "AREA" >
-|	< COORD1: "COORD1" >
-|	< COORD2: "COORD2" >
-|	< COORDSYS: "COORDSYS" >
-|	< DISTANCE: "DISTANCE" >
+	< BOX: "BOX" >               { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CENTROID: "CENTROID" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CIRCLE: "CIRCLE" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POINT: "POINT" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POLYGON: "POLYGON" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< REGION: "REGION" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+
+|	< CONTAINS: "CONTAINS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< INTERSECTS: "INTERSECTS" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< AREA: "AREA" >             { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORD1: "COORD1" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORD2: "COORD2" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORDSYS: "COORDSYS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< DISTANCE: "DISTANCE" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ********************** */
 /* Mathematical functions */
 /* ********************** */
 TOKEN : {
-	< ABS: "ABS" >
-|	< CEILING: "CEILING" >
-|	< DEGREES: "DEGREES" >
-|	< EXP: "EXP" >
-|	< FLOOR: "FLOOR" >
-|	< LOG: "LOG" >
-|	< LOG10: "LOG10" >
-|	< MOD: "MOD" >
-|	< PI: "PI" >
-|	< POWER: "POWER" >
-|	< RADIANS: "RADIANS" >
-|	< RAND: "RAND" >
-|	< ROUND: "ROUND" >
-|	< SQRT: "SQRT" >
-|	< TRUNCATE: "TRUNCATE" >
+	< ABS: "ABS" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CEILING: "CEILING" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< DEGREES: "DEGREES" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< EXP: "EXP" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< FLOOR: "FLOOR" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< LOG: "LOG" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< LOG10: "LOG10" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MOD: "MOD" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< PI: "PI" >             { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POWER: "POWER" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< RADIANS: "RADIANS" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< RAND: "RAND" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ROUND: "ROUND" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SQRT: "SQRT" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< TRUNCATE: "TRUNCATE" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ************************* */
 /* Trigonometrical functions */
 /* ************************* */
 TOKEN : {
-	< ACOS: "ACOS" >
-|	< ASIN: "ASIN" >
-|	< ATAN: "ATAN" >
-|	< ATAN2: "ATAN2" >
-|	< COS: "COS" >
-|	< COT: "COT" >
-|	< SIN: "SIN" >
-|	< TAN: "TAN" >
+	< ACOS: "ACOS" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ASIN: "ASIN" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ATAN: "ATAN" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ATAN2: "ATAN2" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COS: "COS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COT: "COT" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SIN: "SIN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< TAN: "TAN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
 }
 
 /* ******* */
@@ -1229,7 +1170,7 @@ TOKEN : {
 /* GENERAL ADQL SYNTAX */
 /* ******************* */
 /**
-* Parses the ADQL query given at the parser creation or in the {@link ADQLParser#ReInit(java.io.InputStream)}
+* Parses the ADQL query given at the parser creation or in the {@link ADQLParser200#ReInit(java.io.InputStream)}
 * or in the <i>parseQuery</i> functions.
 *
 * @return					The object representation of the query.
@@ -2177,7 +2118,7 @@ UserDefinedFunction UserDefinedFunction(): {Token fct, end; Vector<ADQLOperand>
 		if (!isRegularIdentifier(fct.image))
 			throw new ParseException("Invalid (User Defined) Function name: \""+fct.image+"\"!", new TextPosition(fct));
 		
-		//System.out.println("INFO [ADQLParser]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
+		//System.out.println("INFO [ADQLParser200]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
 		
 		try{
 			//  Build the parameters list:
diff --git a/src/adql/parser/adqlGrammar201.jj b/src/adql/parser/adqlGrammar201.jj
new file mode 100644
index 0000000000000000000000000000000000000000..55393f8062b6f7761ec45912a6716b6f322958ae
--- /dev/null
+++ b/src/adql/parser/adqlGrammar201.jj
@@ -0,0 +1,2177 @@
+/*
+ * This file is part of ADQLLibrary.
+ * 
+ * ADQLLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * ADQLLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ */
+
+/*
+* This JavaCC file implements the BNF definition of ADQL v2.1
+* (IVOA Proposed Recommendation 12 January 2018 -
+*  http://www.ivoa.net/documents/ADQL/20180112/index.html).
+* 
+* To generate the parser with this file use JavaCC. This .jj file has been
+* successfully tested with JavaCC 6.0.
+* 
+* The generated parser checks the syntax of the given ADQL query and generates
+* an object representation but no coherence with any database is done.
+* If the syntax is not conform to the ADQL definition an error message is
+* printed else it will be the message "Correct syntax".
+*
+*  Author:  Gr&eacute;gory Mantelet (CDS)
+*  Version: 2.0 (04/2019)
+*/
+
+							/* ########### */
+							/* # OPTIONS # */
+							/* ########### */
+options {
+	STATIC = false;
+	IGNORE_CASE = true;
+	DEBUG_PARSER = true;
+	KEEP_LINE_COLUMN = true;
+	COMMON_TOKEN_ACTION = true;
+}
+
+							/* ########## */
+							/* # PARSER # */
+							/* ########## */
+PARSER_BEGIN(ADQLParser201)
+
+package adql.parser;
+
+/*
+ * This file is part of ADQLLibrary.
+ * 
+ * ADQLLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * ADQLLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ */
+
+import java.util.Stack;
+import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+import adql.db.exception.UnresolvedIdentifiersException;
+
+import adql.parser.IdentifierItems.IdentifierItem;
+
+import adql.parser.ADQLQueryFactory.JoinType;
+
+import adql.query.*;
+import adql.query.from.*;
+import adql.query.constraint.*;
+
+import adql.query.operand.*;
+
+import adql.query.operand.function.*;
+
+import adql.query.operand.function.string.*;
+
+import adql.query.operand.function.geometry.*;
+import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;
+
+import adql.translator.PostgreSQLTranslator;
+import adql.translator.TranslationException;
+
+/**
+* Parses an ADQL-2.1 query thanks to the {@link ADQLParser201#Query() Query()} function.
+* 
+* <p>
+*   This parser is able, thanks to a {@link QueryChecker} object, to check each
+*   {@link ADQLQuery} just after its generation. It could be used to check the
+*   consistency between the ADQL query to parse and the "database" on which the
+*   query must be executed. By default, there is no {@link QueryChecker}. Thus
+*   you must extend {@link QueryChecker} to check semantically all generated
+*   ADQLQuery objects.
+* </p>
+* 
+* <p>
+*   To create an object representation of the given ADQL query, this parser uses
+*   a {@link ADQLQueryFactory} object. So if you want customize some object
+*   (ie. CONTAINS) of this representation you just have to extend the
+*   corresponding default object (ie. ContainsFunction) and to extend the
+*   corresponding function of {@link ADQLQueryFactory}
+*   (ie. createContains(...)).
+* </p>
+*
+* <p>Here are the key functions to use:</p>
+* <ul>
+* 	<li>{@link #parseQuery(java.lang.String)} (or any of its alternatives)
+* 		to parse an input ADQL query String and get its corresponding ADQL tree
+*   </li>
+*   <li>{@link #tryQuickFix(java.lang.String)} to try fixing the most common
+* 		issues with ADQL queries (e.g. Unicode confusable characters,
+* 		unescaped ADQL identifiers, SQL reserved keywords, ...)</li>
+* </ul>
+* 
+* <p><b><u>WARNING:</u>
+*   To modify this class it's strongly encouraged to modify the .jj file in the
+*   section between <i>PARSER_BEGIN</i> and <i>PARSER_END</i> and to re-compile
+*   it with JavaCC.
+* </b></p>
+*
+* @see QueryChecker
+* @see ADQLQueryFactory
+*
+* @author Gr&eacute;gory Mantelet (CDS)
+* @version 2.0 (04/2019)
+* @since 2.0
+*/
+public class ADQLParser201 implements ADQLParser {
+	
+	/** Tools to build the object representation of the ADQL query. */
+	private ADQLQueryFactory queryFactory = new ADQLQueryFactory();
+	
+	/** The stack of queries (because there may be some sub-queries). */
+	private Stack<ADQLQuery> stackQuery = new Stack<ADQLQuery>();
+	
+	/** The object representation of the ADQL query to parse.
+	 * (ONLY USED DURING THE PARSING, else it is always <i>null</i>). */
+	private ADQLQuery query = null;
+	
+	/** Checks each {@link ADQLQuery} (sub-query or not) just after their
+	 * generation. */
+	private QueryChecker queryChecker = null;
+	
+	/**
+	* Builds an ADQL parser without a query to parse.
+	*/
+	public ADQLParser201(){
+		this(new java.io.ByteArrayInputStream("".getBytes()));
+		setDebug(false);
+	}
+	
+	/**
+	* Builds an ADQL parser without a query to parse but with a
+	* {@link QueryChecker} and a {@link ADQLQueryFactory}.
+	*
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	* @param factory	The object to use to build an object representation of
+	*               	the given ADQL query.
+	*/
+	public ADQLParser201(QueryChecker checker, ADQLQueryFactory factory) {
+		this();
+		
+		queryChecker = checker;
+			
+		if (factory != null)
+			queryFactory = factory;
+	}
+	
+	/**
+	* Builds an ADQL parser without a query to parse but with a
+	* {@link QueryChecker}.
+	*
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	*/
+	public ADQLParser201(QueryChecker checker) {
+		this(checker, null);
+	}
+	
+	/**
+	* Builds an ADQL parser without a query to parse but with a
+	* {@link ADQLQueryFactory}.
+	*
+	* @param factory	The object to use to build an object representation of
+	*               	the given ADQL query.
+	*/
+	public ADQLParser201(ADQLQueryFactory factory) {
+		this((QueryChecker)null, factory);
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	* @param factory	The object to use to build an object representation of
+	*               	the given ADQL query.
+	*/
+	public ADQLParser201(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) {
+		this(stream);
+		setDebug(false);
+		
+		setDebug(false);
+		
+		queryChecker = checker;
+		
+		if (factory != null)
+			queryFactory = factory;
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	*/
+	public ADQLParser201(java.io.InputStream stream, QueryChecker checker) {
+		this(stream, checker, null);
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param factory	The object to use to build an object representation of
+	*               	the given ADQL query.
+	*/
+	public ADQLParser201(java.io.InputStream stream, ADQLQueryFactory factory) {
+		this(stream, (QueryChecker)null, factory);
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param encoding	The supplied encoding.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	* @param factory	The object to use to build an object representation
+	*               	of the given ADQL query.
+	*/
+	public ADQLParser201(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) {
+		this(stream, encoding);
+		setDebug(false);
+		
+		queryChecker = checker;
+		
+		if (factory != null)
+			queryFactory = factory;
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param encoding	The supplied encoding.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	*/
+	public ADQLParser201(java.io.InputStream stream, String encoding, QueryChecker checker) {
+		this(stream, encoding, checker, null);
+	}
+	
+	/**
+	* Builds a parser with a stream containing the query to parse.
+	*
+	* @param stream		The stream in which the ADQL query to parse is given.
+	* @param encoding	The supplied encoding.
+	* @param factory	The object to use to build an object representation
+	*               	of the given ADQL query.
+	*/
+	public ADQLParser201(java.io.InputStream stream, String encoding, ADQLQueryFactory factory) {
+		this(stream, encoding, null, factory);
+	}
+	
+	/**
+	* Builds a parser with a reader containing the query to parse.
+	*
+	* @param reader		The reader in which the ADQL query to parse is given.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	* @param factory	The object to use to build an object representation
+	*               	of the given ADQL query.
+	*/
+	public ADQLParser201(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory) {
+		this(reader);
+		setDebug(false);
+		
+		setDebug(false);
+		
+		queryChecker = checker;
+
+		if (factory != null)
+			queryFactory = factory;
+	}
+	
+	/**
+	* Builds a parser with a reader containing the query to parse.
+	*
+	* @param reader		The reader in which the ADQL query to parse is given.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	*/
+	public ADQLParser201(java.io.Reader reader, QueryChecker checker) {
+		this(reader, checker, null);
+	}
+	
+	/**
+	* Builds a parser with a reader containing the query to parse.
+	*
+	* @param reader		The reader in which the ADQL query to parse is given.
+	* @param factory	The object to use to build an object representation
+	*               	of the given ADQL query.
+	*/
+	public ADQLParser201(java.io.Reader reader, ADQLQueryFactory factory) {
+		this(reader, null, factory);
+	}
+	
+	/**
+	* Builds a parser with another token manager.
+	*
+	* @param tm			The manager which associates a token to a numeric code.
+	* @param checker	The object to use to check each {@link ADQLQuery }.
+	* @param factory	The object to use to build an object representation
+	*               	of the given ADQL query.
+	*/
+	public ADQLParser201(ADQLParser201TokenManager tm, QueryChecker checker, ADQLQueryFactory factory) {
+		this(tm);
+		setDebug(false);
+		
+		setDebug(false);
+		
+		queryChecker = checker;
+
+		if (factory != null)
+			queryFactory = factory;
+	}
+	
+	/**
+	* Builds a parser with another token manager.
+	*
+	* @param tm			The manager which associates a token to a numeric code.
+	* @param checker	The object to use to check each {@link ADQLQuery}.
+	*/
+	public ADQLParser201(ADQLParser201TokenManager tm, QueryChecker checker) {
+		this(tm, checker, null);
+	}
+	
+	/**
+	* Builds a parser with another token manager.
+	*
+	* @param tm			The manager which associates a token to a numeric code.
+	* @param factory	The object to use to build an object representation of
+	*               	the given ADQL query.
+	*/
+	public ADQLParser201(ADQLParser201TokenManager tm, ADQLQueryFactory factory) {
+		this(tm, null, factory);
+	}
+
+	/* ADDITIONAL GETTERS & SETTERS */
+	
+	public final void setDebug(boolean debug){
+		if (debug) enable_tracing();
+		else       disable_tracing();
+	}
+	
+	public final QueryChecker getQueryChecker(){
+		return queryChecker;
+	}
+	
+	public final void setQueryChecker(QueryChecker checker){
+		queryChecker = checker;
+	}
+	
+	public final ADQLQueryFactory getQueryFactory(){
+		return queryFactory;
+	}
+	
+	public final void setQueryFactory(ADQLQueryFactory factory){
+		queryFactory = (factory!=null)?factory:(new ADQLQueryFactory());
+	}
+
+	/* EXCEPTION HELPER FUNCTION */
+	
+	private final ParseException generateParseException(Exception ex){
+		if (!(ex instanceof ParseException)){
+			ParseException pex = new ParseException("["+ex.getClass().getName()+"] "+ex.getMessage());
+			pex.setStackTrace(ex.getStackTrace());
+			return pex;
+		}else
+			return (ParseException)ex;
+	}
+
+	/* QUERY PARSING FUNCTIONS */
+
+	/**
+	 * Tell whether the given string is a valid ADQL regular identifier.
+	 *
+	 * <p>
+	 * 	According to the ADQL-2.0's BNF, a regular identifier (i.e. not delimited
+	 * 	; not between double quotes) must be a letter followed by a letter, digit
+	 * 	or underscore. So, the following regular expression:
+	 * </p>
+	 * <pre>[a-zA-Z]+[a-zA-Z0-9_]*</pre>
+	 *
+	 * <p>This is what this function tests on the given string.</p>
+	 *
+	 * @param idCandidate	The string to test.
+	 *
+	 * @return	<code>true</code> if the given string is a valid regular
+	 *        	identifier,
+	 *        	<code>false</code> otherwise.
+	 *
+	 * @see #testRegularIdentifier(adql.parser.Token)
+	 *
+	 * @since 1.5
+	 */
+	public final boolean isRegularIdentifier(final String idCandidate) {
+		return idCandidate.matches("[a-zA-Z]+[a-zA-Z0-9_]*");
+	}
+
+	/**
+	 * Test the given token as an ADQL's regular identifier.
+	 *
+	 * <p>
+	 * 	This function uses {@link #isRegularIdentifier(java.lang.String)} to
+	 * 	test the given token's image. If the test fails, a
+	 * 	{@link adql.parser.ParseException} is thrown.
+	 * </p>
+	 *
+	 * @param token	The token to test.
+	 *
+	 * @throws ParseException	If the given token is not a valid ADQL regular
+	 *                       	identifier.
+	 *
+	 * @see #isRegularIdentifier(java.lang.String)
+	 *
+	 * @since 1.5
+	 */
+	public final void testRegularIdentifier(final Token token) throws ParseException {
+		if (!isRegularIdentifier(token.image))
+			throw new ParseException("Invalid ADQL regular identifier: \""+token.image+"\"! If it aims to be a column/table name/alias, you should write it between double quotes.", new TextPosition(token));
+	}
+	
+	/**
+	* Parses the query given at the creation of this parser or in the
+	* <i>ReInit</i> functions.
+	*
+	* @return 	The object representation of the given ADQL query.
+	* 
+	* @throws ParseException	If there is at least one syntactic error.
+	*
+	* @see ADQLParser201#Query()
+	*/
+	public final ADQLQuery parseQuery() throws ParseException {
+		stackQuery.clear();
+		query = null;
+		try { 
+			return Query();
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}
+	}
+	
+	/**
+	* Parses the query given in parameter.
+	*
+	* @param q	The ADQL query to parse.
+	* 
+	* @return	The object representation of the given ADQL query.
+	* 
+	* @throws ParseException	If there is at least one syntactic error.
+	*
+	* @see ADQLParser201#ReInit(java.io.InputStream)
+	* @see ADQLParser201#setDebug(boolean)
+	* @see ADQLParser201#Query()
+	*/
+	public final ADQLQuery parseQuery(String q) throws ParseException {
+		stackQuery.clear();
+		query = null;
+		ReInit(new java.io.ByteArrayInputStream(q.getBytes()));
+		try { 
+			return Query();
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}
+	}
+	
+	/**
+	* Parses the query contained in the stream given in parameter.
+	*
+	* @param stream		The stream which contains the ADQL query to parse.
+	* 
+	* @return	The object representation of the given ADQL query.
+	* 
+	* @throws ParseException	If there is at least one syntactic error.
+	*
+	* @see ADQLParser201#ReInit(java.io.InputStream)
+	* @see ADQLParser201#setDebug(boolean)
+	* @see ADQLParser201#Query()
+	*/
+	public final ADQLQuery parseQuery(java.io.InputStream stream) throws ParseException {
+		stackQuery.clear();
+		query = null;
+		ReInit(stream);
+		try { 
+			return Query();
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}
+	}
+
+	@Override
+	public final ClauseSelect parseSelect(java.lang.String adql) throws ParseException {
+	    // Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a SELECT clause:
+			Select();
+
+			// Return what's just got parsed:
+			return query.getSelect();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final FromContent parseFrom(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a FROM clause:
+			From();
+
+			// Return what's just got parsed:
+			return query.getFrom();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseConstraints parseWhere(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a WHERE clause:
+			Where();
+
+			// Return what's just got parsed:
+			return query.getWhere();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseADQL<ADQLOrder> parseOrderBy(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a ORDER BY clause:
+			OrderBy();
+
+			// Return what's just got parsed:
+			return query.getOrderBy();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	
+	@Override
+	public final ClauseADQL<ADQLColumn> parseGroupBy(java.lang.String adql) throws ParseException {
+		// Set the string to parse:
+		ReInit(new java.io.ByteArrayInputStream(adql.getBytes()));
+		
+		try {
+			// Create the query:
+			query = queryFactory.createQuery();
+
+			// Parse the string as a GROUP BY clause:
+			GroupBy();
+
+			// Return what's just got parsed:
+			return query.getGroupBy();
+			
+		}catch(TokenMgrError tme) {
+			throw new ParseException(tme);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+
+	/* CORRECTION SUGGESTION */
+
+	/**
+	 * Try fixing tokens/terms of the input ADQL query.
+	 *
+	 * <p>
+	 * 	<b>This function does not try to fix syntactical or semantical errors.</b>
+	 *  It just try to fix the most common issues in ADQL queries, such as:
+	 * </p>
+	 * <ul>
+	 * 	<li>some Unicode characters confusable with ASCII characters (like a
+	 * 		space, a dash, ...) ; this function replace them by their ASCII
+	 * 		alternative,</li>
+	 * 	<li>any of the following are double quoted:
+	 * 		<ul>
+	 * 			<li>non regular ADQL identifiers
+	 * 				(e.g. <code>_RAJ2000</code>),</li>
+	 * 			<li>ADQL function names used as identifiers
+	 * 				(e.g. <code>distance</code>)</li>
+	 * 			<li>and SQL reserved keywords
+	 * 				(e.g. <code>public</code>).</li>
+	 * 		</ul>
+	 * 	</li>
+	 * </ul>
+	 *
+	 * <p><i><b>Note 1:</b>
+	 * 	The given stream is NOT closed by this function even if the EOF is
+	 * 	reached. It is the responsibility of the caller to close it.
+	 * </i></p>
+	 *
+	 * <p><i><b>Note 2:</b>
+	 * 	This function does not use any instance variable of this parser
+	 * 	(especially the InputStream or Reader provided at initialisation or
+	 * 	ReInit).
+	 * </i></p>
+	 *
+	 * @param input	Stream containing the input ADQL query to fix.
+	 *
+	 * @return	The suggested correction of the input ADQL query.
+	 *
+	 * @throws java.io.IOException	If there is any error while reading from the
+	 *                            	given input stream.
+	 * @throws ParseException	If any unrecognised character is encountered,
+	 *                       	or if anything else prevented the tokenization
+	 *                       	   of some characters/words/terms.
+	 *
+	 * @see #tryQuickFix(java.lang.String)
+	 *
+	 * @since 1.5
+	 */
+	public final String tryQuickFix(final java.io.InputStream input) throws java.io.IOException, ParseException {
+		// Fetch everything into a single string:
+		StringBuffer buf = new StringBuffer();
+		byte[] cBuf = new byte[1024];
+		int nbChar;
+		while((nbChar = input.read(cBuf)) > -1){
+			buf.append(new String(cBuf, 0, nbChar));
+		}
+		
+		// Convert the buffer into a String and now try to fix it:
+		return tryQuickFix(buf.toString());
+	}
+
+	/**
+	 * Try fixing tokens/terms of the given ADQL query.
+	 *
+	 * <p>
+	 * 	<b>This function does not try to fix syntactical or semantical errors.</b>
+	 *  It just try to fix the most common issues in ADQL queries, such as:
+	 * </p>
+	 * <ul>
+	 * 	<li>some Unicode characters confusable with ASCII characters (like a
+	 * 		space, a dash, ...) ; this function replace them by their ASCII
+	 * 		alternative,</li>
+	 * 	<li>any of the following are double quoted:
+	 * 		<ul>
+	 * 			<li>non regular ADQL identifiers
+	 * 				(e.g. <code>_RAJ2000</code>),</li>
+	 * 			<li>ADQL function names used as identifiers
+	 * 				(e.g. <code>distance</code>)</li>
+	 * 			<li>and SQL reserved keywords
+	 * 				(e.g. <code>public</code>).</li>
+	 * 		</ul>
+	 * 	</li>
+	 * </ul>
+	 *
+	 * <p><i><b>Note:</b>
+	 * 	This function does not use any instance variable of this parser
+	 * 	(especially the InputStream or Reader provided at initialisation or
+	 * 	ReInit).
+	 * </i></p>
+	 *
+	 * @param adqlQuery	The input ADQL query to fix.
+	 *
+	 * @return	The suggested correction of the given ADQL query.
+	 *
+	 * @throws ParseException	If any unrecognised character is encountered,
+	 *                       	or if anything else prevented the tokenization
+	 *                       	   of some characters/words/terms.
+	 *
+	 * @since 1.5
+	 */
+	public String tryQuickFix(String adqlQuery) throws ParseException {
+		StringBuffer suggestedQuery = new StringBuffer();
+
+		// 1. Replace all Unicode confusable characters:
+		adqlQuery = replaceUnicodeConfusables(adqlQuery);
+
+		/* 1.bis. Normalise new lines and tabulations
+		 *        (to simplify the column counting): */
+		adqlQuery = adqlQuery.replaceAll("(\r\n|\r|\n)", System.getProperty("line.separator")).replaceAll("\t", "    ");
+
+		// 2. Analyse the query token by token:
+		ADQLParser201TokenManager parser = new ADQLParser201TokenManager(new SimpleCharStream(new java.io.ByteArrayInputStream(adqlQuery.getBytes())));
+		
+		final String[] lines = adqlQuery.split(System.getProperty("line.separator"));
+
+		try{
+			String suggestedToken;
+			int lastLine = 1, lastCol = 1;
+
+			Token token = null, nextToken = parser.getNextToken();
+			// for all tokens until the EOF or EOQ:
+			do{
+				// get the next token:
+				token = nextToken;
+				nextToken = (isEnd(token) ? null : parser.getNextToken());
+
+				// 3. Double quote any suspect token:
+				if (mustEscape(token, nextToken)){
+					suggestedToken = "\"" + token.image + "\"";
+				}else
+					suggestedToken = token.image;
+
+				/* 4. Append all space characters (and comments) before the
+				 *    token: */
+				/* same line, just get the space characters between the last
+				 * token and the one to append: */
+				if (lastLine == token.beginLine){
+					suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1, token.beginColumn - (isEnd(token) ? 0 : 1)));
+					lastCol = token.endColumn + 1;
+				}
+				// not the same line...
+				else{
+				    /* append all remaining space characters until the position
+				     * of the token to append: */
+					do{
+						suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1)).append('\n');
+						lastLine++;
+						lastCol = 1;
+					}while(lastLine < token.beginLine);
+					/* if there are still space characters before the token,
+					 * append them as well: */
+					if (lastCol < token.beginColumn)
+						suggestedQuery.append(lines[lastLine - 1].substring(lastCol - 1, token.beginColumn - 1));
+					// finally, set the correct column position:
+					lastCol = token.endColumn + 1;
+				}
+
+				// 5. Append the suggested token:
+				suggestedQuery.append(suggestedToken);
+
+			}while(!isEnd(token));
+
+		}catch(TokenMgrError err){
+		    // wrap such errors and propagate them:
+			throw new ParseException(err);
+		}
+
+		return suggestedQuery.toString();
+	}
+
+	/**
+	 * All of the most common Unicode confusable characters and their
+	 * ASCII/UTF-8 alternative.
+	 *
+	 * <p>
+	 * 	Keys of this map represent the ASCII character while the values are the
+	 * 	regular expression for all possible Unicode alternatives.
+	 * </p>
+	 *
+	 * <p><i><b>Note:</b>
+	 * 	All of them have been listed using
+	 * 	<a href="https://unicode.org/cldr/utility/confusables.jsp">Unicode Utilities: Confusables</a>.
+	 * </i></p>
+	 *
+	 * @since 1.5
+	 */
+	protected final static java.util.Map<String, String> REGEX_UNICODE_CONFUSABLES = new java.util.HashMap<String, String>(10);
+	/** Regular expression matching all Unicode alternatives for <code>-</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_DASH         = "[\u002D\u02D7\u06D4\u2010\u2011\u2012\u2013\u2043\u2212\u2796\u2CBA\uFE58\u2014\u2015\u207B\u208B\u0096\u058A\uFE63\uFF0D]";
+	/** Regular expression matching all Unicode alternatives for <code>_</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_UNDERSCORE   = "[\u005F\u07FA\uFE4D\uFE4E\uFE4F]";
+	/** Regular expression matching all Unicode alternatives for <code>'</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_QUOTE        = "[\u0027\u0060\u00B4\u02B9\u02BB\u02BC\u02BD\u02BE\u02C8\u02CA\u02CB\u02F4\u0374\u0384\u055A\u055D\u05D9\u05F3\u07F4\u07F5\u144A\u16CC\u1FBD\u1FBF\u1FEF\u1FFD\u1FFE\u2018\u2019\u201B\u2032\u2035\uA78C\uFF07\uFF40]";
+	/** Regular expression matching all Unicode alternatives for <code>"</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_DOUBLE_QUOTE = "[\u02BA\u02DD\u02EE\u02F6\u05F2\u05F4\u1CD3\u201C\u201D\u201F\u2033\u2036\u3003\uFF02]";
+	/** Regular expression matching all Unicode alternatives for <code>.</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_STOP         = "[\u002E\u0660\u06F0\u0701\u0702\u2024\uA4F8\uA60E]";
+	/** Regular expression matching all Unicode alternatives for <code>+</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_PLUS         = "[\u002B\u16ED\u2795]";
+	/** Regular expression matching all Unicode alternatives for <code> </code>.
+	 * @since 1.5 */
+	protected final static String REGEX_SPACE        = "[\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F]";
+	/** Regular expression matching all Unicode alternatives for <code>&lt;</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_LESS_THAN    = "[\u003C\u02C2\u1438\u16B2\u2039\u276E]";
+	/** Regular expression matching all Unicode alternatives for <code>&gt;</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_GREATER_THAN = "[\u003E\u02C3\u1433\u203A\u276F]";
+	/** Regular expression matching all Unicode alternatives for <code>=</code>.
+	 * @since 1.5 */
+	protected final static String REGEX_EQUAL        = "[\u003D\u1400\u2E40\u30A0\uA4FF]";
+	static {
+		REGEX_UNICODE_CONFUSABLES.put("-", REGEX_DASH);
+		REGEX_UNICODE_CONFUSABLES.put("_", REGEX_UNDERSCORE);
+		REGEX_UNICODE_CONFUSABLES.put("'", REGEX_QUOTE);
+		REGEX_UNICODE_CONFUSABLES.put("\"", REGEX_DOUBLE_QUOTE);
+		REGEX_UNICODE_CONFUSABLES.put(".", REGEX_STOP);
+		REGEX_UNICODE_CONFUSABLES.put("+", REGEX_PLUS);
+		REGEX_UNICODE_CONFUSABLES.put(" ", REGEX_SPACE);
+		REGEX_UNICODE_CONFUSABLES.put("<", REGEX_LESS_THAN);
+		REGEX_UNICODE_CONFUSABLES.put(">", REGEX_GREATER_THAN);
+		REGEX_UNICODE_CONFUSABLES.put("=", REGEX_EQUAL);
+	}
+
+	/**
+	 * Replace all Unicode characters that can be confused with other ASCI/UTF-8
+	 * characters (e.g. different spaces, dashes, ...) in their ASCII version.
+	 *
+	 * @param adqlQuery	The ADQL query string in which Unicode confusable
+	 *                 	characters must be replaced.
+	 *
+	 * @return	The same query without the most common Unicode confusable
+	 *        	characters.
+	 *
+	 * @since 1.5
+	 */
+	protected String replaceUnicodeConfusables(final String adqlQuery){
+		String newAdqlQuery = adqlQuery;
+		for(java.util.Map.Entry<String, String> confusable : REGEX_UNICODE_CONFUSABLES.entrySet())
+			newAdqlQuery = newAdqlQuery.replaceAll(confusable.getValue(), confusable.getKey());
+		return newAdqlQuery;
+	}
+
+	/**
+	 * Tell whether the given token represents the end of an ADQL query.
+	 *
+	 * @param token	Token to analyze.
+	 *
+	 * @return	<code>true</code> if the given token represents a query end,
+	 *        	<code>false</code> otherwise.
+	 *
+	 * @since 1.5
+	 */
+	protected boolean isEnd(final Token token){
+		return token.kind == ADQLParser201Constants.EOF || token.kind == ADQLParser201Constants.EOQ;
+	}
+
+	/**
+	 * Tell whether the given token must be double quoted.
+	 *
+	 * <p>
+	 * 	This function considers all the following as terms to double quote:
+	 * </p>
+	 * <ul>
+	 * 	<li>SQL reserved keywords</li>,
+	 * 	<li>unrecognised regular identifiers (e.g. neither a delimited nor a
+	 * 		valid ADQL regular identifier)</li>
+	 * 	<li>and ADQL function name without a parameters list.</li>
+	 * </ul>
+	 *
+	 * @param token		The token to analyze.
+	 * @param nextToken	The following token. (useful to detect the start of a
+	 *                 	function's parameters list)
+	 *
+	 * @return	<code>true</code> if the given token must be double quoted,
+	 *        	<code>false</code> to keep it as provided.
+	 *
+	 * @since 1.5
+	 */
+	protected boolean mustEscape(final Token token, final Token nextToken){
+		switch(token.kind){
+			case ADQLParser201Constants.SQL_RESERVED_WORD:
+				return true;
+			case ADQLParser201Constants.REGULAR_IDENTIFIER_CANDIDATE:
+				return !isRegularIdentifier(token.image);
+			default:
+				return token.isFunctionName && (nextToken == null || nextToken.kind != ADQLParser201Constants.LEFT_PAR);
+		}
+	}
+}
+
+PARSER_END(ADQLParser201)
+
+				/* ################################### */
+				/* # CUSTOMIZATION OF TOKEN CREATION # */
+				/* ################################### */
+
+TOKEN_MGR_DECLS: {
+	protected void CommonTokenAction(final Token t) {
+		t.adqlVersion = ADQLParserFactory.ADQLVersion.V2_1;
+	} 
+}
+
+
+							/* ########### */
+							/* # GRAMMAR # */
+							/* ########### */
+/* ******************** */
+/* Characters to ignore */
+/* ******************** */
+SKIP : { < " " | "\t" | "\n" | "\r" | "\r\n" > }
+
+/* ************************************************************************** */
+/* Reserved SQL words                                                         */
+/*                                                                            */
+/* NOTE:                                                                      */
+/*   This list is the one provided by the ADQL-2.0 standard after removal of  */
+/*   all ADQL used words (e.g. SELECT, AS, LIKE, AVG, ABS, COS, POINT).       */
+/*   (see ParseException.initialise(Token, int[][], String[]) for more        */
+/*   details)                                                                 */
+/* ************************************************************************** */
+
+TOKEN : {
+	< SQL_RESERVED_WORD: ("ABSOLUTE"|"ACTION"|"ADD"|"ALLOCATE"|"ALTER"|"ANY"|"ARE"|"ASSERTION"|"AT"|"AUTHORIZATION"|"BEGIN"|"BIT"|"BIT_LENGTH"|"BOTH"|"CASCADE"|"CASCADED"|"CASE"|"CAST"|"CATALOG"|"CHAR"|"CHARACTER"|"CHAR_LENGTH"|"CHARACTER_LENGTH"|"CHECK"|"CLOSE"|"COALESCE"|"COLLATE"|"COLLATION"|"COLUMN"|"COMMIT"|"CONNECT"|"CONNECTION"|"CONSTRAINT"|"CONSTRAINTS"|"CONTINUE"|"CONVERT"|"CORRESPONDING"|"CREATE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_USER"|"CURSOR"|"DATE"|"DAY"|"DEALLOCATE"|"DECIMAL"|"DECLARE"|"DEFAULT"|"DEFERRABLE"|"DEFERRED"|"DELETE"|"DESCRIBE"|"DESCRIPTOR"|"DIAGNOSTICS"|"DISCONNECT"|"DOMAIN"|"DOUBLE"|"DROP"|"ELSE"|"END"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXCEPTION"|"EXEC"|"EXECUTE"|"EXTERNAL"|"EXTRACT"|"FALSE"|"FETCH"|"FIRST"|"FLOAT"|"FOR"|"FOREIGN"|"FOUND"|"GET"|"GLOBAL"|"GO"|"GOTO"|"GRANT"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"INDICATOR"|"INITIALLY"|"INPUT"|"INSENSITIVE"|"INSERT"|"INT"|"INTEGER"|"INTERSECT"|"INTERVAL"|"INTO"|"ISOLATION"|"KEY"|"LANGUAGE"|"LAST"|"LEADING"|"LEVEL"|"LOCAL"|"MATCH"|"MINUTE"|"MODULE"|"MONTH"|"NAMES"|"NATIONAL"|"NCHAR"|"NEXT"|"NO"|"NULLIF"|"NUMERIC"|"OCTET_LENGTH"|"OF"|"ONLY"|"OPEN"|"OPTION"|"OUTPUT"|"OVERLAPS"|"PAD"|"PARTIAL"|"POSITION"|"PRECISION"|"PREPARE"|"PRESERVE"|"PRIMARY"|"PRIOR"|"PRIVILEGES"|"PROCEDURE"|"PUBLIC"|"READ"|"REAL"|"REFERENCES"|"RELATIVE"|"RESTRICT"|"REVOKE"|"ROLLBACK"|"ROWS"|"SCHEMA"|"SCROLL"|"SECOND"|"SECTION"|"SESSION"|"SESSION_USER"|"SET"|"SIZE"|"SMALLINT"|"SOME"|"SPACE"|"SQL"|"SQLCODE"|"SQLERROR"|"SQLSTATE"|"SUBSTRING"|"SYSTEM_USER"|"TABLE"|"TEMPORARY"|"THEN"|"TIME"|"TIMESTAMP"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSACTION"|"TRANSLATE"|"TRANSLATION"|"TRIM"|"TRUE"|"UNION"|"UNIQUE"|"UNKNOWN"|"UPDATE"|"UPPER"|"USAGE"|"USER"|"VALUE"|"VALUES"|"VARCHAR"|"VARYING"|"VIEW"|"WHEN"|"WHENEVER"|"WITH"|"WORK"|"WRITE"|"YEAR"|"ZONE") >
+	{ matchedToken.sqlReserved = true; }
+}
+
+/* *********** */
+/* Punctuation */
+/* *********** */
+TOKEN : {
+	< LEFT_PAR: "(" >
+|	< RIGHT_PAR: ")" > 
+|	< DOT: "." >
+|	< COMMA: "," >
+|	< EOQ: ";">
+|	< CONCAT: "||" >
+}
+
+/* ******************** */
+/* Arithmetic operators */
+/* ******************** */
+TOKEN : {
+	< PLUS: "+" >
+|	< MINUS: "-" >
+|	< ASTERISK: "*" >
+|	< DIVIDE: "/" >
+}
+
+/* ******************** */
+/* Comparison operators */
+/* ******************** */
+TOKEN : {
+	< EQUAL: "=" >
+|	< NOT_EQUAL: "<>" | "!=" >
+|	< LESS_THAN: "<" >
+|	< LESS_EQUAL_THAN: "<=" >
+|	< GREATER_THAN: ">" >
+|	< GREATER_EQUAL_THAN: ">=" >
+}
+
+/* *************** */
+/* SELECT's tokens */
+/* *************** */
+TOKEN : {
+	< SELECT: "SELECT" >               { matchedToken.adqlReserved = true; }
+|	< QUANTIFIER: "DISTINCT" | "ALL" > { matchedToken.adqlReserved = true; }
+|	< TOP: "TOP" >                     { matchedToken.adqlReserved = true; }
+}
+
+/* ************* */
+/* FROM's tokens */
+/* ************* */
+TOKEN : {
+	< FROM: "FROM" >       { matchedToken.adqlReserved = true; }
+|	< AS: "AS" >           { matchedToken.adqlReserved = true; }
+|	< NATURAL: "NATURAL" > { matchedToken.adqlReserved = true; }
+|	< INNER: "INNER" >     { matchedToken.adqlReserved = true; }
+|	< OUTER: "OUTER" >     { matchedToken.adqlReserved = true; }
+|	< RIGHT: "RIGHT" >     { matchedToken.adqlReserved = true; }
+|	< LEFT: "LEFT" >       { matchedToken.adqlReserved = true; }
+|	< FULL: "FULL" >       { matchedToken.adqlReserved = true; }
+|	< JOIN: "JOIN" >       { matchedToken.adqlReserved = true; }
+|	< ON: "ON" >           { matchedToken.adqlReserved = true; }
+}
+TOKEN : { 
+	< USING: "USING" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ************** */
+/* WHERE's tokens */
+/* ************** */
+TOKEN : {
+	< WHERE: "WHERE" >     { matchedToken.adqlReserved = true; }
+|	< AND: "AND" >         { matchedToken.adqlReserved = true; }
+|	< OR: "OR" >           { matchedToken.adqlReserved = true; }
+|	< NOT: "NOT" >         { matchedToken.adqlReserved = true; }
+|	< IS: "IS" >           { matchedToken.adqlReserved = true; }
+|	< NULL: "NULL" >       { matchedToken.adqlReserved = true; }
+|	< BETWEEN: "BETWEEN" > { matchedToken.adqlReserved = true; }
+|	< LIKE: "LIKE" >       { matchedToken.adqlReserved = true; }
+}
+TOKEN : { 
+	< IN: "IN" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< EXISTS: "EXISTS" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ********************* */
+/* Other clauses' tokens */
+/* ********************* */
+TOKEN : {
+	< BY: "BY" >         { matchedToken.adqlReserved = true; }
+|	< GROUP: "GROUP" >   { matchedToken.adqlReserved = true; }
+|	< HAVING: "HAVING" > { matchedToken.adqlReserved = true; }
+|	< ORDER: "ORDER" >   { matchedToken.adqlReserved = true; }
+|	< ASC: "ASC" >       { matchedToken.adqlReserved = true; }
+|	< DESC: "DESC" >     { matchedToken.adqlReserved = true; }
+}
+
+/* ************* */
+/* SQL functions */
+/* ************* */
+TOKEN : {
+	< AVG: "AVG" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MAX: "MAX" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MIN: "MIN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SUM: "SUM" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COUNT: "COUNT" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ************** */
+/* ADQL functions */
+/* ************** */
+TOKEN : {
+	< BOX: "BOX" >               { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CENTROID: "CENTROID" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CIRCLE: "CIRCLE" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POINT: "POINT" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POLYGON: "POLYGON" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< REGION: "REGION" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+
+|	< CONTAINS: "CONTAINS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< INTERSECTS: "INTERSECTS" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< AREA: "AREA" >             { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORD1: "COORD1" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORD2: "COORD2" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COORDSYS: "COORDSYS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< DISTANCE: "DISTANCE" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ********************** */
+/* String functions */
+/* ********************** */
+TOKEN : {
+	< LOWER: "LOWER" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ********************** */
+/* Mathematical functions */
+/* ********************** */
+TOKEN : {
+	< ABS: "ABS" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< CEILING: "CEILING" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< DEGREES: "DEGREES" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< EXP: "EXP" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< FLOOR: "FLOOR" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< LOG: "LOG" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< LOG10: "LOG10" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< MOD: "MOD" >           { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< PI: "PI" >             { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< POWER: "POWER" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< RADIANS: "RADIANS" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< RAND: "RAND" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ROUND: "ROUND" >       { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SQRT: "SQRT" >         { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< TRUNCATE: "TRUNCATE" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ************************* */
+/* Trigonometrical functions */
+/* ************************* */
+TOKEN : {
+	< ACOS: "ACOS" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ASIN: "ASIN" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ATAN: "ATAN" >   { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< ATAN2: "ATAN2" > { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COS: "COS" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< COT: "COT" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< SIN: "SIN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+|	< TAN: "TAN" >     { matchedToken.adqlReserved = matchedToken.isFunctionName = true; }
+}
+
+/* ******* */
+/* Comment */
+/* ******* */
+SKIP : { < <MINUS><MINUS> (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > }
+
+/* ****** */
+/* String */
+/* ****** */
+<DEFAULT> MORE : { "'" : WithinString }
+<WithinString> MORE : { < ~["'"] | ("''") > }
+<WithinString> TOKEN : { < STRING_LITERAL: "'" >: DEFAULT }
+
+/* *************** */
+/* Primary numbers */
+/* *************** */
+TOKEN : {
+	< SCIENTIFIC_NUMBER: (<UNSIGNED_FLOAT>|<UNSIGNED_INTEGER>) "E" (<PLUS>|<MINUS>)? <UNSIGNED_INTEGER> >
+|	< UNSIGNED_FLOAT: (<UNSIGNED_INTEGER> <DOT> (<UNSIGNED_INTEGER>)?) | (<DOT> <UNSIGNED_INTEGER>) >
+|	< UNSIGNED_INTEGER: (<DIGIT>)+ >
+|	< #DIGIT: ["0"-"9"] >
+}
+
+/* ************************************************* */
+/* Identifier (column, tables, ...) */
+/* ************************************************* */
+<DEFAULT> MORE : { "\"" : WithinDelimitedId }
+<WithinDelimitedId> MORE : { < ~["\""] | ("\"\"") > }
+<WithinDelimitedId> TOKEN : { < DELIMITED_IDENTIFIER: "\"" >: DEFAULT }
+
+TOKEN : {
+	< REGULAR_IDENTIFIER_CANDIDATE: ((<Letter>)+ (<DIGIT> | <Letter>)* | (<DIGIT>)+ <Letter> (<DIGIT> | <Letter>)*) >
+|	< #Letter: ["a"-"z","A"-"Z","_","?","!","$","@","^","#","`","~","[","]","{","}"] >
+}
+
+							/* ########## */
+							/* # SYNTAX # */
+							/* ########## */
+							
+/* ******************* */
+/* GENERAL ADQL SYNTAX */
+/* ******************* */
+/**
+* Parses the ADQL query given at the parser creation or in the {@link ADQLParser201#ReInit(java.io.InputStream)}
+* or in the <i>parseQuery</i> functions.
+*
+* @return					The object representation of the query.
+* @throws ParseException	If the query syntax is incorrect.
+*/
+ADQLQuery Query(): {ADQLQuery q = null;}{
+	q=QueryExpression() (<EOF> | <EOQ>)
+	{
+		// check the query:
+		if (queryChecker != null)
+			queryChecker.check(q);
+			
+		return q;
+	}
+}
+
+ADQLQuery QueryExpression(): {TextPosition endPos = null;} {
+	{
+		try{
+			// create the query:
+			query = queryFactory.createQuery();
+			stackQuery.push(query);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	Select()
+	From()     {endPos = query.getFrom().getPosition();}
+	[Where()   {endPos = query.getWhere().getPosition();}]
+	[GroupBy() {endPos = query.getGroupBy().getPosition();}]
+	[Having()  {endPos = query.getHaving().getPosition();}]
+	[OrderBy() {endPos = query.getOrderBy().getPosition();}]
+	{
+		// set the position of the query:
+		query.setPosition(new TextPosition(query.getSelect().getPosition(), endPos));
+		
+		// get the previous query (!= null if the current query is a sub-query):
+		ADQLQuery previousQuery = stackQuery.pop();
+		if (stackQuery.isEmpty())
+			query = null;
+		else
+			query = stackQuery.peek();
+			
+		return previousQuery;
+	}
+}
+
+ADQLQuery SubQueryExpression(): {ADQLQuery q = null; Token start, end;} {
+	start=<LEFT_PAR> q=QueryExpression() end=<RIGHT_PAR>
+	{
+		q.setPosition(new TextPosition(start, end));
+		return q;
+	}
+}
+
+void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; Token start,t = null;} {
+	start=<SELECT>
+	[t=<QUANTIFIER> {select.setDistinctColumns(t.image.equalsIgnoreCase("DISTINCT"));}]
+	[<TOP> t=<UNSIGNED_INTEGER>
+	 {
+	  try{
+	  	select.setLimit(Integer.parseInt(t.image));
+	  }catch(NumberFormatException nfe){
+	  	throw new ParseException("[l."+t.beginLine+";c."+t.beginColumn+"] The TOP limit (\""+t.image+"\") isn't a regular unsigned integer !");
+	  }
+	 }
+	]
+	
+	item=SelectItem() {select.add(item);}
+	(<COMMA> item=SelectItem() {select.add(item);})*
+	{
+		TextPosition lastItemPos = query.getSelect().get(query.getSelect().size()-1).getPosition();
+		select.setPosition(new TextPosition(start.beginLine, start.beginColumn, lastItemPos.endLine, lastItemPos.endColumn));
+	}
+}
+
+SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} {
+	(
+		( starToken=<ASTERISK>
+		  {
+		    item = new SelectAllColumns(query);
+		    item.setPosition(new TextPosition(starToken));
+		    return item;
+		  }
+		)
+	|LOOKAHEAD(7)
+		(
+			id=Identifier() <DOT> { identifiers.append(id); }
+			(
+				id=Identifier() <DOT> { identifiers.append(id); }
+				(
+					id=Identifier() <DOT> { identifiers.append(id); }
+				)?
+			)?
+			starToken=<ASTERISK>
+			{
+				try{
+					item = new SelectAllColumns( queryFactory.createTable(identifiers, null) );
+					TextPosition firstPos = identifiers.get(0).position;
+					item.setPosition(new TextPosition(firstPos.beginLine, firstPos.beginColumn, starToken.endLine, (starToken.endColumn < 0) ? -1 : (starToken.endColumn + 1)));
+					return item;
+				}catch(Exception ex) {
+					throw generateParseException(ex);
+				}
+			}
+		)
+		
+	| 
+		(op=ValueExpression()[[<AS>] label=Identifier()])
+	)
+	
+	{
+		try{
+			item = queryFactory.createSelectItem(op, (label==null)?null:label.identifier);
+			if (label != null){
+				item.setCaseSensitive(label.caseSensitivity);
+				item.setPosition(new TextPosition(op.getPosition(), label.position));
+			}else
+				item.setPosition(new TextPosition(op.getPosition()));
+			return item;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+void From():{FromContent content = null, content2 = null;}{
+	try{
+		<FROM> content=TableRef()
+		(<COMMA> content2=TableRef()
+		 {
+		   TextPosition startPos = content.getPosition(), endPos = content2.getPosition();
+		   content = queryFactory.createJoin(JoinType.CROSS, content, content2);
+		   content.setPosition(new TextPosition(startPos, endPos));
+		 }
+		)*
+		{ query.setFrom(content); }
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+void Where(): {ClauseConstraints where = query.getWhere(); ADQLConstraint condition; Token start;} {
+	start=<WHERE> ConditionsList(where)
+	{
+	  TextPosition endPosition = where.getPosition();
+	  where.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
+	}
+}
+
+void GroupBy(): {ClauseADQL<ADQLColumn> groupBy = query.getGroupBy(); ADQLColumn colRef = null; Token start;} {
+	start=<GROUP> <BY> colRef=Column() { groupBy.add(colRef); }
+	( <COMMA> colRef=Column() { groupBy.add(colRef); } )*
+	{ groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn)); }
+}
+
+void Having(): {ClauseConstraints having = query.getHaving(); Token start;} {
+	start=<HAVING> ConditionsList(having)
+	{
+	  TextPosition endPosition = having.getPosition();
+	  having.setPosition(new TextPosition(start.beginLine, start.beginColumn, endPosition.endLine, endPosition.endColumn));
+	}
+}
+
+void OrderBy(): {ClauseADQL<ADQLOrder> orderBy = query.getOrderBy(); ADQLOrder order = null; Token start;} {
+	start=<ORDER> <BY> order=OrderItem() {orderBy.add(order);}
+	( <COMMA> order=OrderItem() {orderBy.add(order);} )*
+	{ orderBy.setPosition(new TextPosition(start, token)); }
+}
+
+/* *************************** */
+/* COLUMN AND TABLE REFERENCES */
+/* *************************** */
+IdentifierItem Identifier(): {Token t;} {
+	(
+		t=<REGULAR_IDENTIFIER_CANDIDATE>
+		{
+		  	testRegularIdentifier(t);
+			return new IdentifierItem(t, false);
+		}
+	|
+		t=<DELIMITED_IDENTIFIER>
+		{ return new IdentifierItem(t, true); }
+	)
+}
+
+/**
+ * Extracts the name of a table with its possible catalog and schema prefixes.
+ * 
+ * @return A {@link IdentifierItems} which contains at most three items: catalogName, schemaName and tableName.
+ */
+IdentifierItems TableName(): {IdentifierItems identifiers=new IdentifierItems(true); IdentifierItem id=null;} {
+	(
+		id=Identifier() {identifiers.append(id);}						// catalog
+		(LOOKAHEAD(1) <DOT> id=Identifier() {identifiers.append(id);})?	// schema
+		(LOOKAHEAD(1) <DOT> id=Identifier() {identifiers.append(id);})?	// table
+	)
+	{ return identifiers; }
+}
+
+/**
+ * Extracts the name of a column with its possible catalog, schema and table prefixes.
+ * 
+ * @return A {@link IdentifierItems} which contains at most four items: catalogName, schemaName, tableName and columnName.
+ */
+IdentifierItems ColumnName(): {IdentifierItem id; IdentifierItems table=null, identifiers=new IdentifierItems(false);} {
+	( id=Identifier() (LOOKAHEAD(1) <DOT> table=TableName())? )
+	{
+		identifiers.append(id);
+		if (table != null){
+			for(int i=0; i<table.size(); i++)
+				identifiers.append(table.get(i));
+		}
+		return identifiers;
+	}
+}
+
+ADQLColumn Column(): {IdentifierItems identifiers;} {
+	identifiers = ColumnName()
+	{
+		try{
+			return queryFactory.createColumn(identifiers);
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+ADQLOrder OrderItem(): {IdentifierItem identifier = null; Token ind = null, desc = null;}{
+	(identifier=Identifier() | ind=<UNSIGNED_INTEGER>) (<ASC> | desc=<DESC>)?
+	{
+		try{
+			ADQLOrder order = null;
+			if (identifier != null){
+				order = queryFactory.createOrder(identifier, desc!=null);
+				order.setPosition(identifier.position);
+			}else{
+				order = queryFactory.createOrder(Integer.parseInt(ind.image), desc!=null);
+				order.setPosition(new TextPosition(ind));
+			}
+			return order;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null; Token start,end;} {
+	try{
+		(
+			identifiers=TableName() [[<AS>] alias=Identifier()]
+			{
+			  content = queryFactory.createTable(identifiers, alias);
+			  if (alias == null)
+			  	content.setPosition(new TextPosition(identifiers.get(0).position, identifiers.get(identifiers.size()-1).position));
+			  else
+			  	content.setPosition(new TextPosition(identifiers.get(0).position, alias.position));
+			  return content;
+			}
+		|LOOKAHEAD(2)
+			subQuery=SubQueryExpression() [<AS>] alias=Identifier()
+			{
+			  content = queryFactory.createTable(subQuery, alias);
+			  if (alias == null)
+			  	content.setPosition(new TextPosition(subQuery.getPosition()));
+			  else
+			  	content.setPosition(new TextPosition(subQuery.getPosition(), alias.position));
+			  return content;
+			}
+		|
+			start=<LEFT_PAR> content=JoinedTable() end=<RIGHT_PAR>
+			{
+			  content.setPosition(new TextPosition(start, end));
+			  return content;
+			}
+		)
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+FromContent TableRef(): { FromContent content; } {
+	content=SimpleTableRef()
+	( LOOKAHEAD(2) content=JoinSpecification(content) )*
+	{ return content; }
+}
+
+FromContent JoinedTable(): { FromContent content; } {
+	content=SimpleTableRef()
+	( content=JoinSpecification(content) )+
+	{ return content; }
+}
+
+
+ADQLJoin JoinSpecification(FromContent leftTable): { boolean natural = false; JoinType type = JoinType.INNER;  ClauseConstraints condition = new ClauseConstraints("ON"); ArrayList<ADQLColumn> lstColumns=new ArrayList<ADQLColumn>(); IdentifierItem id; FromContent rightTable; ADQLJoin join; Token lastPar;} {
+	try{
+		(
+			<NATURAL> {natural=true;} [<INNER> | ((<LEFT> {type = JoinType.OUTER_LEFT;}|<RIGHT> {type = JoinType.OUTER_RIGHT;}|<FULL> {type = JoinType.OUTER_FULL;}) [<OUTER>])] <JOIN> rightTable=SimpleTableRef()
+			{
+			  join = queryFactory.createJoin(type, leftTable, rightTable);
+			  join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition()));
+			  return join;
+			}
+		|
+			[<INNER> | ((<LEFT> {type = JoinType.OUTER_LEFT;}|<RIGHT> {type = JoinType.OUTER_RIGHT;}|<FULL> {type = JoinType.OUTER_FULL;}) [<OUTER>])] <JOIN> rightTable=SimpleTableRef()
+			(
+				<ON> ConditionsList(condition)
+				{
+				  join = queryFactory.createJoin(type, leftTable, rightTable, condition);
+				  join.setPosition(new TextPosition(leftTable.getPosition(), condition.getPosition()));
+				  return join;
+				}
+			|
+				<USING> <LEFT_PAR> id=Identifier()
+						{ lstColumns.add( queryFactory.createColumn(id) ); }
+						(
+							<COMMA> id=Identifier()
+							{ lstColumns.add( queryFactory.createColumn(id) ); }
+						)* lastPar=<RIGHT_PAR>
+				{
+				  join = queryFactory.createJoin(type, leftTable, rightTable, lstColumns);
+				  join.setPosition(new TextPosition(leftTable.getPosition().beginLine, leftTable.getPosition().beginColumn, lastPar.endLine, (lastPar.endColumn < 0) ? -1 : (lastPar.endColumn + 1)));
+				  return join;
+				}
+			)
+		)
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+/* ****** */
+/* STRING */
+/* ****** */
+StringConstant String(): {Token t, start=null; String str=""; StringConstant cst;} {
+	(t=<STRING_LITERAL>
+	 {
+	   	str += t.image.substring(1, t.image.length()-1).replaceAll("''", "'");
+	   	if (start == null)
+	   		start = t;
+	 }
+	)+
+	{
+		try{
+		  cst = queryFactory.createStringConstant(str);
+		  cst.setPosition(new TextPosition(start, t));
+		  return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+/* ************* */
+/* NUMERIC TYPES */
+/* ************* */
+NumericConstant UnsignedNumeric(): {Token t; NumericConstant cst;} {
+	(t=<SCIENTIFIC_NUMBER>
+	| t=<UNSIGNED_FLOAT>
+	| t=<UNSIGNED_INTEGER>)
+	{		try{
+		  cst = queryFactory.createNumericConstant(t.image);
+		  cst.setPosition(new TextPosition(t));
+		  return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+NumericConstant UnsignedFloat(): {Token t; NumericConstant cst;} {
+	(t=<UNSIGNED_INTEGER>
+	| t=<UNSIGNED_FLOAT>)
+	{
+		try{
+			cst = queryFactory.createNumericConstant(t.image);
+		  	cst.setPosition(new TextPosition(t));
+			return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+NumericConstant SignedInteger(): {Token sign=null, number; NumericConstant cst;} {
+	((sign=<PLUS>|sign=<MINUS>)? number=<UNSIGNED_INTEGER>)
+	{
+		try{
+		  	if (sign == null){		  		cst = queryFactory.createNumericConstant(number.image);
+		  		cst.setPosition(new TextPosition(number));
+		 	}else{		 		cst = queryFactory.createNumericConstant(sign.image+number.image);
+		  		cst.setPosition(new TextPosition(sign, number));
+		 	}
+		 	return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+/* *********** */
+/* EXPRESSIONS */
+/* *********** */
+ADQLOperand NumericValueExpressionPrimary(): {ADQLColumn column; ADQLOperand op; Token left, right;} {
+	try{
+		(// unsigned_value_specification
+		  op=UnsignedNumeric() {return op;}
+		// column_reference
+		| column=Column() {column.setExpectedType('N'); return column;}
+		// set_function_specification
+		| op=SqlFunction() {return op;}
+		// LEFT_PAR value_expression RIGHT_PAR
+		| (left=<LEFT_PAR> op=NumericExpression() right=<RIGHT_PAR>) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; })
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+ADQLOperand StringValueExpressionPrimary(): {StringConstant expr; ADQLColumn column; ADQLOperand op; Token left, right;} {
+	try{
+		(// string
+		  expr=String() {return expr;}
+		// unsigned numeric
+		| op=UnsignedNumeric() {return op;}
+		// set_function_specification
+		| op=SqlFunction() {return op;}
+		// column_reference
+		| column=Column() {column.setExpectedType('*'); return column;}
+		// LEFT_PAR value_expression RIGHT_PAR
+		| (left=<LEFT_PAR> (op=ValueExpression()) right=<RIGHT_PAR>) { WrappedOperand wop = queryFactory.createWrappedOperand(op); wop.setPosition(new TextPosition(left, right)); return wop; })
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+ADQLOperand ValueExpression(): {ADQLOperand valueExpr = null; Token left, right; } {
+	try{
+		(LOOKAHEAD((<PLUS>|<MINUS>) | (Factor() (<PLUS>|<MINUS>|<ASTERISK>|<DIVIDE>))) valueExpr=NumericExpression()
+		| LOOKAHEAD(<COORDSYS> | <LOWER> | (StringFactor() <CONCAT>)) valueExpr=StringExpression()
+		| LOOKAHEAD(<LEFT_PAR>) left=<LEFT_PAR> valueExpr=ValueExpression() right=<RIGHT_PAR> { valueExpr = queryFactory.createWrappedOperand(valueExpr); ((WrappedOperand)valueExpr).setPosition(new TextPosition(left, right)); }
+		| LOOKAHEAD(<REGULAR_IDENTIFIER_CANDIDATE> <LEFT_PAR>) valueExpr=UserDefinedFunction()
+		| LOOKAHEAD(2) valueExpr=GeometryValueFunction()
+		| LOOKAHEAD(Column()) valueExpr=Column()
+		| LOOKAHEAD(String()) valueExpr=StringFactor()
+		| LOOKAHEAD(3) valueExpr=Factor()
+
+		/* At this position in this switch, all possibilities (including
+		 * Column()) have already been tested and failed.
+		 * 
+		 * So, this final choice actually aims to throw an error set with the
+		 * current token and with an error message implying that a column name
+		 * was expected (which is generally the case in an ADQL query).
+		 *
+		 * Note: This choice will generally be reached if an unexpected ADQL/SQL
+		 *       word is ending the query. */
+		| valueExpr=Column() )
+		{return valueExpr;}
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+ADQLOperand NumericExpression(): {Token sign=null; ADQLOperand leftOp, rightOp=null;} {
+	(leftOp=NumericTerm() ((sign=<PLUS> | sign=<MINUS>) rightOp=NumericExpression())?)
+	{
+	if (sign == null)
+		return leftOp;
+	else{
+		try{
+			Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+			operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
+			return operation;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	}
+}
+
+ADQLOperand NumericTerm(): {Token sign=null; ADQLOperand leftOp, rightOp=null;} {
+	(leftOp=Factor() ((sign=<ASTERISK> | sign=<DIVIDE>) rightOp=NumericTerm())?)
+	{
+	if (sign == null)
+		return leftOp;
+	else{
+		try{
+			Operation operation = queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+			operation.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
+			return operation;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+	}
+}
+
+ADQLOperand Factor(): {boolean negative = false; Token minusSign = null; ADQLOperand op;} {
+	(
+		(<PLUS> | (minusSign=<MINUS> {negative = true;}))?
+		(LOOKAHEAD(2) op=NumericFunction() | op=NumericValueExpressionPrimary())
+	)
+	
+	{
+		if (negative){
+			try{
+			  	TextPosition position = op.getPosition();
+				op = queryFactory.createNegativeOperand(op);
+				NegativeOperand negativeOp = (NegativeOperand)op;
+				if (minusSign != null)
+					negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, position.endLine, position.endColumn));
+				else
+					negativeOp.setPosition(position);
+			}catch(Exception ex){
+				throw generateParseException(ex);
+			}
+		}
+		
+		return op;
+	}
+}
+
+ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null;} {
+	leftOp=StringFactor()
+	(
+		<CONCAT>
+		rightOp=StringFactor()
+		{
+			if (!(leftOp instanceof Concatenation)){
+				try{
+					ADQLOperand temp = leftOp;
+					leftOp = queryFactory.createConcatenation();
+					((Concatenation)leftOp).add(temp);
+				}catch(Exception ex){
+					throw generateParseException(ex);
+				}
+			}
+			((Concatenation)leftOp).add(rightOp);
+		}
+	)*
+	{
+		if (leftOp instanceof Concatenation){
+			Concatenation concat = (Concatenation)leftOp;
+			concat.setPosition(new TextPosition(concat.get(0).getPosition(), concat.get(concat.size()-1).getPosition()));
+		}
+	  return leftOp;
+	}
+}
+
+ADQLOperand StringFactor(): {ADQLOperand op;} {
+	(op=ExtractCoordSys()
+	| op=LowerFunction()
+	| LOOKAHEAD(2) op=UserDefinedFunction() { ((UserDefinedFunction)op).setExpectedType('S'); }
+	| op=StringValueExpressionPrimary())
+	{return op;}
+}
+
+GeometryValue<GeometryFunction> GeometryExpression(): {ADQLColumn col = null; GeometryFunction gf = null;} {
+	(col=Column() | gf=GeometryValueFunction())
+	{
+		if (col != null){
+		  	col.setExpectedType('G');
+			return new GeometryValue<GeometryFunction>(col);
+		}else
+			return new GeometryValue<GeometryFunction>(gf);
+	}
+}
+
+/* ********************************** */
+/* BOOLEAN EXPRESSIONS (WHERE clause) */
+/* ********************************** */
+ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint constraint = null; Token op = null; boolean notOp = false;} {
+	try{
+		[op=<NOT> {notOp = true;}]
+		constraint=Constraint()
+		{
+			if (notOp){
+			  	TextPosition oldPos = constraint.getPosition();
+				constraint = queryFactory.createNot(constraint);
+				((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
+			}
+			notOp = false;
+			
+			if (clause instanceof ADQLConstraint)
+				clause.add(constraint);
+			else
+				clause.add(constraint);
+		}
+		(
+			(op=<AND> | op=<OR>)
+			[<NOT> {notOp = true;}]
+			constraint=Constraint()
+			{
+				if (notOp){
+			  		TextPosition oldPos = constraint.getPosition();
+					constraint = queryFactory.createNot(constraint);
+					((NotConstraint)constraint).setPosition(new TextPosition(op.beginLine, op.beginColumn, oldPos.endLine, oldPos.endColumn));
+				}
+				notOp = false;
+				
+				if (clause instanceof ADQLConstraint)
+					clause.add(op.image, constraint);
+				else
+					clause.add(op.image, constraint);
+			}
+		)*
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+	{
+	  	if (!clause.isEmpty()){
+	  		TextPosition start = clause.get(0).getPosition();
+	  		TextPosition end = clause.get(clause.size()-1).getPosition();
+			clause.setPosition(new TextPosition(start, end));
+		}
+		return clause;
+	}
+}
+
+ADQLConstraint Constraint(): {ADQLConstraint constraint =  null; Token start, end;} {
+	(LOOKAHEAD(<EXISTS> | ValueExpression()) constraint=Predicate()
+	| (
+		start=<LEFT_PAR>
+		{
+			try{
+				constraint = queryFactory.createGroupOfConstraints();
+			}catch(Exception ex){
+				throw generateParseException(ex);
+			}
+		}
+		ConditionsList((ConstraintsGroup)constraint)
+		end=<RIGHT_PAR>
+		{ ((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end)); }
+	))
+	{return constraint;}
+}
+
+ADQLConstraint Predicate(): {ADQLQuery q=null; ADQLColumn column=null; ADQLOperand strExpr1=null, strExpr2=null; ADQLOperand op; Token start, notToken = null, end; ADQLConstraint constraint = null;} {
+	try{
+		// exists_predicate
+		(
+		  (start=<EXISTS> q=SubQueryExpression()
+			{
+			  Exists e = queryFactory.createExists(q);
+			  e.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
+			  return e;
+			}
+		  )
+		// null_predicate
+		| LOOKAHEAD(Column() <IS>)(column=Column() <IS> [notToken=<NOT>] end=<NULL>
+		    {
+		      IsNull in = queryFactory.createIsNull((notToken!=null), column);
+		      in.setPosition(new TextPosition(column.getPosition().beginLine, column.getPosition().beginColumn, end.endLine, (end.endColumn < 0) ? -1 : (end.endColumn + 1)));
+		      return in;
+		    }
+		   )
+		// like_predicate
+		| LOOKAHEAD(StringExpression() [<NOT>] <LIKE>) (strExpr1=StringExpression() [notToken=<NOT>] <LIKE> strExpr2=StringExpression()
+		    {
+		      Comparison comp = queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.LIKE:ComparisonOperator.NOTLIKE, strExpr2);
+		      comp.setPosition(new TextPosition(strExpr1.getPosition(), strExpr2.getPosition()));
+		      return comp;
+		    }
+		  )
+		| (op=ValueExpression()
+			(// comparison_predicate
+			(constraint=ComparisonEnd(op))
+			// between predicate
+			| LOOKAHEAD(2) constraint=BetweenEnd(op)
+			// in_predicate
+			| constraint=InEnd(op)
+			)
+		  )
+		)
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+	{return constraint;}
+}
+
+Comparison ComparisonEnd(ADQLOperand leftOp): {Token comp; ADQLOperand rightOp;} {
+	((comp=<EQUAL> | comp=<NOT_EQUAL> | comp=<LESS_THAN> | comp=<LESS_EQUAL_THAN> | comp=<GREATER_THAN> | comp=<GREATER_EQUAL_THAN>) rightOp=ValueExpression())
+	{
+		try{
+		  	Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
+		  	comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
+			return comparison;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+Between BetweenEnd(ADQLOperand leftOp): {Token start,notToken=null; ADQLOperand min, max;} {
+	[notToken=<NOT>] start=<BETWEEN> min=ValueExpression() <AND> max=ValueExpression()
+	{
+		try{
+		  	Between bet = queryFactory.createBetween((notToken!=null), leftOp, min, max);
+		  	if (notToken != null) start = notToken;
+		  	bet.setPosition(new TextPosition(start.beginLine, start.beginColumn, max.getPosition().endLine, max.getPosition().endColumn));
+			return bet;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+In InEnd(ADQLOperand leftOp): {Token not=null, start; ADQLQuery q = null; ADQLOperand item; Vector<ADQLOperand> items = new Vector<ADQLOperand>();} {
+	[not=<NOT>] start=<IN>
+	(LOOKAHEAD(2) q=SubQueryExpression()
+	| (<LEFT_PAR> item=ValueExpression() {items.add(item);} (<COMMA> item=ValueExpression() {items.add(item);})* <RIGHT_PAR>))
+	{
+		try{
+		  	In in;
+		  	start = (not!=null) ? not : start;
+			if (q != null){
+				in = queryFactory.createIn(leftOp, q, not!=null);
+				in.setPosition(new TextPosition(start.beginLine, start.beginColumn, q.getPosition().endLine, q.getPosition().endColumn));
+			}else{
+				ADQLOperand[] list = new ADQLOperand[items.size()];
+				int i=0;
+				for(ADQLOperand op : items)
+					list[i++] = op;
+				in = queryFactory.createIn(leftOp, list, not!=null);
+				in.setPosition(new TextPosition(start.beginLine, start.beginColumn, list[list.length-1].getPosition().endLine, list[list.length-1].getPosition().endColumn));
+			}
+			return in;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+
+/* ************* */
+/* SQL FUNCTIONS */
+/* ************* */
+SQLFunction SqlFunction(): {Token fct, all=null, distinct=null, end; ADQLOperand op=null; SQLFunction funct = null;}{
+	try{
+		(
+			(fct=<COUNT> <LEFT_PAR> [distinct=<QUANTIFIER>] (all=<ASTERISK> | op=ValueExpression()) end=<RIGHT_PAR>
+			{
+			  funct = queryFactory.createSQLFunction((all!=null)?SQLFunctionType.COUNT_ALL:SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
+			  funct.setPosition(new TextPosition(fct, end));
+			})
+		|
+			((fct=<AVG> | fct=<MAX> | fct=<MIN> | fct=<SUM>) <LEFT_PAR> [distinct=<QUANTIFIER>] op=ValueExpression() end=<RIGHT_PAR> 
+			{
+			  funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct"));
+			  funct.setPosition(new TextPosition(fct, end));
+			})
+		)
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+	{ return funct; }
+}
+
+
+/* ************** */
+/* ADQL FUNCTIONS */
+/* ************** */
+ADQLOperand[] Coordinates(): {ADQLOperand[] ops = new ADQLOperand[2];} {
+	ops[0]=NumericExpression() <COMMA> ops[1]=NumericExpression()
+	{return ops;}
+}
+
+GeometryFunction GeometryFunction(): {Token fct=null, end; GeometryValue<GeometryFunction> gvf1, gvf2; GeometryValue<PointFunction> gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} {
+	try{
+		// predicate_geometry_function
+		(
+			((fct=<CONTAINS> | fct=<INTERSECTS>) <LEFT_PAR> gvf1=GeometryExpression() <COMMA> gvf2=GeometryExpression() end=<RIGHT_PAR>
+			{
+				if (fct.image.equalsIgnoreCase("contains"))
+					gf = queryFactory.createContains(gvf1, gvf2);
+				else
+					gf = queryFactory.createIntersects(gvf1, gvf2);
+			})
+		// non_predicate_geometry_function
+		|	(fct=<AREA> <LEFT_PAR> gvf1=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createArea(gvf1);}
+		|	(fct=<COORD1> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord1(col1);}) end=<RIGHT_PAR>)
+		|	(fct=<COORD2> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {col1.setExpectedType('G'); gf = queryFactory.createCoord2(col1);}) end=<RIGHT_PAR>)
+		|	(fct=<DISTANCE>
+				<LEFT_PAR>
+				(p1=Point()|col1=Column()) 
+				{
+					if (p1 != null)
+						gvp1 = new GeometryValue<PointFunction>(p1);
+					else{
+						col1.setExpectedType('G');
+						gvp1 = new GeometryValue<PointFunction>(col1);
+					}
+				}
+				<COMMA>
+				(p2=Point()|col2=Column())
+				{
+					if (p2 != null)
+						gvp2 = new GeometryValue<PointFunction>(p2);
+					else{
+						col2.setExpectedType('G');
+						gvp2 = new GeometryValue<PointFunction>(col2);
+					}
+				} 
+				end=<RIGHT_PAR>
+				{gf = queryFactory.createDistance(gvp1, gvp2);}
+			)
+		)
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+	
+	{
+	  gf.setPosition(new TextPosition(fct, end));
+	  return gf;
+	}
+}
+
+ADQLOperand CoordinateSystem(): { ADQLOperand coordSys=null;}{
+	coordSys=StringExpression()
+	{ return coordSys; }
+}
+
+GeometryFunction GeometryValueFunction(): {Token fct=null, end=null; ADQLOperand coordSys; ADQLOperand width, height; ADQLOperand[] coords, tmp; Vector<ADQLOperand> vCoords; ADQLOperand op=null; GeometryValue<GeometryFunction> gvf = null; GeometryFunction gf = null;} {
+	try{
+		// BOX:
+		((fct=<BOX> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+				<COMMA> coords=Coordinates() // coordinates
+				<COMMA> width=NumericExpression() <COMMA> height=NumericExpression() end=<RIGHT_PAR>)
+		 {gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);}
+		 
+		// CENTROID:
+		| (fct=<CENTROID> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createCentroid(gvf);}
+		
+		// CIRCLE:
+		| (fct=<CIRCLE> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+				<COMMA> coords=Coordinates() // coordinates
+				<COMMA> width=NumericExpression() end=<RIGHT_PAR>) // radius
+		 {gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);}
+		
+		// POINT: 
+		| gf=Point()
+		
+		// POLYGON:
+		| (fct=<POLYGON> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+				{ vCoords = new Vector<ADQLOperand>(); } // coordinates
+				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
+				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
+				<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);}
+				(<COMMA> tmp=Coordinates() {vCoords.add(tmp[0]); vCoords.add(tmp[1]);})*
+				end=<RIGHT_PAR>)
+		  { gf = queryFactory.createPolygon(coordSys, vCoords); }
+		  
+		// REGION:
+		| (fct=<REGION> <LEFT_PAR> op=StringExpression() end=<RIGHT_PAR>) {gf = queryFactory.createRegion(op);})
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+	
+	{
+	  if (fct != null && end != null) // = !(gf instanceof Point)
+	  	gf.setPosition(new TextPosition(fct, end));
+	  return gf;
+	}
+}
+
+PointFunction Point(): {Token start, end; ADQLOperand coordSys; ADQLOperand[] coords;} {
+	start=<POINT> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+			<COMMA> coords=Coordinates() end=<RIGHT_PAR> // coordinates
+	{
+		try{
+			PointFunction pf = queryFactory.createPoint(coordSys, coords[0], coords[1]);
+			pf.setPosition(new TextPosition(start, end));
+			return pf;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+GeometryFunction ExtractCoordSys(): {Token start, end; GeometryValue<GeometryFunction> gvf;} {
+	start=<COORDSYS> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>
+	{
+		try{
+			GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
+			gf.setPosition(new TextPosition(start, end));
+			return gf;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+/* **************** */
+/* STRING FUNCTIONS */
+/* **************** */
+
+LowerFunction LowerFunction(): { Token start, end; ADQLOperand str; } {
+	start=<LOWER> <LEFT_PAR> str=StringExpression() end=<RIGHT_PAR>
+	{
+	  	try{
+			LowerFunction lf = queryFactory.createLowerFunction(str);
+			lf.setPosition(new TextPosition(start, end));
+			return lf;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+/* ***************** */
+/* NUMERIC FUNCTIONS */
+/* ***************** */
+ADQLFunction NumericFunction(): {ADQLFunction fct;} {
+	(fct=MathFunction()
+	| fct=TrigFunction()
+	| fct=GeometryFunction()
+	| fct=UserDefinedFunction() { ((UserDefinedFunction)fct).setExpectedType('N'); })
+	{return fct;}
+}
+
+MathFunction MathFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null; NumericConstant integerValue = null;} {
+	try{
+		((fct=<ABS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<CEILING> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<DEGREES> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<EXP> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<FLOOR> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<LOG> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<LOG10> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<MOD> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<PI> <LEFT_PAR> end=<RIGHT_PAR>)
+		| (fct=<POWER> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<RADIANS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<RAND> <LEFT_PAR> (param1=NumericExpression())? end=<RIGHT_PAR>)
+		| (fct=<ROUND> <LEFT_PAR> param1=NumericExpression() (<COMMA> param2=SignedInteger())? end=<RIGHT_PAR>)
+		| (fct=<SQRT> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+		| (fct=<TRUNCATE> <LEFT_PAR> param1=NumericExpression() (<COMMA> param2=SignedInteger())? end=<RIGHT_PAR>))
+		{
+			MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+			mf.setPosition(new TextPosition(fct, end));
+			return mf;
+		}
+	}catch(Exception ex){
+		throw generateParseException(ex);
+	}
+}
+
+MathFunction TrigFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null;} {
+	((fct=<ACOS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<ASIN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<ATAN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<ATAN2> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<COS> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<COT> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<SIN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>)
+	| (fct=<TAN> <LEFT_PAR> param1=NumericExpression() end=<RIGHT_PAR>))
+	{
+		try{
+			MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+			mf.setPosition(new TextPosition(fct, end));
+			return mf;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
+UserDefinedFunction UserDefinedFunction(): {Token fct, end; Vector<ADQLOperand> params = new Vector<ADQLOperand>(); ADQLOperand op;} {
+	fct=<REGULAR_IDENTIFIER_CANDIDATE> <LEFT_PAR> (op=ValueExpression() {params.add(op);} (<COMMA> op=ValueExpression() {params.add(op);})*)? end=<RIGHT_PAR>
+	{
+		// Ensure the given function name is valid: 
+		if (!isRegularIdentifier(fct.image))
+			throw new ParseException("Invalid (User Defined) Function name: \""+fct.image+"\"!", new TextPosition(fct));
+		
+		//System.out.println("INFO [ADQLParser201]: \""+fct.image+"\" (from line "+fct.beginLine+" and column "+fct.beginColumn+" to line "+token.endLine+" and column "+(token.endColumn+1)+") is considered as an user defined function !");
+		
+		try{
+			//  Build the parameters list:
+			ADQLOperand[] parameters = new ADQLOperand[params.size()];
+			for(int i=0; i<params.size(); i++)
+				parameters[i] = params.get(i);
+			
+			// Create the UDF function:
+			UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
+			udf.setPosition(new TextPosition(fct, end));
+			return udf;
+			
+		}catch(UnsupportedOperationException uoe){
+		  	/* This catch clause is just for backward compatibility:
+		  	 * if the createUserDefinedFunction(...) is overridden and
+		  	 * the function can not be identified a such exception may be thrown). */
+			throw new ParseException(uoe.getMessage(), new TextPosition(fct, token));
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
+}
+
diff --git a/src/adql/query/operand/function/string/LowerFunction.java b/src/adql/query/operand/function/string/LowerFunction.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1d557b1913eaa876a6502628571173ae1080c06
--- /dev/null
+++ b/src/adql/query/operand/function/string/LowerFunction.java
@@ -0,0 +1,125 @@
+package adql.query.operand.function.string;
+
+/*
+ * This file is part of ADQLLibrary.
+ *
+ * ADQLLibrary is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ADQLLibrary is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ADQLLibrary.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ */
+
+import adql.query.ADQLObject;
+import adql.query.operand.ADQLOperand;
+import adql.query.operand.function.ADQLFunction;
+
+/**
+ * It represents the LOWER function of ADQL.
+ *
+ * <p>This function put the given text in lower case.</p>
+ *
+ * <p><i><u>Example:</u><br/>
+ * 	<code>LOWER('Francis Albert Augustus Charles Emmanuel')</code><br/>
+ * 	which should return:<br/>
+ * 	<code>francis albert augustus charles emmanuel</code>
+ * </i></p>
+ *
+ * @author Gr&eacute;gory Mantelet (CDS)
+ * @version 2.0 (04/2019)
+ * @since 2.0
+ */
+public class LowerFunction extends ADQLFunction {
+
+	/** Constant name of this function. */
+	protected final String FCT_NAME = "LOWER";
+
+	/** The only parameter of this function. */
+	protected ADQLOperand strParam;
+
+	/**
+	 * Builds a LOWER function with its parameter.
+	 *
+	 * @param param					Parameter of LOWER.
+	 * @throws NullPointerException	If the given operand is <i>null</i>
+	 *                             	or if it's not a string parameter.
+	 */
+	public LowerFunction(final ADQLOperand strParam) {
+		if (strParam == null)
+			throw new NullPointerException("The function " + FCT_NAME + " must have one non-NULL parameter!");
+
+		if (!strParam.isString())
+			throw new NullPointerException("The ADQL function " + FCT_NAME + " must have one parameter of type VARCHAR (i.e. a String)!");
+
+		this.strParam = strParam;
+	}
+
+	@Override
+	public final boolean isNumeric() {
+		return false;
+	}
+
+	@Override
+	public final boolean isString() {
+		return true;
+	}
+
+	@Override
+	public final boolean isGeometry() {
+		return false;
+	}
+
+	@Override
+	public final String getName() {
+		return FCT_NAME;
+	}
+
+	@Override
+	public ADQLObject getCopy() throws Exception {
+		return new LowerFunction((ADQLOperand)(strParam.getCopy()));
+	}
+
+	@Override
+	public int getNbParameters() {
+		return 1;
+	}
+
+	@Override
+	public final ADQLOperand[] getParameters() {
+		return new ADQLOperand[]{ strParam };
+	}
+
+	@Override
+	public ADQLOperand getParameter(final int index) throws ArrayIndexOutOfBoundsException {
+		if (index == 0)
+			return strParam;
+		else
+			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + FCT_NAME + "\" !");
+	}
+
+	@Override
+	public ADQLOperand setParameter(final int index, final ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception {
+		if (index == 0) {
+			ADQLOperand replaced = strParam;
+			if (replacer == null)
+				throw new NullPointerException("Missing the new parameter of the function \"" + toADQL() + "\"!");
+			else if (replacer.isString())
+				strParam = replacer;
+			else
+				throw new Exception("Impossible to replace a String parameter by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
+			setPosition(null);
+			return replaced;
+		} else
+			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + FCT_NAME + "\" !");
+	}
+
+}
diff --git a/src/tap/ADQLExecutor.java b/src/tap/ADQLExecutor.java
index 689a152a2ffa4fbfa55643660b00e7647a7a12e2..2f42f1263c4dfe753ab99ef236bb2ccc2255ca4f 100644
--- a/src/tap/ADQLExecutor.java
+++ b/src/tap/ADQLExecutor.java
@@ -26,6 +26,7 @@ import java.io.OutputStream;
 import javax.servlet.http.HttpServletResponse;
 
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ADQLQueryFactory;
 import adql.parser.ParseException;
 import adql.query.ADQLQuery;
@@ -105,7 +106,7 @@ import uws.service.log.UWSLog.LogLevel;
  * </p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.3 (03/2019)
+ * @version 3.0 (04/2019)
  */
 public class ADQLExecutor {
 
@@ -142,7 +143,7 @@ public class ADQLExecutor {
 	 *
 	 * @param service	The description of the TAP service.
 	 */
-	public ADQLExecutor(final ServiceConnection service){
+	public ADQLExecutor(final ServiceConnection service) {
 		this.service = service;
 		this.logger = service.getLogger();
 	}
@@ -152,7 +153,7 @@ public class ADQLExecutor {
 	 *
 	 * @return	The used logger.
 	 */
-	public final TAPLog getLogger(){
+	public final TAPLog getLogger() {
 		return logger;
 	}
 
@@ -166,7 +167,7 @@ public class ADQLExecutor {
 	 *
 	 * @return	The execution report.
 	 */
-	public final TAPExecutionReport getExecReport(){
+	public final TAPExecutionReport getExecReport() {
 		return report;
 	}
 
@@ -180,7 +181,7 @@ public class ADQLExecutor {
 	 *
 	 * @see ServiceConnection#getOutputFormat(String)
 	 */
-	protected OutputFormat getFormatter() throws TAPException{
+	protected OutputFormat getFormatter() throws TAPException {
 		// Search for the corresponding formatter:
 		String format = tapParams.getFormat();
 		OutputFormat formatter = service.getOutputFormat((format == null) ? "votable" : format);
@@ -211,7 +212,7 @@ public class ADQLExecutor {
 	 *
 	 * @see #start()
 	 */
-	public final TAPExecutionReport start(final AsyncThread thread) throws UWSException, InterruptedException{
+	public final TAPExecutionReport start(final AsyncThread thread) throws UWSException, InterruptedException {
 		if (this.thread != null || this.report != null)
 			throw new UWSException(UWSException.INTERNAL_SERVER_ERROR, "This ADQLExecutor has already been executed!");
 
@@ -222,19 +223,19 @@ public class ADQLExecutor {
 		this.report = new TAPExecutionReport(tapJob.getJobId(), false, tapParams);
 		this.response = null;
 
-		try{
+		try {
 			return start();
-		}catch(IOException ioe){
+		} catch(IOException ioe) {
 			if (thread.isInterrupted())
 				return report;
 			else
 				throw new UWSException(ioe);
-		}catch(TAPException te){
+		} catch(TAPException te) {
 			if (thread.isInterrupted())
 				return report;
 			else
 				throw new UWSException(te.getHttpErrorCode(), te);
-		}catch(UWSException ue){
+		} catch(UWSException ue) {
 			if (thread.isInterrupted())
 				return report;
 			else
@@ -256,7 +257,7 @@ public class ADQLExecutor {
 	 *
 	 * @since 2.0
 	 */
-	public final void initDBConnection(final String jobID) throws TAPException{
+	public final void initDBConnection(final String jobID) throws TAPException {
 		if (dbConn == null)
 			dbConn = service.getFactory().getConnection(jobID);
 	}
@@ -267,7 +268,7 @@ public class ADQLExecutor {
 	 *
 	 * @since 2.1
 	 */
-	public final void cancelQuery(){
+	public final void cancelQuery() {
 		if (dbConn != null && (progression == ExecutionProgression.EXECUTING_ADQL || progression == ExecutionProgression.UPLOADING))
 			dbConn.cancel(true);
 	}
@@ -290,7 +291,7 @@ public class ADQLExecutor {
 	 *
 	 * @see #start()
 	 */
-	public final TAPExecutionReport start(final Thread thread, final String jobId, final TAPParameters params, final HttpServletResponse response) throws TAPException, IOException, InterruptedException{
+	public final TAPExecutionReport start(final Thread thread, final String jobId, final TAPParameters params, final HttpServletResponse response) throws TAPException, IOException, InterruptedException {
 		if (this.thread != null || this.report != null)
 			throw new TAPException("This ADQLExecutor has already been executed!");
 
@@ -299,9 +300,9 @@ public class ADQLExecutor {
 		this.report = new TAPExecutionReport(jobId, true, tapParams);
 		this.response = response;
 
-		try{
+		try {
 			return start();
-		}catch(UWSException ue){
+		} catch(UWSException ue) {
 			throw new TAPException(ue, ue.getHttpErrorCode());
 		}
 	}
@@ -336,7 +337,7 @@ public class ADQLExecutor {
 	 *                    			In asynchronous, the error is stored as job error report and is never propagated.</i>
 	 * @throws InterruptedException	If the job has been interrupted (by the user or a time-out).
 	 */
-	protected final TAPExecutionReport start() throws TAPException, UWSException, IOException, InterruptedException{
+	protected final TAPExecutionReport start() throws TAPException, UWSException, IOException, InterruptedException {
 		logger.logTAP(LogLevel.INFO, report, "START_EXEC", (report.synchronous ? "Synchronous" : "Asynchronous") + " execution of an ADQL query STARTED.", null);
 
 		// Save the start time (for reporting usage):
@@ -344,12 +345,12 @@ public class ADQLExecutor {
 
 		TableIterator queryResult = null;
 
-		try{
+		try {
 			// Get a "database" connection:
 			initDBConnection(report.jobID);
 
 			// 1. UPLOAD TABLES, if there is any:
-			if (tapParams.getUploadedTables() != null && tapParams.getUploadedTables().length > 0){
+			if (tapParams.getUploadedTables() != null && tapParams.getUploadedTables().length > 0) {
 				startStep(ExecutionProgression.UPLOADING);
 				uploadTables();
 				endStep();
@@ -362,9 +363,9 @@ public class ADQLExecutor {
 			startStep(ExecutionProgression.PARSING);
 			// Parse the query:
 			ADQLQuery adqlQuery = null;
-			try{
+			try {
 				adqlQuery = parseADQL();
-			}catch(ParseException pe){
+			} catch(ParseException pe) {
 				if (report.synchronous)
 					throw new TAPException("Incorrect ADQL query: " + pe.getMessage(), pe, UWSException.BAD_REQUEST, tapParams.getQuery(), progression);
 				else
@@ -404,27 +405,27 @@ public class ADQLExecutor {
 
 			return report;
 
-		}catch(DBCancelledException dce){
+		} catch(DBCancelledException dce) {
 			throw new InterruptedException();
-		}finally{
+		} finally {
 			// Close the result if any:
-			if (queryResult != null){
-				try{
+			if (queryResult != null) {
+				try {
 					queryResult.close();
-				}catch(DataReadException dre){
+				} catch(DataReadException dre) {
 					logger.logTAP(LogLevel.WARNING, report, "END_EXEC", "Can not close the database query result!", dre);
 				}
 			}
 
 			// Drop all the uploaded tables (they are not supposed to exist after the query execution):
-			try{
+			try {
 				dropUploadedTables();
-			}catch(TAPException e){
+			} catch(TAPException e) {
 				logger.logTAP(LogLevel.WARNING, report, "END_EXEC", "Can not drop the uploaded tables from the database!", e);
 			}
 
 			// Free the connection (so that giving it back to a pool if any, otherwise just free resources):
-			if (dbConn != null){
+			if (dbConn != null) {
 				service.getFactory().freeConnection(dbConn);
 				dbConn = null;
 			}
@@ -448,15 +449,15 @@ public class ADQLExecutor {
 	 *
 	 * @see #endStep()
 	 */
-	private void startStep(final ExecutionProgression progression){
+	private void startStep(final ExecutionProgression progression) {
 		// Save the start time (for report usage):
 		startStep = System.currentTimeMillis();
 		// Memorize the current step:
 		this.progression = progression;
 		// Update the job parameter "progression", to notify the user about the progression of the query processing:
-		try{
+		try {
 			tapParams.set(TAPJob.PARAM_PROGRESSION, this.progression);
-		}catch(UWSException ue){
+		} catch(UWSException ue) {
 			// should not happen, but just in case...
 			logger.logTAP(LogLevel.WARNING, report, "START_STEP", "Can not set/update the informative job parameter \"" + TAPJob.PARAM_PROGRESSION + "\" (this parameter would be just for notification purpose about the execution progression)!", ue);
 		}
@@ -476,8 +477,8 @@ public class ADQLExecutor {
 	 *
 	 * @see #startStep(ExecutionProgression)
 	 */
-	private void endStep(){
-		if (progression != null){
+	private void endStep() {
+		if (progression != null) {
 			// Set the duration of this step in the execution report:
 			report.setDuration(progression, System.currentTimeMillis() - startStep);
 			// No start time:
@@ -497,12 +498,12 @@ public class ADQLExecutor {
 	 * @throws TAPException	If any error occurs while reading the uploaded table
 	 *                     	or while importing them in the database.
 	 */
-	private final void uploadTables() throws TAPException{
+	private final void uploadTables() throws TAPException {
 		// Fetch the tables to upload:
 		DALIUpload[] tables = tapParams.getUploadedTables();
 
 		// Upload them, if needed:
-		if (tables.length > 0){
+		if (tables.length > 0) {
 			logger.logTAP(LogLevel.INFO, report, "UPLOADING", "Loading uploaded tables (" + tables.length + ")", null);
 			uploadSchema = service.getFactory().createUploader(dbConn).upload(tables);
 		}
@@ -531,15 +532,15 @@ public class ADQLExecutor {
 	 * @throws InterruptedException		If the thread has been interrupted.
 	 * @throws TAPException				If the TAP factory is unable to create the ADQL factory or the query checker.
 	 */
-	protected ADQLQuery parseADQL() throws ParseException, InterruptedException, TAPException{
+	protected ADQLQuery parseADQL() throws ParseException, InterruptedException, TAPException {
 		// Log the start of the parsing:
 		logger.logTAP(LogLevel.INFO, report, "PARSING", "Parsing ADQL: " + tapParams.getQuery().replaceAll("(\t|\r?\n)+", " "), null);
 
 		// Create the ADQL parser:
 		ADQLParser parser = service.getFactory().createADQLParser();
-		if (parser == null){
+		if (parser == null) {
 			logger.logTAP(LogLevel.WARNING, null, "PARSING", "No ADQL parser returned by the TAPFactory! The default implementation is used instead.", null);
-			parser = new ADQLParser();
+			parser = ADQLParserFactory.createDefaultParser();
 		}
 
 		// Set the ADQL factory:
@@ -553,11 +554,11 @@ public class ADQLExecutor {
 		// Parse the ADQL query:
 		ADQLQuery query = null;
 		// if the fixOnFail option is enabled...
-		if (service.fixOnFailEnabled()){
-			try{
+		if (service.fixOnFailEnabled()) {
+			try {
 				// try parsing the query:
 				query = parser.parseQuery(tapParams.getQuery());
-			}catch(ParseException pe){
+			} catch(ParseException pe) {
 				// if it fails...
 				// ...log the auto fix attempt:
 				logger.logTAP(LogLevel.INFO, report, "PARSING", "Parse attempt of the original input query failed! Trying auto-fix...", null);
@@ -572,14 +573,14 @@ public class ADQLExecutor {
 			}
 		}
 		// if not enabled, parse immediately the query:
-		else{
+		else {
 			query = parser.parseQuery(tapParams.getQuery());
 		}
 
 		// Set or check the row limit:
 		final int limit = query.getSelect().getLimit();
 		final Integer maxRec = tapParams.getMaxRec();
-		if (maxRec != null && maxRec > -1){
+		if (maxRec != null && maxRec > -1) {
 			if (limit <= -1 || limit > maxRec)
 				query.getSelect().setLimit(maxRec + 1);
 		}
@@ -607,19 +608,19 @@ public class ADQLExecutor {
 	 *
 	 * @see DBConnection#executeQuery(ADQLQuery)
 	 */
-	protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, DBCancelledException, TAPException{
+	protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, DBCancelledException, TAPException {
 		// Log the start of execution:
 		logger.logTAP(LogLevel.INFO, report, "START_DB_EXECUTION", "ADQL query: " + adql.toADQL().replaceAll("(\t|\r?\n)+", " "), null);
 
 		// Set the fetch size, if any:
-		if (service.getFetchSize() != null && service.getFetchSize().length >= 1){
+		if (service.getFetchSize() != null && service.getFetchSize().length >= 1) {
 			if (report.synchronous && service.getFetchSize().length >= 2)
 				dbConn.setFetchSize(service.getFetchSize()[1]);
 			else
 				dbConn.setFetchSize(service.getFetchSize()[0]);
 		}
 
-		try{
+		try {
 			// Execute the ADQL query:
 			TableIterator result = dbConn.executeQuery(adql);
 
@@ -631,7 +632,7 @@ public class ADQLExecutor {
 			logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query successfully executed in " + (System.currentTimeMillis() - startStep) + "ms!", null);
 
 			return result;
-		}catch(DBCancelledException dce){
+		} catch(DBCancelledException dce) {
 			logger.logTAP(LogLevel.INFO, report, "END_DB_EXECUTION", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
 			throw dce;
 		}
@@ -657,7 +658,7 @@ public class ADQLExecutor {
 	 *
 	 * @see #writeResult(TableIterator, OutputFormat, OutputStream)
 	 */
-	protected final void writeResult(final TableIterator queryResult) throws InterruptedException, IOException, TAPException, UWSException{
+	protected final void writeResult(final TableIterator queryResult) throws InterruptedException, IOException, TAPException, UWSException {
 		// Log the start of the writing:
 		logger.logTAP(LogLevel.INFO, report, "WRITING_RESULT", "Writing the query result", null);
 
@@ -665,7 +666,7 @@ public class ADQLExecutor {
 		OutputFormat formatter = getFormatter();
 
 		// CASE SYNCHRONOUS:
-		if (response != null){
+		if (response != null) {
 			long start = -1;
 
 			// Set the HTTP content type to the MIME type of the result format:
@@ -681,12 +682,12 @@ public class ADQLExecutor {
 			logger.logTAP(LogLevel.INFO, report, "RESULT_WRITTEN", "Result formatted (in " + formatter.getMimeType() + " ; " + (report.nbRows < 0 ? "?" : report.nbRows) + " rows ; " + ((report.resultingColumns == null) ? "?" : report.resultingColumns.length) + " columns) in " + ((start <= 0) ? "?" : (System.currentTimeMillis() - start)) + "ms!", null);
 		}
 		// CASE ASYNCHRONOUS:
-		else{
+		else {
 			boolean completed = false;
 			long start = -1, end = -1;
 			Result result = null;
 			JobThread jobThread = (JobThread)thread;
-			try{
+			try {
 				// Create a UWS Result object to store the result
 				// (the result will be stored in a file and this object is the association between the job and the result file):
 				result = jobThread.createResult();
@@ -709,17 +710,17 @@ public class ADQLExecutor {
 
 				logger.logTAP(LogLevel.INFO, report, "RESULT_WRITTEN", "Result formatted (in " + formatter.getMimeType() + " ; " + (report.nbRows < 0 ? "?" : report.nbRows) + " rows ; " + ((report.resultingColumns == null) ? "?" : report.resultingColumns.length) + " columns) in " + ((start <= 0 || end <= 0) ? "?" : (end - start)) + "ms!", null);
 
-			}catch(IOException ioe){
+			} catch(IOException ioe) {
 				// Propagate the exception:
 				throw new UWSException(UWSException.INTERNAL_SERVER_ERROR, ioe, "Impossible to write in the file into which the result of the job " + report.jobID + " must be written!");
-			}finally{
-				if (!completed){
+			} finally {
+				if (!completed) {
 					// Delete the result file (it is either incomplete or incorrect ;
 					// it is then not reliable and is anyway not associated with the job and so could not be later deleted when the job will be):
-					if (result != null){
-						try{
+					if (result != null) {
+						try {
 							service.getFileManager().deleteResult(result, jobThread.getJob());
-						}catch(IOException ioe){
+						} catch(IOException ioe) {
 							logger.logTAP(LogLevel.ERROR, report, "WRITING_RESULT", "The result writting has failed and the produced partial result must be deleted, but this deletion also failed! (job: " + report.jobID + ")", ioe);
 						}
 					}
@@ -746,7 +747,7 @@ public class ADQLExecutor {
 	 * @throws IOException			If there is an error while writing the result in the given stream.
 	 * @throws TAPException			If there is an error while formatting the result.
 	 */
-	protected void writeResult(TableIterator queryResult, OutputFormat formatter, OutputStream output) throws InterruptedException, IOException, TAPException{
+	protected void writeResult(TableIterator queryResult, OutputFormat formatter, OutputStream output) throws InterruptedException, IOException, TAPException {
 		formatter.writeResult(queryResult, output, report, thread);
 	}
 
@@ -759,13 +760,13 @@ public class ADQLExecutor {
 	 *
 	 * @throws TAPException	If a grave error occurs. <i>By default, no exception is thrown ; they are just logged.</i>
 	 */
-	protected void dropUploadedTables() throws TAPException{
-		if (uploadSchema != null){
+	protected void dropUploadedTables() throws TAPException {
+		if (uploadSchema != null) {
 			// Drop all uploaded tables:
-			for(TAPTable t : uploadSchema){
-				try{
+			for(TAPTable t : uploadSchema) {
+				try {
 					dbConn.dropUploadedTable(t);
-				}catch(DBException dbe){
+				} catch(DBException dbe) {
 					logger.logTAP(LogLevel.ERROR, report, "DROP_UPLOAD", "Can not drop the uploaded table \"" + t.getDBName() + "\" (in adql \"" + t.getADQLName() + "\") from the database!", dbe);
 				}
 			}
diff --git a/src/tap/AbstractTAPFactory.java b/src/tap/AbstractTAPFactory.java
index dbc0e7d38614dd2faac6a12a8d850bc72939dad4..c9899fdea0b6e329f62a941a9f5ff14bc92e9e0f 100644
--- a/src/tap/AbstractTAPFactory.java
+++ b/src/tap/AbstractTAPFactory.java
@@ -16,7 +16,7 @@ package tap;
  * You should have received a copy of the GNU Lesser General Public License
  * along with TAPLibrary.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ * Copyright 2012-2019 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
  *                       Astronomisches Rechen Institut (ARI)
  */
 
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
 
 import adql.db.DBChecker;
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ADQLQueryFactory;
 import adql.parser.ParseException;
 import adql.parser.QueryChecker;
@@ -55,13 +56,18 @@ import uws.service.error.ServiceErrorWriter;
  * Only the functions related with the database connection stay abstract.
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.2 (09/2017)
+ * @version 3.0 (04/2019)
  */
 public abstract class AbstractTAPFactory extends TAPFactory {
 
 	/** The error writer to use when any error occurs while executing a resource or to format an error occurring while executing an asynchronous job. */
 	protected final ServiceErrorWriter errorWriter;
 
+	/** Factory of ADQL parsers. This factory can be configured to work with a
+	 * different version of the ADQL grammar.
+	 * @since 3.0 */
+	protected ADQLParserFactory parserFactory;
+
 	/**
 	 * Build a basic TAPFactory.
 	 * Nothing is done except setting the service connection.
@@ -72,7 +78,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 *
 	 * @see AbstractTAPFactory#AbstractTAPFactory(ServiceConnection, ServiceErrorWriter)
 	 */
-	protected AbstractTAPFactory(ServiceConnection service) throws NullPointerException{
+	protected AbstractTAPFactory(ServiceConnection service) throws NullPointerException {
 		this(service, new DefaultTAPErrorWriter(service));
 	}
 
@@ -89,13 +95,14 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 *
 	 * @see TAPFactory#TAPFactory(ServiceConnection)
 	 */
-	protected AbstractTAPFactory(final ServiceConnection service, final ServiceErrorWriter errorWriter) throws NullPointerException{
+	protected AbstractTAPFactory(final ServiceConnection service, final ServiceErrorWriter errorWriter) throws NullPointerException {
 		super(service);
 		this.errorWriter = errorWriter;
+		this.parserFactory = new ADQLParserFactory();
 	}
 
 	@Override
-	public final ServiceErrorWriter getErrorWriter(){
+	public final ServiceErrorWriter getErrorWriter() {
 		return errorWriter;
 	}
 
@@ -110,7 +117,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public ADQLExecutor createADQLExecutor() throws TAPException{
+	public ADQLExecutor createADQLExecutor() throws TAPException {
 		return new ADQLExecutor(service);
 	}
 
@@ -120,8 +127,8 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public ADQLParser createADQLParser() throws TAPException{
-		return new ADQLParser();
+	public ADQLParser createADQLParser() throws TAPException {
+		return parserFactory.createParser();
 	}
 
 	/**
@@ -132,7 +139,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public ADQLQueryFactory createQueryFactory() throws TAPException{
+	public ADQLQueryFactory createQueryFactory() throws TAPException {
 		return new ADQLQueryFactory();
 	}
 
@@ -147,7 +154,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public final QueryChecker createQueryChecker(final TAPSchema uploadSchema) throws TAPException{
+	public final QueryChecker createQueryChecker(final TAPSchema uploadSchema) throws TAPException {
 		// Get all tables published in this TAP service:
 		TAPMetadata meta = service.getTAPMetadata();
 
@@ -160,7 +167,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 			tables.add(it.next());
 
 		// Add all tables uploaded by the user:
-		if (uploadSchema != null){
+		if (uploadSchema != null) {
 			for(TAPTable table : uploadSchema)
 				tables.add(table);
 		}
@@ -184,10 +191,10 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 *
 	 * @throws TAPException	If any error occurs while creating the query checker.
 	 */
-	protected QueryChecker createQueryChecker(final Collection<TAPTable> tables) throws TAPException{
-		try{
+	protected QueryChecker createQueryChecker(final Collection<TAPTable> tables) throws TAPException {
+		try {
 			return new DBChecker(tables, service.getUDFs(), service.getGeometries(), service.getCoordinateSystems());
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			throw new TAPException("Unable to build a DBChecker instance! " + e.getMessage(), e, UWSException.INTERNAL_SERVER_ERROR);
 		}
 	}
@@ -207,7 +214,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public Uploader createUploader(final DBConnection dbConn) throws TAPException{
+	public Uploader createUploader(final DBConnection dbConn) throws TAPException {
 		return new Uploader(service, dbConn);
 	}
 
@@ -224,13 +231,13 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </i></p>
 	 */
 	@Override
-	public UWSService createUWS() throws TAPException{
-		try{
+	public UWSService createUWS() throws TAPException {
+		try {
 			UWSService uws = new UWSService(this, this.service.getFileManager(), this.service.getLogger());
 			uws.setName("TAP/async");
 			uws.setErrorWriter(errorWriter);
 			return uws;
-		}catch(UWSException ue){
+		} catch(UWSException ue) {
 			throw new TAPException("Can not create a UWS service (asynchronous resource of TAP)!", ue, UWSException.INTERNAL_SERVER_ERROR);
 		}
 	}
@@ -242,7 +249,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * <p>You must override this function if you want enable the backup feature.</p>
 	 */
 	@Override
-	public UWSBackupManager createUWSBackupManager(final UWSService uws) throws TAPException{
+	public UWSBackupManager createUWSBackupManager(final UWSService uws) throws TAPException {
 		return null;
 	}
 
@@ -255,8 +262,8 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </p>
 	 */
 	@Override
-	protected TAPJob createTAPJob(final HttpServletRequest request, final JobOwner owner) throws UWSException{
-		try{
+	protected TAPJob createTAPJob(final HttpServletRequest request, final JobOwner owner) throws UWSException {
+		try {
 			// Extract the HTTP request ID (the job ID should be the same, if not already used by another job):
 			String requestID = null;
 			if (request.getAttribute(UWS.REQ_ATTRIBUTE_ID) != null && request.getAttribute(UWS.REQ_ATTRIBUTE_ID) instanceof String)
@@ -267,7 +274,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 
 			// Create the job:
 			return new TAPJob(owner, tapParams, requestID);
-		}catch(TAPException te){
+		} catch(TAPException te) {
 			if (te.getCause() != null && te.getCause() instanceof UWSException)
 				throw (UWSException)te.getCause();
 			else
@@ -285,10 +292,10 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </p>
 	 */
 	@Override
-	protected TAPJob createTAPJob(final String jobId, final long creationTime, final JobOwner owner, final TAPParameters params, final long quote, final long startTime, final long endTime, final List<Result> results, final ErrorSummary error) throws UWSException{
-		try{
+	protected TAPJob createTAPJob(final String jobId, final long creationTime, final JobOwner owner, final TAPParameters params, final long quote, final long startTime, final long endTime, final List<Result> results, final ErrorSummary error) throws UWSException {
+		try {
 			return new TAPJob(jobId, creationTime, owner, params, quote, startTime, endTime, results, error);
-		}catch(TAPException te){
+		} catch(TAPException te) {
 			if (te.getCause() != null && te.getCause() instanceof UWSException)
 				throw (UWSException)te.getCause();
 			else
@@ -307,7 +314,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </p>
 	 */
 	@Override
-	public TAPParameters createTAPParameters(final HttpServletRequest request) throws TAPException{
+	public TAPParameters createTAPParameters(final HttpServletRequest request) throws TAPException {
 		return new TAPParameters(request, service);
 	}
 
@@ -322,7 +329,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	 * </p>
 	 */
 	@Override
-	public TAPParameters createTAPParameters(final Map<String,Object> params) throws TAPException{
+	public TAPParameters createTAPParameters(final Map<String, Object> params) throws TAPException {
 		return new TAPParameters(service, params);
 	}
 
diff --git a/test/adql/db/TestDBChecker.java b/test/adql/db/TestDBChecker.java
index 3e675ae1ee20e60ef24eb876c64f405b46ed8736..c35ab326260dda2fc6b5484dffc9977b1efaa394 100644
--- a/test/adql/db/TestDBChecker.java
+++ b/test/adql/db/TestDBChecker.java
@@ -22,6 +22,7 @@ import adql.db.DBType.DBDatatype;
 import adql.db.FunctionDef.FunctionParam;
 import adql.db.exception.UnresolvedIdentifiersException;
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.query.ADQLObject;
 import adql.query.ADQLQuery;
@@ -37,10 +38,12 @@ import adql.translator.TranslationException;
 
 public class TestDBChecker {
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	private static List<DBTable> tables;
 
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{
+	public static void setUpBeforeClass() throws Exception {
 		tables = new ArrayList<DBTable>();
 
 		DefaultDBTable fooTable = new DefaultDBTable(null, "aschema", "foo");
@@ -61,62 +64,67 @@ public class TestDBChecker {
 	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{}
+	public static void tearDownAfterClass() throws Exception {
+	}
 
 	@Before
-	public void setUp() throws Exception{}
+	public void setUp() throws Exception {
+	}
 
 	@After
-	public void tearDown() throws Exception{}
+	public void tearDown() throws Exception {
+	}
 
 	@Test
-	public void testSplitTableName(){
+	public void testSplitTableName() {
 		String[] names = DefaultDBTable.splitTableName("foo");
-		String[] expected = new String[]{null,null,"foo"};
+		String[] expected = new String[]{ null, null, "foo" };
 		assertEquals(expected.length, names.length);
 		for(int i = 0; i < names.length; i++)
 			assertEquals(expected[i], names[i]);
 
 		names = DefaultDBTable.splitTableName("aschema.foo");
-		expected = new String[]{null,"aschema","foo"};
+		expected = new String[]{ null, "aschema", "foo" };
 		assertEquals(expected.length, names.length);
 		for(int i = 0; i < names.length; i++)
 			assertEquals(expected[i], names[i]);
 
 		names = DefaultDBTable.splitTableName("acat.aschema.foo");
-		expected = new String[]{"acat","aschema","foo"};
+		expected = new String[]{ "acat", "aschema", "foo" };
 		assertEquals(expected.length, names.length);
 		for(int i = 0; i < names.length; i++)
 			assertEquals(expected[i], names[i]);
 
 		names = DefaultDBTable.splitTableName("weird.acat.aschema.foo");
-		expected = new String[]{"weird.acat","aschema","foo"};
+		expected = new String[]{ "weird.acat", "aschema", "foo" };
 		assertEquals(expected.length, names.length);
 		for(int i = 0; i < names.length; i++)
 			assertEquals(expected[i], names[i]);
 	}
 
 	@Test
-	public void testClauseADQLWithNameNull(){
+	public void testClauseADQLWithNameNull() {
 		/* The name of an ADQLClause is got in DBChecker by SearchColumnOutsideGroupByHandler.goInto(...)
 		 * and possibly in other locations in the future. If this name is NULL, no NullPointerException
 		 * should be thrown.
 		 *
 		 * This issue can be tested by creating a ConstraintsGroup (i.e. in a constraints location like WHERE or JOIN...ON,
 		 * a constraint (or more) between parenthesis). */
-		ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
-		try{
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
+		try {
 			parser.parseQuery("SELECT * FROM foo WHERE (colI BETWEEN 1 AND 10)");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail();
 		}
 	}
 
 	@Test
-	public void testGroupByWithQualifiedColName(){
-		ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
-		try{
+	public void testGroupByWithQualifiedColName() {
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
+		try {
 			// Not qualified column name:
 			parser.parseQuery("SELECT colI, COUNT(*) AS cnt FROM foo GROUP BY colI");
 			// Qualified with the table name:
@@ -125,16 +133,17 @@ public class TestDBChecker {
 			parser.parseQuery("SELECT f.colI, COUNT(*) AS cnt FROM foo AS f GROUP BY f.colI");
 			// With the SELECT item alias:
 			parser.parseQuery("SELECT colI AS mycol, COUNT(*) AS cnt FROM foo GROUP BY mycol");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail();
 		}
 	}
 
 	@Test
-	public void testQualifiedName(){
-		ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
-		try{
+	public void testQualifiedName() {
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
+		try {
 			// Tests with a table whose the schema is specified:
 			parser.parseQuery("SELECT * FROM foo;");
 			parser.parseQuery("SELECT * FROM aschema.foo;");
@@ -155,26 +164,29 @@ public class TestDBChecker {
 			parser.parseQuery("SELECT \"oid\" FROM \"foo2\";");
 			parser.parseQuery("SELECT foo2.oid FROM foo2;");
 			parser.parseQuery("SELECT \"foo2\".\"oid\" FROM \"foo2\";");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail();
 		}
 
 		// If no schema is specified, then the table is not part of a schema and so, there is no reason a table with a fake schema prefix should work:
-		try{
+		try {
 			parser.parseQuery("SELECT * FROM noschema.foo2;");
 			fail("The table \"foo2\" has no schema specified and so, is not part of a schema. A fake schema prefix should then be forbidden!");
-		}catch(ParseException pe){}
-		try{
+		} catch(ParseException pe) {
+		}
+		try {
 			parser.parseQuery("SELECT noschema.foo2.* FROM foo2;");
 			fail("The table \"foo2\" has no schema specified and so, is not part of a schema. A fake schema prefix should then be forbidden!");
-		}catch(ParseException pe){}
+		} catch(ParseException pe) {
+		}
 	}
 
 	@Test
-	public void testColRefWithDottedAlias(){
-		ADQLParser parser = new ADQLParser(new DBChecker(tables));
-		try{
+	public void testColRefWithDottedAlias() {
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables));
+		try {
 			// ORDER BY
 			ADQLQuery adql = parser.parseQuery("SELECT colI AS \"col.I\" FROM aschema.foo ORDER BY \"col.I\"");
 			assertNotNull(adql);
@@ -184,19 +196,19 @@ public class TestDBChecker {
 			adql = parser.parseQuery("SELECT colI AS \"col.I\" FROM aschema.foo GROUP BY \"col.I\"");
 			assertNotNull(adql);
 			assertEquals("SELECT \"aschema\".\"foo\".\"colI\" AS \"col.I\"\nFROM \"aschema\".\"foo\"\nGROUP BY \"col.I\"", (new PostgreSQLTranslator()).translate(adql));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail();
-		}catch(TranslationException te){
+		} catch(TranslationException te) {
 			te.printStackTrace();
 			fail();
 		}
 	}
 
 	@Test
-	public void testNumericOrStringValueExpressionPrimary(){
-		ADQLParser parser = new ADQLParser();
-		try{
+	public void testNumericOrStringValueExpressionPrimary() {
+		ADQLParser parser = parserFactory.createParser();
+		try {
 			assertNotNull(parser.parseQuery("SELECT 'toto' FROM foo;"));
 			assertNotNull(parser.parseQuery("SELECT ('toto') FROM foo;"));
 			assertNotNull(parser.parseQuery("SELECT (('toto')) FROM foo;"));
@@ -215,50 +227,56 @@ public class TestDBChecker {
 			assertNotNull(parser.parseQuery("SELECT 'toto' || 1 FROM foo;"));
 			assertNotNull(parser.parseQuery("SELECT 1 || 'toto' FROM foo;"));
 			assertNotNull(parser.parseQuery("SELECT 'toto' || (-1) FROM foo;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail();
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT ABS('toto') FROM foo;");
 			fail();
-		}catch(ParseException pe){}
-		try{
+		} catch(ParseException pe) {
+		}
+		try {
 			parser.parseQuery("SELECT 'toto' || -1 FROM foo;");
 			fail();
-		}catch(ParseException pe){}
-		try{
+		} catch(ParseException pe) {
+		}
+		try {
 			parser.parseQuery("SELECT -1 || 'toto' FROM foo;");
 			fail();
-		}catch(ParseException pe){}
-		try{
+		} catch(ParseException pe) {
+		}
+		try {
 			parser.parseQuery("SELECT ABS(('toto' || 'blabla')) FROM foo;");
 			fail();
-		}catch(ParseException pe){}
-		try{
+		} catch(ParseException pe) {
+		}
+		try {
 			parser.parseQuery("SELECT 'toto' * 3 FROM foo;");
 			fail();
-		}catch(ParseException pe){}
+		} catch(ParseException pe) {
+		}
 	}
 
 	@Test
-	public void testUDFManagement(){
+	public void testUDFManagement() {
 		// UNKNOWN FUNCTIONS ARE NOT ALLOWED:
-		ADQLParser parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0)));
 
 		// Test with a simple ADQL query without unknown or user defined function:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT * FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("A simple and basic query should not be a problem for the parser!");
 		}
 
 		// Test with an ADQL query containing one not declared UDF:
-		try{
+		try {
 			parser.parseQuery("SELECT toto() FROM foo;");
 			fail("This query contains a UDF while it's not allowed: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -266,23 +284,24 @@ public class TestDBChecker {
 		}
 
 		// DECLARE THE UDFs:
-		FunctionDef[] udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)),new FunctionDef("tata", new DBType(DBDatatype.INTEGER))};
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));
+		FunctionDef[] udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)), new FunctionDef("tata", new DBType(DBDatatype.INTEGER)) };
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 
 		// Test again:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT toto() FROM foo;"));
 			assertNotNull(parser.parseQuery("SELECT tata() FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a DECLARED UDF: this test should have succeeded!");
 		}
 
 		// Test but with at least one parameter:
-		try{
+		try {
 			parser.parseQuery("SELECT toto('blabla') FROM foo;");
 			fail("This query contains an unknown UDF signature (the fct toto is declared with no parameter): this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -290,10 +309,10 @@ public class TestDBChecker {
 		}
 
 		// Test but with at least one column parameter:
-		try{
+		try {
 			parser.parseQuery("SELECT toto(colS) FROM foo;");
 			fail("This query contains an unknown UDF signature (the fct toto is declared with no parameter): this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -301,10 +320,10 @@ public class TestDBChecker {
 		}
 
 		// Test but with at least one unknown column parameter:
-		try{
+		try {
 			parser.parseQuery("SELECT toto(whatami) FROM foo;");
 			fail("This query contains an unknown UDF signature (the fct toto is declared with no parameter): this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(2, ex.getNbErrors());
@@ -314,31 +333,32 @@ public class TestDBChecker {
 		}
 
 		// Test with a UDF whose the class is specified ; the corresponding object in the ADQL tree must be replace by an instance of this class:
-		udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("txt", new DBType(DBDatatype.VARCHAR))})};
+		udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("txt", new DBType(DBDatatype.VARCHAR)) }) };
 		udfs[0].setUDFClass(UDFToto.class);
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));
-		try{
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT toto('blabla') FROM foo;");
 			assertNotNull(query);
-			Iterator<ADQLObject> it = query.search(new SimpleSearchHandler(){
+			Iterator<ADQLObject> it = query.search(new SimpleSearchHandler() {
 				@Override
-				protected boolean match(ADQLObject obj){
+				protected boolean match(ADQLObject obj) {
 					return (obj instanceof UserDefinedFunction) && ((UserDefinedFunction)obj).getName().equals("toto");
 				}
 			});
 			assertTrue(it.hasNext());
 			assertEquals(UDFToto.class.getName(), it.next().getClass().getName());
 			assertFalse(it.hasNext());
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace();
 			fail("This query contains a DECLARED UDF with a valid UserDefinedFunction class: this test should have succeeded!");
 		}
 
 		// Test with a wrong parameter type:
-		try{
+		try {
 			parser.parseQuery("SELECT toto(123) FROM foo;");
 			fail("This query contains an unknown UDF signature (the fct toto is declared with one parameter of type STRING...here it is a numeric): this test should have failed!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -346,13 +366,14 @@ public class TestDBChecker {
 		}
 
 		// Test with UDF class constructor throwing an exception:
-		udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("txt", new DBType(DBDatatype.VARCHAR))})};
+		udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("txt", new DBType(DBDatatype.VARCHAR)) }) };
 		udfs[0].setUDFClass(WrongUDFToto.class);
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));
-		try{
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
+		try {
 			parser.parseQuery("SELECT toto('blabla') FROM foo;");
 			fail("The set UDF class constructor has throw an error: this test should have failed!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -361,30 +382,32 @@ public class TestDBChecker {
 	}
 
 	@Test
-	public void testGeometry(){
+	public void testGeometry() {
 		// DECLARE A SIMPLE PARSER where all geometries are allowed by default:
-		ADQLParser parser = new ADQLParser(new DBChecker(tables));
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables));
 
 		// Test with several geometries while all are allowed:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains several geometries, and all are theoretically allowed: this test should have succeeded!");
 		}
 
 		// Test with several geometries while only the allowed ones:
-		try{
-			parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0), Arrays.asList(new String[]{"CONTAINS","POINT","CIRCLE"}), null));
+		try {
+			parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0), Arrays.asList(new String[]{ "CONTAINS", "POINT", "CIRCLE" }), null));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains several geometries, and all are theoretically allowed: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT * FROM foo WHERE INTERSECTS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;");
 			fail("This query contains a not-allowed geometry function (INTERSECTS): this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(1, ex.getNbErrors());
@@ -392,17 +415,18 @@ public class TestDBChecker {
 		}
 
 		// Test by adding REGION:
-		try{
-			parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0), Arrays.asList(new String[]{"CONTAINS","POINT","CIRCLE","REGION"}), null));
+		try {
+			parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0), Arrays.asList(new String[]{ "CONTAINS", "POINT", "CIRCLE", "REGION" }), null));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(REGION('Position 12.3 45.6'), REGION('circle 1.2 2.3 5')) = 1;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains several geometries, and all are theoretically allowed: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(REGION('Position 12.3 45.6'), REGION('BOX 1.2 2.3 5 9')) = 1;");
 			fail("This query contains a not-allowed geometry function (BOX): this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(1, ex.getNbErrors());
@@ -410,11 +434,12 @@ public class TestDBChecker {
 		}
 
 		// Test with several geometries while none geometry is allowed:
-		try{
-			parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0), new ArrayList<String>(0), null));
+		try {
+			parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0), new ArrayList<String>(0), null));
 			parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;");
 			fail("This query contains geometries while they are all forbidden: this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(3, ex.getNbErrors());
@@ -426,34 +451,36 @@ public class TestDBChecker {
 	}
 
 	@Test
-	public void testCoordSys(){
+	public void testCoordSys() {
 		// DECLARE A SIMPLE PARSER where all coordinate systems are allowed by default:
-		ADQLParser parser = new ADQLParser(new DBChecker(tables));
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables));
 
 		// Test with several coordinate systems while all are allowed:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('icrs', 12.3, 45.6), CIRCLE('cartesian2', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('lsr', 12.3, 45.6), CIRCLE('galactic heliocenter', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('unknownframe', 12.3, 45.6), CIRCLE('galactic unknownrefpos spherical2', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(REGION('position icrs lsr 12.3 45.6'), REGION('circle fk5 1.2 2.3 5')) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT Region('not(position 1 2)') FROM foo;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains several valid coordinate systems, and all are theoretically allowed: this test should have succeeded!");
 		}
 
 		// Concatenation as coordinate systems not checked:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('From ' || 'here', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains a concatenation as coordinate systems (but only string constants are checked): this test should have succeeded!");
 		}
 
 		// Test with several coordinate systems while only some allowed:
-		try{
-			parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0), null, Arrays.asList(new String[]{"icrs * *","fk4 geocenter *","galactic * spherical2"})));
+		try {
+			parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0), null, Arrays.asList(new String[]{ "icrs * *", "fk4 geocenter *", "galactic * spherical2" })));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('icrs', 12.3, 45.6), CIRCLE('cartesian3', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT POINT('fk4', 12.3, 45.6) FROM foo;"));
@@ -462,23 +489,23 @@ public class TestDBChecker {
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('galactic geocenter', 12.3, 45.6), CIRCLE('galactic lsr spherical2', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(REGION('position galactic lsr 12.3 45.6'), REGION('circle icrs 1.2 2.3 5')) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT Region('not(position 1 2)') FROM foo;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query contains several valid coordinate systems, and all are theoretically allowed: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT POINT('fk5 geocenter', 12.3, 45.6) FROM foo;");
 			fail("This query contains a not-allowed coordinate system ('fk5' is not allowed): this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Coordinate system \"fk5 geocenter\" (= \"FK5 GEOCENTER SPHERICAL2\") not allowed in this implementation. Allowed coordinate systems are: fk4 geocenter *, galactic * spherical2, icrs * *", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT Region('not(position fk5 heliocenter 1 2)') FROM foo;");
 			fail("This query contains a not-allowed coordinate system ('fk5' is not allowed): this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(1, ex.getNbErrors());
@@ -486,19 +513,20 @@ public class TestDBChecker {
 		}
 
 		// Test with a coordinate system while none is allowed:
-		try{
-			parser = new ADQLParser(new DBChecker(tables, new ArrayList<FunctionDef>(0), null, new ArrayList<String>(0)));
+		try {
+			parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables, new ArrayList<FunctionDef>(0), null, new ArrayList<String>(0)));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('', 12.3, 45.6), CIRCLE('', 1.2, 2.3, 5)) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(REGION('position 12.3 45.6'), REGION('circle 1.2 2.3 5')) = 1;"));
 			assertNotNull(parser.parseQuery("SELECT Region('not(position 1 2)') FROM foo;"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("This query specifies none coordinate system: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT * FROM foo WHERE CONTAINS(POINT('ICRS SPHERICAL2', 12.3, 45.6), CIRCLE('icrs', 1.2, 2.3, 5)) = 1;");
 			fail("This query specifies coordinate systems while they are all forbidden: this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(2, ex.getNbErrors());
@@ -506,10 +534,10 @@ public class TestDBChecker {
 			assertEquals("Coordinate system \"ICRS SPHERICAL2\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation. No coordinate system is allowed!", itErrors.next().getMessage());
 			assertEquals("Coordinate system \"icrs\" (= \"ICRS UNKNOWNREFPOS SPHERICAL2\") not allowed in this implementation. No coordinate system is allowed!", itErrors.next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT Region('not(position fk4 1 2)') FROM foo;");
 			fail("This query specifies coordinate systems while they are all forbidden: this test should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertTrue(pe instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)pe;
 			assertEquals(1, ex.getNbErrors());
@@ -518,12 +546,13 @@ public class TestDBChecker {
 	}
 
 	@Test
-	public void testTypesChecking(){
+	public void testTypesChecking() {
 		// DECLARE A SIMPLE PARSER:
-		ADQLParser parser = new ADQLParser(new DBChecker(tables));
+		ADQLParser parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables));
 
 		// Test the type of columns generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT colS, colI, colG FROM foo;");
 			ADQLOperand colS = query.getSelect().get(0).getOperand();
 			ADQLOperand colI = query.getSelect().get(1).getOperand();
@@ -543,7 +572,7 @@ public class TestDBChecker {
 			assertFalse(colG.isString());
 			assertFalse(colG.isNumeric());
 			assertTrue(colG.isGeometry());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			if (e1 instanceof UnresolvedIdentifiersException)
 				((UnresolvedIdentifiersException)e1).getErrors().next().printStackTrace();
 			else
@@ -552,25 +581,25 @@ public class TestDBChecker {
 		}
 
 		// Test the expected type - NUMERIC - generated by the parser:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT colI * 3 FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a product between 2 numerics: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT colS * 3 FROM foo;");
 			fail("This query contains a product between a string and an integer: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Type mismatch! A numeric value was expected instead of \"colS\".", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT colG * 3 FROM foo;");
 			fail("This query contains a product between a geometry and an integer: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -578,45 +607,45 @@ public class TestDBChecker {
 		}
 
 		// Test the expected type - STRING - generated by the parser:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT colS || 'blabla' FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a concatenation between 2 strings: this test should have succeeded!");
 		}
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT colI || 'blabla' FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a concatenation between a column (whatever its type) and a string: this test should have succeeded!");
 		}
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT colG || 'blabla' FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a concatenation between a column (whatever its type) and a string: this test should have succeeded!");
 		}
 
 		// Test the expected type - GEOMETRY - generated by the parser:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT CONTAINS(colG, CIRCLE('', 1, 2, 5)) FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("This query contains a geometrical predicate between 2 geometries: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT CONTAINS(colI, CIRCLE('', 1, 2, 5)) FROM foo;");
 			fail("This query contains a geometrical predicate between an integer and a geometry: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Type mismatch! A geometry was expected instead of \"colI\".", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT CONTAINS(colS, CIRCLE('', 1, 2, 5)) FROM foo;");
 			fail("This query contains a geometrical predicate between a string and a geometry: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -624,11 +653,12 @@ public class TestDBChecker {
 		}
 
 		// DECLARE SOME UDFs:
-		FunctionDef[] udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)),new FunctionDef("tata", new DBType(DBDatatype.INTEGER)),new FunctionDef("titi", new DBType(DBDatatype.REGION))};
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));
+		FunctionDef[] udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)), new FunctionDef("tata", new DBType(DBDatatype.INTEGER)), new FunctionDef("titi", new DBType(DBDatatype.REGION)) };
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 
 		// Test the return type of the function TOTO generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
 			ADQLOperand fct = query.getSelect().get(0).getOperand();
 			assertTrue(fct instanceof DefaultUDF);
@@ -636,22 +666,22 @@ public class TestDBChecker {
 			assertTrue(fct.isString());
 			assertFalse(fct.isNumeric());
 			assertFalse(fct.isGeometry());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains a DECLARED UDF: this test should have succeeded!");
 		}
 
 		// Test the return type checking inside a whole query:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT toto() || 'Blabla ' AS \"SuperText\" FROM foo;"));
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains a DECLARED UDF concatenated to a String: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT toto()*3 AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			assertTrue(e1 instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e1;
 			assertEquals(1, ex.getNbErrors());
@@ -659,7 +689,7 @@ public class TestDBChecker {
 		}
 
 		// Test the return type of the function TATA generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT tata() FROM foo;");
 			ADQLOperand fct = query.getSelect().get(0).getOperand();
 			assertTrue(fct instanceof DefaultUDF);
@@ -667,31 +697,31 @@ public class TestDBChecker {
 			assertFalse(fct.isString());
 			assertTrue(fct.isNumeric());
 			assertFalse(fct.isGeometry());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains a DECLARED UDF: this test should have succeeded!");
 		}
 
 		// Test the return type checking inside a whole query:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT tata()*3 AS \"aNumeric\" FROM foo;"));
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains a DECLARED UDF multiplicated by 3: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT 'Blabla ' || tata() AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			assertTrue(e1 instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e1;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Type mismatch! A string value was expected instead of \"tata()\".", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT tata() || 'Blabla ' AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			assertTrue(e1 instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e1;
 			assertEquals(1, ex.getNbErrors());
@@ -699,7 +729,7 @@ public class TestDBChecker {
 		}
 
 		// Test the return type of the function TITI generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT titi() FROM foo;");
 			ADQLOperand fct = query.getSelect().get(0).getOperand();
 			assertTrue(fct instanceof DefaultUDF);
@@ -707,23 +737,23 @@ public class TestDBChecker {
 			assertFalse(fct.isString());
 			assertFalse(fct.isNumeric());
 			assertTrue(fct.isGeometry());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains a DECLARED UDF: this test should have succeeded!");
 		}
 
 		// Test the return type checking inside a whole query:
-		try{
+		try {
 			parser.parseQuery("SELECT CONTAINS(colG, titi()) ' AS \"Super\" FROM foo;");
 			fail("Geometrical UDFs are not allowed for the moment in the ADQL language: this test should have failed!");
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			assertTrue(e1 instanceof ParseException);
 			assertEquals(" Encountered \"(\". Was expecting one of: \")\" \".\" \".\" \")\" ", e1.getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT titi()*3 AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			assertTrue(e1 instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e1;
 			assertEquals(1, ex.getNbErrors());
@@ -733,22 +763,23 @@ public class TestDBChecker {
 		// Try with functions wrapped on 2 levels:
 		// i.e. fct1('blabla', fct2(fct3('blabla')))
 		FunctionDef[] complexFcts = new FunctionDef[3];
-		complexFcts[0] = new FunctionDef("fct1", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR)),new FunctionParam("num", new DBType(DBDatatype.INTEGER))});
-		complexFcts[1] = new FunctionDef("fct2", new DBType(DBDatatype.INTEGER), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR))});
-		complexFcts[2] = new FunctionDef("fct3", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("str", new DBType(DBDatatype.VARCHAR))});
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(complexFcts)));
+		complexFcts[0] = new FunctionDef("fct1", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("str", new DBType(DBDatatype.VARCHAR)), new FunctionParam("num", new DBType(DBDatatype.INTEGER)) });
+		complexFcts[1] = new FunctionDef("fct2", new DBType(DBDatatype.INTEGER), new FunctionParam[]{ new FunctionParam("str", new DBType(DBDatatype.VARCHAR)) });
+		complexFcts[2] = new FunctionDef("fct3", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("str", new DBType(DBDatatype.VARCHAR)) });
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(complexFcts)));
 		// With parameters of the good type:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT fct1('blabla', fct2(fct3('blabla'))) FROM foo"));
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("Types are matching: this test should have succeeded!");
 		}
 		// With parameters of the bad type:
-		try{
+		try {
 			parser.parseQuery("SELECT fct2(fct1('blabla', fct3('blabla'))) FROM foo");
 			fail("Parameters types are not matching: the parsing should have failed!");
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			assertEquals(UnresolvedIdentifiersException.class, pe.getClass());
 			assertEquals(1, ((UnresolvedIdentifiersException)pe).getNbErrors());
 			ParseException innerPe = ((UnresolvedIdentifiersException)pe).getErrors().next();
@@ -756,78 +787,81 @@ public class TestDBChecker {
 		}
 
 		// CLEAR ALL UDFs AND ALLOW UNKNOWN FUNCTION:
-		parser = new ADQLParser(new DBChecker(tables, null));
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, null));
 
 		// Test again:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT toto() FROM foo;"));
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			e.printStackTrace();
 			fail("The parser allow ANY unknown function: this test should have succeeded!");
 		}
 
 		// Test the return type of the function generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
 			ADQLOperand fct = query.getSelect().get(0).getOperand();
 			assertTrue(fct instanceof DefaultUDF);
 			assertNull(((DefaultUDF)fct).getDefinition());
 			assertTrue(fct.isString());
 			assertTrue(fct.isNumeric());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("The parser allow ANY unknown function: this test should have succeeded!");
 		}
 
 		// DECLARE THE UDF (while unknown functions are allowed):
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR))})));
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR)) })));
 
 		// Test the return type of the function generated by the parser:
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT toto() FROM foo;");
 			ADQLOperand fct = query.getSelect().get(0).getOperand();
 			assertTrue(fct instanceof DefaultUDF);
 			assertNotNull(((DefaultUDF)fct).getDefinition());
 			assertTrue(fct.isString());
 			assertFalse(fct.isNumeric());
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("The parser allow ANY unknown function: this test should have succeeded!");
 		}
 
 		// DECLARE UDFs WITH SAME NAMES BUT DIFFERENT TYPE OF ARGUMENT:
-		udfs = new FunctionDef[]{new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{new FunctionParam("attr", new DBType(DBDatatype.VARCHAR))}),new FunctionDef("toto", new DBType(DBDatatype.INTEGER), new FunctionParam[]{new FunctionParam("attr", new DBType(DBDatatype.INTEGER))}),new FunctionDef("toto", new DBType(DBDatatype.INTEGER), new FunctionParam[]{new FunctionParam("attr", new DBType(DBDatatype.POINT))})};
-		parser = new ADQLParser(new DBChecker(tables, Arrays.asList(udfs)));
+		udfs = new FunctionDef[]{ new FunctionDef("toto", new DBType(DBDatatype.VARCHAR), new FunctionParam[]{ new FunctionParam("attr", new DBType(DBDatatype.VARCHAR)) }), new FunctionDef("toto", new DBType(DBDatatype.INTEGER), new FunctionParam[]{ new FunctionParam("attr", new DBType(DBDatatype.INTEGER)) }), new FunctionDef("toto", new DBType(DBDatatype.INTEGER), new FunctionParam[]{ new FunctionParam("attr", new DBType(DBDatatype.POINT)) }) };
+		parser = parserFactory.createParser();
+		parser.setQueryChecker(new DBChecker(tables, Arrays.asList(udfs)));
 
 		// Test the return type in function of the parameter:
-		try{
+		try {
 			assertNotNull(parser.parseQuery("SELECT toto('blabla') AS toto1, toto(123) AS toto2, toto(POINT('', 1, 2)) AS toto3  FROM foo;"));
-		}catch(ParseException e1){
+		} catch(ParseException e1) {
 			e1.printStackTrace();
 			fail("This query contains two DECLARED UDFs used here: this test should have succeeded!");
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT toto('blabla') * 123 AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as numeric...which is here not possible: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Type mismatch! A numeric value was expected instead of \"toto('blabla')\".", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT toto(123) || 'blabla' AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
 			assertEquals("Type mismatch! A string value was expected instead of \"toto(123)\".", ex.getErrors().next().getMessage());
 		}
-		try{
+		try {
 			parser.parseQuery("SELECT toto(POINT('', 1, 2)) || 'blabla' AS \"SuperError\" FROM foo;");
 			fail("This query contains a DECLARED UDF BUT used as string...which is here not possible: this test should have failed!");
-		}catch(ParseException e){
+		} catch(ParseException e) {
 			assertTrue(e instanceof UnresolvedIdentifiersException);
 			UnresolvedIdentifiersException ex = (UnresolvedIdentifiersException)e;
 			assertEquals(1, ex.getNbErrors());
@@ -836,7 +870,7 @@ public class TestDBChecker {
 	}
 
 	private static class WrongUDFToto extends UDFToto {
-		public WrongUDFToto(final ADQLOperand[] params) throws Exception{
+		public WrongUDFToto(final ADQLOperand[] params) throws Exception {
 			super(params);
 			throw new Exception("Systematic error!");
 		}
@@ -845,7 +879,7 @@ public class TestDBChecker {
 	public static class UDFToto extends UserDefinedFunction {
 		protected StringConstant fakeParam;
 
-		public UDFToto(final ADQLOperand[] params) throws Exception{
+		public UDFToto(final ADQLOperand[] params) throws Exception {
 			if (params == null || params.length == 0)
 				throw new Exception("Missing parameter for the user defined function \"toto\"!");
 			else if (params.length > 1)
@@ -856,50 +890,50 @@ public class TestDBChecker {
 		}
 
 		@Override
-		public final boolean isNumeric(){
+		public final boolean isNumeric() {
 			return false;
 		}
 
 		@Override
-		public final boolean isString(){
+		public final boolean isString() {
 			return true;
 		}
 
 		@Override
-		public final boolean isGeometry(){
+		public final boolean isGeometry() {
 			return false;
 		}
 
 		@Override
-		public ADQLObject getCopy() throws Exception{
-			ADQLOperand[] params = new ADQLOperand[]{(StringConstant)fakeParam.getCopy()};
+		public ADQLObject getCopy() throws Exception {
+			ADQLOperand[] params = new ADQLOperand[]{ (StringConstant)fakeParam.getCopy() };
 			return new UDFToto(params);
 		}
 
 		@Override
-		public final String getName(){
+		public final String getName() {
 			return "toto";
 		}
 
 		@Override
-		public final ADQLOperand[] getParameters(){
-			return new ADQLOperand[]{fakeParam};
+		public final ADQLOperand[] getParameters() {
+			return new ADQLOperand[]{ fakeParam };
 		}
 
 		@Override
-		public final int getNbParameters(){
+		public final int getNbParameters() {
 			return 1;
 		}
 
 		@Override
-		public final ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException{
+		public final ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException {
 			if (index != 0)
 				throw new ArrayIndexOutOfBoundsException("Incorrect parameter index: " + index + "! The function \"toto\" has only one parameter.");
 			return fakeParam;
 		}
 
 		@Override
-		public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{
+		public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception {
 			if (index != 0)
 				throw new ArrayIndexOutOfBoundsException("Incorrect parameter index: " + index + "! The function \"toto\" has only one parameter.");
 			else if (!(replacer instanceof StringConstant))
@@ -908,7 +942,7 @@ public class TestDBChecker {
 		}
 
 		@Override
-		public String translate(final ADQLTranslator caller) throws TranslationException{
+		public String translate(final ADQLTranslator caller) throws TranslationException {
 			/* Note: Since this function is totally fake, this function will be replaced in SQL by its parameter (the string). */
 			return caller.translate(fakeParam);
 		}
diff --git a/test/adql/db/TestSTCS.java b/test/adql/db/TestSTCS.java
index 2f7698da8bbae233a8c81b2c5cda58683d83936a..e9c25f72e8f9990623a4ba7b081ccf2386619bc5 100644
--- a/test/adql/db/TestSTCS.java
+++ b/test/adql/db/TestSTCS.java
@@ -21,6 +21,7 @@ import adql.db.STCS.RefPos;
 import adql.db.STCS.Region;
 import adql.db.STCS.RegionType;
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.query.operand.ADQLColumn;
 import adql.query.operand.ADQLOperand;
@@ -42,46 +43,50 @@ import adql.query.operand.function.geometry.RegionFunction;
 public class TestSTCS {
 
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{}
+	public static void setUpBeforeClass() throws Exception {
+	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{}
+	public static void tearDownAfterClass() throws Exception {
+	}
 
 	@Before
-	public void setUp() throws Exception{}
+	public void setUp() throws Exception {
+	}
 
 	@After
-	public void tearDown() throws Exception{}
+	public void tearDown() throws Exception {
+	}
 
 	@Test
-	public void buildRegion(){
+	public void buildRegion() {
 		// Special values:
-		try{
+		try {
 			new Region((GeometryFunction)null);
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof NullPointerException);
 			assertEquals("Missing geometry to convert into STCS.Region!", e.getMessage());
 		}
 
-		try{
+		try {
 			new Region((Region)null);
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof NullPointerException);
 			assertEquals("Missing region to NOT select!", e.getMessage());
 		}
 
-		try{
+		try {
 			new Region(new ContainsFunction(new GeometryValue<GeometryFunction>(new RegionFunction(new StringConstant("position 1 2"))), new GeometryValue<GeometryFunction>(new RegionFunction(new StringConstant("circle 0 1 4")))));
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof IllegalArgumentException);
 			assertEquals("Unknown region type! Only geometrical function PointFunction, CircleFunction, BoxFunction, PolygonFunction and RegionFunction are allowed.", e.getMessage());
 		}
 
 		// Allowed values (1 test for each type of region):
-		try{
+		try {
 			Region r = new Region(new PointFunction(new StringConstant(""), new NumericConstant(1.2), new NegativeOperand(new NumericConstant(2.3))));
 			assertEquals(RegionType.POSITION, r.type);
 			assertEquals("", r.coordSys.toSTCS());
@@ -121,7 +126,7 @@ public class TestSTCS {
 			assertNull(r.regions);
 			assertEquals("BOX ICRS HELIOCENTER 1.2 -2.3 5.0 4.6", r.toSTCS());
 
-			r = new Region(new PolygonFunction(new StringConstant("cartesian2"), new ADQLOperand[]{new NumericConstant(1.2),new NegativeOperand(new NumericConstant(2.3)),new NumericConstant(5),new NumericConstant(4.6),new NegativeOperand(new NumericConstant(.89)),new NumericConstant(1)}));
+			r = new Region(new PolygonFunction(new StringConstant("cartesian2"), new ADQLOperand[]{ new NumericConstant(1.2), new NegativeOperand(new NumericConstant(2.3)), new NumericConstant(5), new NumericConstant(4.6), new NegativeOperand(new NumericConstant(.89)), new NumericConstant(1) }));
 			assertEquals(RegionType.POLYGON, r.type);
 			assertEquals("CARTESIAN2", r.coordSys.toSTCS());
 			assertEquals(3, r.coordinates.length);
@@ -221,78 +226,80 @@ public class TestSTCS {
 			assertEquals(Double.NaN, innerR.height, 0);
 			assertNull(innerR.regions);
 			assertEquals("CIRCLE ICRS 1.2 -2.3 5.0", innerR.toSTCS());
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail();
 		}
 
 		// Test with incorrect syntaxes:
-		try{
+		try {
 			new Region(new PointFunction(new StringConstant(""), new StringConstant("1.2"), new NegativeOperand(new NumericConstant(2.3))));
 			fail("The first coordinate is a StringConstant rather than a NumericConstant!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Can not convert into STC-S a non numeric argument (including ADQLColumn and Operation)!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new PointFunction(new NumericConstant(.65), new NumericConstant(1.2), new NegativeOperand(new NumericConstant(2.3))));
 			fail("The coordinate system is a NumericConstant rather than a StringConstant!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("A coordinate system must be a string literal: \"0.65\" is not a string operand!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new PointFunction(new StringConstant(""), null, new NegativeOperand(new NumericConstant(2.3))));
 			fail("The first coordinate is missing!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof NullPointerException);
 			assertEquals("The POINT function must have non-null coordinates!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new RegionFunction(new StringConstant("")));
 			fail("Missing STC-S expression!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Missing STC-S expression to parse!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new RegionFunction(new StringConstant("MyRegion HERE 1.2")));
 			fail("Totally incorrect region type!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Unknown STC region type: \"MYREGION\"!", e.getMessage());
 		}
-		try{
-			new Region(new RegionFunction((new ADQLParser(new StringBufferInputStream("'POSITION ' || coordinateSys || ' ' || ra || ' ' || dec"))).StringExpression()));
+		try {
+			ADQLParser parser = ADQLParserFactory.createDefaultParser();
+			parser.ReInit(new StringBufferInputStream("'POSITION ' || coordinateSys || ' ' || ra || ' ' || dec"));
+			new Region(new RegionFunction(parser.StringExpression()));
 			fail("String concatenation can not be managed!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Can not convert into STC-S a non string argument (including ADQLColumn and Concatenation)!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new PointFunction(new ADQLColumn("coordSys"), new NumericConstant(1), new NumericConstant(2)));
 			fail("Columns can not be managed!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Can not convert into STC-S a non string argument (including ADQLColumn and Concatenation)!", e.getMessage());
 		}
-		try{
+		try {
 			new Region(new PointFunction(new StringConstant("ICRS"), new Operation(new NumericConstant(2), OperationType.MULT, new NumericConstant(5)), new NumericConstant(2)));
 			fail("Operations can not be managed!");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Can not convert into STC-S a non numeric argument (including ADQLColumn and Operation)!", e.getMessage());
 		}
 	}
 
 	@Test
-	public void parseCoordSys(){
+	public void parseCoordSys() {
 		// GOOD SYNTAXES:
-		try{
+		try {
 			CoordSys p;
 
 			// Default coordinate system (should be then interpreted as local coordinate system):
-			for(String s : new String[]{null,"","  	"}){
+			for(String s : new String[]{ null, "", "  	" }) {
 				p = STCS.parseCoordSys(s);
 				assertEquals(Frame.UNKNOWNFRAME, p.frame);
 				assertEquals(RefPos.UNKNOWNREFPOS, p.refpos);
@@ -355,45 +362,45 @@ public class TestSTCS {
 			assertEquals(RefPos.GEOCENTER, p.refpos);
 			assertEquals(Flavor.SPHERICAL2, p.flavor);
 			assertFalse(p.isDefault());
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail();
 		}
 
 		// WRONG SYNTAXES:
-		try{
+		try {
 			STCS.parseCoordSys("HOME");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Incorrect syntax: \"HOME\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage());
 		}
 
 		// With wrong reference position:
-		try{
+		try {
 			STCS.parseCoordSys("ICRS HOME SPHERICAL2");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Incorrect syntax: \"HOME SPHERICAL2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage());
 		}
 
 		// With a cartesian flavor:
-		try{
+		try {
 			STCS.parseCoordSys("ICRS CARTESIAN2");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("a coordinate system expressed with a cartesian flavor MUST have an UNKNOWNFRAME and UNKNOWNREFPOS!", e.getMessage());
 		}
-		try{
+		try {
 			STCS.parseCoordSys("LSR CARTESIAN3");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("a coordinate system expressed with a cartesian flavor MUST have an UNKNOWNFRAME and UNKNOWNREFPOS!", e.getMessage());
 		}
-		try{
+		try {
 			CoordSys p = STCS.parseCoordSys("CARTESIAN2");
 			assertEquals(Frame.UNKNOWNFRAME, p.frame);
 			assertEquals(RefPos.UNKNOWNREFPOS, p.refpos);
@@ -403,24 +410,24 @@ public class TestSTCS {
 			assertEquals(Frame.UNKNOWNFRAME, p.frame);
 			assertEquals(RefPos.UNKNOWNREFPOS, p.refpos);
 			assertEquals(Flavor.CARTESIAN3, p.flavor);
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail();
 		}
 
 		// Without spaces:
-		try{
+		try {
 			STCS.parseCoordSys("icrsGeocentercarteSIAN2");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Incorrect syntax: \"icrsGeocentercarteSIAN2\" was unexpected! Expected syntax: \"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used.", e.getMessage());
 		}
 	}
 
 	@Test
-	public void serializeCoordSys(){
-		try{
+	public void serializeCoordSys() {
+		try {
 			assertEquals("", STCS.toSTCS((CoordSys)null));
 
 			assertEquals("", STCS.toSTCS(new CoordSys()));
@@ -459,75 +466,75 @@ public class TestSTCS {
 			assertEquals("UNKNOWNFRAME GEOCENTER SPHERICAL2", new CoordSys(Frame.UNKNOWNFRAME, RefPos.GEOCENTER, Flavor.DEFAULT).toFullSTCS());
 			assertEquals("UNKNOWNFRAME UNKNOWNREFPOS CARTESIAN3", new CoordSys(Frame.DEFAULT, RefPos.DEFAULT, Flavor.CARTESIAN3).toFullSTCS());
 			assertEquals("ICRS GEOCENTER SPHERICAL2", new CoordSys(Frame.ICRS, RefPos.GEOCENTER, Flavor.DEFAULT).toFullSTCS());
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace(System.err);
 			fail();
 		}
 	}
 
 	@Test
-	public void parseRegion(){
+	public void parseRegion() {
 		// TESTS WITH NO STC-S:
-		try{
+		try {
 			STCS.parseRegion(null);
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Missing STC-S expression to parse!", e.getMessage());
 		}
-		try{
+		try {
 			STCS.parseRegion("");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Missing STC-S expression to parse!", e.getMessage());
 		}
-		try{
+		try {
 			STCS.parseRegion("   	\n\r");
 			fail();
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertTrue(e instanceof ParseException);
 			assertEquals("Missing STC-S expression to parse!", e.getMessage());
 		}
 
 		// TESTS WITH A VALID EXPRESSION, EACH OF A DIFFERENT REGION TYPE:
-		String[] expressions = new String[]{" Position GALACTIC 10 20","Circle  	 ICRS    GEOCENTER	10	20	0.5 ","BOX cartesian2 3 3 2 2","Polygon 1 4 2 4 2 5 1 5","Union ICRS (Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)","INTERSECTION ICRS (Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)","NOT(Circle ICRS GEOCENTER 10 20 0.5)"};
-		try{
+		String[] expressions = new String[]{ " Position GALACTIC 10 20", "Circle  	 ICRS    GEOCENTER	10	20	0.5 ", "BOX cartesian2 3 3 2 2", "Polygon 1 4 2 4 2 5 1 5", "Union ICRS (Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)", "INTERSECTION ICRS (Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)", "NOT(Circle ICRS GEOCENTER 10 20 0.5)" };
+		try {
 			for(String e : expressions)
 				STCS.parseRegion(e);
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail();
 		}
 
 		// TEST WITH A MISSING PARAMETER:
-		expressions = new String[]{" Position GALACTIC 10 ","BOX cartesian2 3 3 2","NOT()"};
-		for(String e : expressions){
-			try{
+		expressions = new String[]{ " Position GALACTIC 10 ", "BOX cartesian2 3 3 2", "NOT()" };
+		for(String e : expressions) {
+			try {
 				STCS.parseRegion(e);
 				fail();
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				assertTrue(ex instanceof ParseException);
 				assertTrue(ex.getMessage().startsWith("Unexpected End Of Expression! Expected syntax: \""));
 			}
 		}
 
 		// TEST WITH A WRONG COORDINATE SYSTEM (since it is optional in all these expressions, it will be considered as a coordinate...which is of course, not the case):
-		try{
+		try {
 			STCS.parseRegion("Circle  	 HERE	10	20	0.5 ");
 			fail();
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			assertTrue(ex instanceof ParseException);
 			assertTrue(ex.getMessage().startsWith("Incorrect syntax: a coordinates pair (2 numerics separated by one or more spaces) was expected! Expected syntax: \"CIRCLE <coordSys> <coordPair> <radius>\", where coordPair=\"<numeric> <numeric>\", radius=\"<numeric>\" and coordSys=\"[(ECLIPTIC|FK4|FK5|J2000|GALACTIC|ICRS|UNKNOWNFRAME)] [(BARYCENTER|GEOCENTER|HELIOCENTER|LSR|TOPOCENTER|RELOCATABLE|UNKNOWNREFPOS)] [(CARTESIAN2|CARTESIAN3|SPHERICAL2)]\" ; an empty string is also allowed and will be interpreted as the coordinate system locally used."));
 		}
 
 		// TEST WITH EITHER A WRONG NUMERIC (L in lower case instead of 1) OR A MISSING OPENING PARENTHESIS:
-		expressions = new String[]{"Polygon 1 4 2 4 2 5 l 5","Union ICRS Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)"};
-		for(String e : expressions){
-			try{
+		expressions = new String[]{ "Polygon 1 4 2 4 2 5 l 5", "Union ICRS Polygon 1 4 2 4 2 5 1 5 Polygon 3 4 4 4 4 5 3 5)" };
+		for(String e : expressions) {
+			try {
 				STCS.parseRegion(e);
 				fail();
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				assertTrue(ex instanceof ParseException);
 				assertTrue(ex.getMessage().startsWith("Incorrect syntax: "));
 			}
diff --git a/test/adql/db/TestSubQueries.java b/test/adql/db/TestSubQueries.java
index d350de951466c63cef77ca882424823bc8855226..e6f675e0e2822acad88f3e8674c9baec9a3d294b 100644
--- a/test/adql/db/TestSubQueries.java
+++ b/test/adql/db/TestSubQueries.java
@@ -11,6 +11,7 @@ import org.junit.Before;
 import org.junit.Test;
 
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.query.ADQLQuery;
 import adql.translator.PostgreSQLTranslator;
 import tap.metadata.TAPMetadata;
@@ -19,12 +20,15 @@ import tap.metadata.TableSetParser;
 
 public class TestSubQueries {
 
+	ADQLParserFactory adqlParserFactory = new ADQLParserFactory();
+
 	@Before
-	public void setUp() throws Exception{}
+	public void setUp() throws Exception {
+	}
 
 	@Test
-	public void testSeveralSubqueries(){
-		try{
+	public void testSeveralSubqueries() {
+		try {
 			TableSetParser tsParser = new TableSetParser();
 			TAPMetadata esaMetaData = tsParser.parse(new File("test/adql/db/subquery_test_tables.xml"));
 			ArrayList<DBTable> esaTables = new ArrayList<DBTable>(esaMetaData.getNbTables());
@@ -32,19 +36,20 @@ public class TestSubQueries {
 			while(itTables.hasNext())
 				esaTables.add(itTables.next());
 
-			ADQLParser adqlParser = new ADQLParser(new DBChecker(esaTables));
+			ADQLParser adqlParser = adqlParserFactory.createParser();
+			adqlParser.setQueryChecker(new DBChecker(esaTables));
 			ADQLQuery query = adqlParser.parseQuery("SELECT sel2.*,t1.h_m, t1.j_m, t1.k_m\nFROM (\n  SELECT sel1.*, t3.*\n  FROM (\n  	SELECT *\n    FROM table2 AS t2\n	WHERE 1=CONTAINS(POINT('ICRS', t2.ra, t2.dec), CIRCLE('ICRS', 56.75, 24.1167, 15.))\n  ) AS sel1 JOIN table3 AS t3 ON t3.oid2=sel1.oid2\n) AS sel2 JOIN table1 AS t1 ON sel2.oid=t1.oid");
 			assertEquals("SELECT sel2.* , t1.h_m , t1.j_m , t1.k_m\nFROM (SELECT sel1.* , t3.*\nFROM (SELECT *\nFROM table2 AS t2\nWHERE 1 = CONTAINS(POINT('ICRS', t2.ra, t2.dec), CIRCLE('ICRS', 56.75, 24.1167, 15.))) AS sel1 INNER JOIN table3 AS t3 ON ON t3.oid2 = sel1.oid2) AS sel2 INNER JOIN table1 AS t1 ON ON sel2.oid = t1.oid", query.toADQL());
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("No error expected! (see console for more details)");
 		}
 	}
 
 	@Test
-	public void testFatherTableAliasIntoSubqueries(){
-		try{
+	public void testFatherTableAliasIntoSubqueries() {
+		try {
 			TableSetParser tsParser = new TableSetParser();
 			TAPMetadata esaMetaData = tsParser.parse(new File("test/adql/db/subquery_test_tables.xml"));
 			ArrayList<DBTable> esaTables = new ArrayList<DBTable>(esaMetaData.getNbTables());
@@ -52,19 +57,20 @@ public class TestSubQueries {
 			while(itTables.hasNext())
 				esaTables.add(itTables.next());
 
-			ADQLParser adqlParser = new ADQLParser(new DBChecker(esaTables));
+			ADQLParser adqlParser = adqlParserFactory.createParser();
+			adqlParser.setQueryChecker(new DBChecker(esaTables));
 
 			ADQLQuery query = adqlParser.parseQuery("SELECT oid FROM table1 as MyAlias WHERE oid IN (SELECT oid2 FROM table2 WHERE oid2 = myAlias.oid)");
 			assertEquals("SELECT \"myalias\".\"oid\" AS \"oid\"\nFROM \"public\".\"table1\" AS \"myalias\"\nWHERE \"myalias\".\"oid\" IN (SELECT \"public\".\"table2\".\"oid2\" AS \"oid2\"\nFROM \"public\".\"table2\"\nWHERE \"public\".\"table2\".\"oid2\" = \"myalias\".\"oid\")", (new PostgreSQLTranslator()).translate(query));
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("No error expected! (see console for more details)");
 		}
 	}
 
 	@Test
-	public void testParentRefToMixedCaseColumnAliasInsideSubQueries(){
-		try{
+	public void testParentRefToMixedCaseColumnAliasInsideSubQueries() {
+		try {
 			TableSetParser tsParser = new TableSetParser();
 			TAPMetadata esaMetaData = tsParser.parse(new File("test/adql/db/subquery_test_tables.xml"));
 			ArrayList<DBTable> esaTables = new ArrayList<DBTable>(esaMetaData.getNbTables());
@@ -72,11 +78,12 @@ public class TestSubQueries {
 			while(itTables.hasNext())
 				esaTables.add(itTables.next());
 
-			ADQLParser adqlParser = new ADQLParser(new DBChecker(esaTables));
+			ADQLParser adqlParser = adqlParserFactory.createParser();
+			adqlParser.setQueryChecker(new DBChecker(esaTables));
 
 			ADQLQuery query = adqlParser.parseQuery("SELECT t.* FROM (SELECT (ra+ra_error) AS x, (dec+dec_error) AS Y, pmra AS \"ProperMotion\" FROM table2) AS t");
 			assertEquals("SELECT \"t\".\"x\" AS \"x\",\"t\".\"y\" AS \"y\",\"t\".\"ProperMotion\" AS \"ProperMotion\"\nFROM (SELECT (\"public\".\"table2\".\"ra\"+\"public\".\"table2\".\"ra_error\") AS \"x\" , (\"public\".\"table2\".\"dec\"+\"public\".\"table2\".\"dec_error\") AS \"y\" , \"public\".\"table2\".\"pmra\" AS \"ProperMotion\"\nFROM \"public\".\"table2\") AS \"t\"", (new PostgreSQLTranslator()).translate(query));
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("No error expected! (see console for more details)");
 		}
diff --git a/test/adql/parser/TestADQLParser.java b/test/adql/parser/TestADQLParser.java
index 1eedba9af90a217fd3ad8747101a006c5962b266..2fc48e1b421e52766e30db137032da0ab9529ad0 100644
--- a/test/adql/parser/TestADQLParser.java
+++ b/test/adql/parser/TestADQLParser.java
@@ -18,26 +18,28 @@ import adql.query.operand.StringConstant;
 
 public class TestADQLParser {
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{
+	public static void setUpBeforeClass() throws Exception {
 	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{
+	public static void tearDownAfterClass() throws Exception {
 	}
 
 	@Before
-	public void setUp() throws Exception{
+	public void setUp() throws Exception {
 	}
 
 	@After
-	public void tearDown() throws Exception{
+	public void tearDown() throws Exception {
 	}
 
 	@Test
-	public void testColumnReference(){
-		ADQLParser parser = new ADQLParser();
-		try{
+	public void testColumnReference() {
+		ADQLParser parser = parserFactory.createParser();
+		try {
 			// ORDER BY
 			parser.parseQuery("SELECT * FROM cat ORDER BY oid;");
 			parser.parseQuery("SELECT * FROM cat ORDER BY oid ASC;");
@@ -50,75 +52,75 @@ public class TestADQLParser {
 			parser.parseQuery("SELECT * FROM cat GROUP BY cat.oid;");
 			// JOIN ... USING(...)
 			parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(oid);");
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail("These ADQL queries are strictly correct! No error should have occured. (see stdout for more details)");
 		}
 
-		try{
+		try {
 			// ORDER BY
 			parser.parseQuery("SELECT * FROM cat ORDER BY cat.oid;");
 			fail("A qualified column name is forbidden in ORDER BY! This test should have failed.");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertEquals(ParseException.class, e.getClass());
 			assertEquals(" Encountered \".\". Was expecting one of: <EOF> \",\" \";\" \"ASC\" \"DESC\" ", e.getMessage());
 		}
 
 		// Query reported as in error before the bug correction:
-		try{
+		try {
 			parser.parseQuery("SELECT TOP 10 browndwarfs.cat.jmag FROM browndwarfs.cat ORDER BY browndwarfs.cat.jmag");
 			fail("A qualified column name is forbidden in ORDER BY! This test should have failed.");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertEquals(ParseException.class, e.getClass());
 			assertEquals(" Encountered \".\". Was expecting one of: <EOF> \",\" \";\" \"ASC\" \"DESC\" ", e.getMessage());
 		}
 
-		try{
+		try {
 			// GROUP BY with a SELECT item index
 			parser.parseQuery("SELECT * FROM cat GROUP BY 1;");
 			fail("A SELECT item index is forbidden in GROUP BY! This test should have failed.");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertEquals(ParseException.class, e.getClass());
 			assertEquals(" Encountered \"1\". Was expecting one of: \"\\\"\" <REGULAR_IDENTIFIER_CANDIDATE> ", e.getMessage());
 		}
 
-		try{
+		try {
 			// JOIN ... USING(...)
 			parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(cat.oid);");
 			fail("A qualified column name is forbidden in USING(...)! This test should have failed.");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertEquals(ParseException.class, e.getClass());
 			assertEquals(" Encountered \".\". Was expecting one of: \")\" \",\" ", e.getMessage());
 		}
 
-		try{
+		try {
 			// JOIN ... USING(...)
 			parser.parseQuery("SELECT * FROM cat JOIN cat2 USING(1);");
 			fail("A column index is forbidden in USING(...)! This test should have failed.");
-		}catch(Exception e){
+		} catch(Exception e) {
 			assertEquals(ParseException.class, e.getClass());
 			assertEquals(" Encountered \"1\". Was expecting one of: \"\\\"\" <REGULAR_IDENTIFIER_CANDIDATE> ", e.getMessage());
 		}
 	}
 
 	@Test
-	public void testDelimitedIdentifiersWithDot(){
-		ADQLParser parser = new ADQLParser();
-		try{
+	public void testDelimitedIdentifiersWithDot() {
+		ADQLParser parser = parserFactory.createParser();
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT * FROM \"B/avo.rad/catalog\";");
 			assertEquals("B/avo.rad/catalog", query.getFrom().getTables().get(0).getTableName());
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail("The ADQL query is strictly correct! No error should have occured. (see stdout for more details)");
 		}
 	}
 
 	@Test
-	public void testJoinTree(){
-		ADQLParser parser = new ADQLParser();
-		try{
+	public void testJoinTree() {
+		ADQLParser parser = parserFactory.createParser();
+		try {
 			String[] queries = new String[]{ "SELECT * FROM aTable A JOIN aSecondTable B ON A.id = B.id JOIN aThirdTable C ON B.id = C.id;", "SELECT * FROM aTable A NATURAL JOIN aSecondTable B NATURAL JOIN aThirdTable C;" };
-			for(String q : queries){
+			for(String q : queries) {
 				ADQLQuery query = parser.parseQuery(q);
 
 				assertTrue(query.getFrom() instanceof ADQLJoin);
@@ -134,69 +136,69 @@ public class TestADQLParser {
 				assertTrue(join.getRightTable() instanceof ADQLTable);
 				assertEquals("aSecondTable", ((ADQLTable)join.getRightTable()).getTableName());
 			}
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail("The ADQL query is strictly correct! No error should have occured. (see stdout for more details)");
 		}
 	}
 
 	@Test
-	public void test(){
-		ADQLParser parser = new ADQLParser();
-		try{
+	public void test() {
+		ADQLParser parser = parserFactory.createParser();
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT 'truc''machin'  	'bidule' --- why not a comment now ^^\n'FIN' FROM foo;");
 			assertNotNull(query);
 			assertEquals("truc'machinbiduleFIN", ((StringConstant)(query.getSelect().get(0).getOperand())).getValue());
 			assertEquals("'truc''machinbiduleFIN'", query.getSelect().get(0).getOperand().toADQL());
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			fail("String litteral concatenation is perfectly legal according to the ADQL standard.");
 		}
 
 		// With a comment ending the query
-		try{
+		try {
 			ADQLQuery query = parser.parseQuery("SELECT TOP 1 * FROM ivoa.ObsCore -- comment");
 			assertNotNull(query);
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace();
 			fail("String litteral concatenation is perfectly legal according to the ADQL standard.");
 		}
 	}
 
 	@Test
-	public void testIncorrectCharacter(){
+	public void testIncorrectCharacter() {
 		/* An identifier must be written only with digits, an underscore or
 		 * regular latin characters: */
-		try{
-			(new ADQLParser()).parseQuery("select gr\u00e9gory FROM aTable");
-		}catch(Throwable t){
+		try {
+			(parserFactory.createParser()).parseQuery("select gr\u00e9gory FROM aTable");
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
 			assertTrue(t.getMessage().startsWith("Incorrect character encountered at l.1, c.10: "));
 			assertTrue(t.getMessage().endsWith("Possible cause: a non-ASCI/UTF-8 character (solution: remove/replace it)."));
 		}
 
 		/* Un-finished double/single quoted string: */
-		try{
-			(new ADQLParser()).parseQuery("select \"stuff FROM aTable");
-		}catch(Throwable t){
+		try {
+			(parserFactory.createParser()).parseQuery("select \"stuff FROM aTable");
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
 			assertTrue(t.getMessage().startsWith("Incorrect character encountered at l.1, c.26: <EOF>"));
 			assertTrue(t.getMessage().endsWith("Possible cause: a string between single or double quotes which is never closed (solution: well...just close it!)."));
 		}
 
 		// But in a string, delimited identifier or a comment, it is fine:
-		try{
-			(new ADQLParser()).parseQuery("select 'gr\u00e9gory' FROM aTable");
-			(new ADQLParser()).parseQuery("select \"gr\u00e9gory\" FROM aTable");
-			(new ADQLParser()).parseQuery("select * FROM aTable -- a comment by Gr\u00e9gory");
-		}catch(Throwable t){
+		try {
+			(parserFactory.createParser()).parseQuery("select 'gr\u00e9gory' FROM aTable");
+			(parserFactory.createParser()).parseQuery("select \"gr\u00e9gory\" FROM aTable");
+			(parserFactory.createParser()).parseQuery("select * FROM aTable -- a comment by Gr\u00e9gory");
+		} catch(Throwable t) {
 			fail("This error should never occurs because all these queries have an accentuated character but at a correct place.");
 		}
 	}
 
 	@Test
-	public void testMultipleSpacesInOrderAndGroupBy(){
-		try{
-			ADQLParser parser = new ADQLParser();
+	public void testMultipleSpacesInOrderAndGroupBy() {
+		try {
+			ADQLParser parser = parserFactory.createParser();
 
 			// Single space:
 			parser.parseQuery("select * from aTable ORDER BY aCol");
@@ -214,130 +216,130 @@ public class TestADQLParser {
 			parser.parseQuery("select * from aTable GROUP\tBY aCol");
 			parser.parseQuery("select * from aTable GROUP\nBY aCol");
 			parser.parseQuery("select * from aTable GROUP \t\nBY aCol");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			t.printStackTrace();
 			fail("Having multiple space characters between the ORDER/GROUP and the BY keywords should not generate any parsing error.");
 		}
 	}
 
 	@Test
-	public void testADQLReservedWord(){
-		ADQLParser parser = new ADQLParser();
+	public void testADQLReservedWord() {
+		ADQLParser parser = parserFactory.createParser();
 
-		final String hintAbs = "\n(HINT: \"abs\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)";
-		final String hintPoint = "\n(HINT: \"point\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)";
-		final String hintExists = "\n(HINT: \"exists\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)";
-		final String hintLike = "\n(HINT: \"LIKE\" is a reserved ADQL word. To use it as a column/table/schema name/alias, write it between double quotes.)";
+		final String hintAbs = ".*\n\\(HINT: \"abs\" is a reserved ADQL word in v[0-9]+\\.[0-9]+\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)";
+		final String hintPoint = ".*\n\\(HINT: \"point\" is a reserved ADQL word in v[0-9]+\\.[0-9]+\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)";
+		final String hintExists = ".*\n\\(HINT: \"exists\" is a reserved ADQL word in v[0-9]+\\.[0-9]+\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)";
+		final String hintLike = ".*\n\\(HINT: \"LIKE\" is a reserved ADQL word in v[0-9]+\\.[0-9]+\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)";
 
 		/* TEST AS A COLUMN/TABLE/SCHEMA NAME... */
 		// ...with a numeric function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select abs from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintAbs));
+			assertTrue(t.getMessage().matches(hintAbs));
 		}
 		// ...with a geometric function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select point from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintPoint));
+			assertTrue(t.getMessage().matches(hintPoint));
 		}
 		// ...with an ADQL function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select exists from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintExists));
+			assertTrue(t.getMessage().matches(hintExists));
 		}
 		// ...with an ADQL syntax item:
-		try{
+		try {
 			parser.parseQuery("select LIKE from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintLike));
+			assertTrue(t.getMessage().matches(hintLike));
 		}
 
 		/* TEST AS AN ALIAS... */
 		// ...with a numeric function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select aCol AS abs from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintAbs));
+			assertTrue(t.getMessage().matches(hintAbs));
 		}
 		// ...with a geometric function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select aCol AS point from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintPoint));
+			assertTrue(t.getMessage().matches(hintPoint));
 		}
 		// ...with an ADQL function name (but no param):
-		try{
+		try {
 			parser.parseQuery("select aCol AS exists from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintExists));
+			assertTrue(t.getMessage().matches(hintExists));
 		}
 		// ...with an ADQL syntax item:
-		try{
+		try {
 			parser.parseQuery("select aCol AS LIKE from aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintLike));
+			assertTrue(t.getMessage().matches(hintLike));
 		}
 
 		/* TEST AT THE END OF THE QUERY (AND IN A WHERE) */
-		try{
+		try {
 			parser.parseQuery("select aCol from aTable WHERE toto = abs");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith(hintAbs));
+			assertTrue(t.getMessage().matches(hintAbs));
 		}
 	}
 
 	@Test
-	public void testSQLReservedWord(){
-		ADQLParser parser = new ADQLParser();
+	public void testSQLReservedWord() {
+		ADQLParser parser = parserFactory.createParser();
 
-		try{
+		try {
 			parser.parseQuery("SELECT rows FROM aTable");
 			fail("\"ROWS\" is an SQL reserved word. This query should not pass.");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith("\n(HINT: \"rows\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)"));
+			assertTrue(t.getMessage().matches(".*\n\\(HINT: \"rows\" is not supported in ADQL v[0-9]+\\.[0-9]+, but is however a reserved word\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)"));
 		}
 
-		try{
+		try {
 			parser.parseQuery("SELECT CASE WHEN aCol = 2 THEN 'two' ELSE 'smth else' END as str FROM aTable");
 			fail("ADQL does not support the CASE syntax. This query should not pass.");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			assertEquals(ParseException.class, t.getClass());
-			assertTrue(t.getMessage().endsWith("\n(HINT: \"CASE\" is not supported in ADQL, but is however a reserved word. To use it as a column/table/schema name/alias, write it between double quotes.)"));
+			assertTrue(t.getMessage().matches(".*\n\\(HINT: \"CASE\" is not supported in ADQL v[0-9]+\\.[0-9]+, but is however a reserved word\\. To use it as a column/table/schema name/alias, write it between double quotes\\.\\)"));
 		}
 	}
 
 	@Test
-	public void testUDFName(){
-		ADQLParser parser = new ADQLParser();
+	public void testUDFName() {
+		ADQLParser parser = parserFactory.createParser();
 
 		// CASE: Valid UDF name => OK
-		try{
+		try {
 			parser.parseQuery("SELECT foo(p1,p2) FROM aTable");
-		}catch(Throwable t){
+		} catch(Throwable t) {
 			t.printStackTrace();
 			fail("Unexpected parsing error! This query should have passed. (see console for more details)");
 		}
 
 		// CASE: Invalid UDF name => ParseException
 		final String[] functionsToTest = new String[]{ "_foo", "2do", "do!" };
-		for(String fct : functionsToTest){
-			try{
+		for(String fct : functionsToTest) {
+			try {
 				parser.parseQuery("SELECT " + fct + "(p1,p2) FROM aTable");
 				fail("A UDF name like \"" + fct + "\" is not allowed by the ADQL grammar. This query should not pass.");
-			}catch(Throwable t){
+			} catch(Throwable t) {
 				assertEquals(ParseException.class, t.getClass());
 				assertEquals("Invalid (User Defined) Function name: \"" + fct + "\"!", t.getMessage());
 			}
@@ -345,10 +347,10 @@ public class TestADQLParser {
 	}
 
 	@Test
-	public void testTryQuickFix(){
-		ADQLParser parser = new ADQLParser();
+	public void testTryQuickFix() {
+		ADQLParser parser = parserFactory.createParser();
 
-		try{
+		try {
 			/* CASE: Nothing to fix => exactly the same as provided */
 			// raw ASCII query with perfectly regular ADQL identifiers:
 			assertEquals("SELECT foo, bar FROM aTable", parser.tryQuickFix("SELECT foo, bar FROM aTable"));
@@ -376,8 +378,8 @@ public class TestADQLParser {
 			/* CASE: a nice combination of everything (with comments at beginning, middle and end) */
 			assertEquals("-- begin comment" + System.getProperty("line.separator") + "SELECT id, \"_raj2000\", \"distance\", (\"date\")," + System.getProperty("line.separator") + "    \"min\",min(mag), \"_dej2000\" -- in-between commment" + System.getProperty("line.separator") + "FROM \"public\".mytable -- end comment", parser.tryQuickFix("-- begin comment\r\nSELECT id, \uFE4Draj2000, distance, (date),\r\tmin,min(mag), \"_dej2000\" -- in-between commment\nFROM public.mytable -- end comment"));
 
-		}catch(Throwable t){
-			t.printStackTrace();
+		} catch(ParseException pe) {
+			pe.printStackTrace();
 			fail("Unexpected parsing error! This query should have passed. (see console for more details)");
 		}
 	}
diff --git a/test/adql/parser/TestIdentifierItem.java b/test/adql/parser/TestIdentifierItem.java
index b2ada44967d03e91e4f8e0ca8391f1387e98e8ab..46e0bf9c216269bf23eb5a04f8436f3cd0bf3745 100644
--- a/test/adql/parser/TestIdentifierItem.java
+++ b/test/adql/parser/TestIdentifierItem.java
@@ -1,7 +1,7 @@
 package adql.parser;
 
-import static adql.parser.ADQLParserConstants.DELIMITED_IDENTIFIER;
-import static adql.parser.ADQLParserConstants.REGULAR_IDENTIFIER_CANDIDATE;
+import static adql.parser.ADQLParser201Constants.DELIMITED_IDENTIFIER;
+import static adql.parser.ADQLParser201Constants.REGULAR_IDENTIFIER_CANDIDATE;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Before;
diff --git a/test/adql/parser/TestUnknownTypes.java b/test/adql/parser/TestUnknownTypes.java
index 2116da0a745ce66d44af4f683693c9f258f6e069..c29f2565b2e50ede106d1029f70772ba682824f1 100644
--- a/test/adql/parser/TestUnknownTypes.java
+++ b/test/adql/parser/TestUnknownTypes.java
@@ -28,55 +28,60 @@ import adql.query.ADQLQuery;
 
 public class TestUnknownTypes {
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{}
+	public static void setUpBeforeClass() throws Exception {
+	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{
+	public static void tearDownAfterClass() throws Exception {
 		DBType.DBDatatype.UNKNOWN.setCustomType(null);
 	}
 
 	@Before
-	public void setUp() throws Exception{}
+	public void setUp() throws Exception {
+	}
 
 	@After
-	public void tearDown() throws Exception{}
+	public void tearDown() throws Exception {
+	}
 
-	public void testForFctDef(){
+	public void testForFctDef() {
 		// Test with the return type:
-		try{
+		try {
 			FunctionDef fct = FunctionDef.parse("foo()->aType");
 			assertTrue(fct.isUnknown());
 			assertFalse(fct.isString());
 			assertFalse(fct.isNumeric());
 			assertFalse(fct.isGeometry());
 			assertEquals("?aType?", fct.returnType.type.toString());
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("Unknown types MUST be allowed!");
 		}
 
 		// Test with a parameter type:
-		try{
+		try {
 			FunctionDef fct = FunctionDef.parse("foo(param1 aType)");
 			assertTrue(fct.getParam(0).type.isUnknown());
 			assertFalse(fct.getParam(0).type.isString());
 			assertFalse(fct.getParam(0).type.isNumeric());
 			assertFalse(fct.getParam(0).type.isGeometry());
 			assertEquals("?aType?", fct.getParam(0).type.toString());
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("Unknown types MUST be allowed!");
 		}
 	}
 
 	@Test
-	public void testForColumns(){
+	public void testForColumns() {
 		final String QUERY_TXT = "SELECT FOO(C1), FOO(C2), FOO(C4), C1, C2, C3, C4 FROM T1";
 
-		try{
+		try {
 			// Create the parser:
-			ADQLParser parser = new ADQLParser();
+			ADQLParser parser = parserFactory.createParser();
 
 			// Create table/column metadata:
 			DefaultDBTable table1 = new DefaultDBTable("T1");
@@ -84,7 +89,7 @@ public class TestUnknownTypes {
 			table1.addColumn(new DefaultDBColumn("C2", new DBType(DBDatatype.UNKNOWN), table1));
 			table1.addColumn(new DefaultDBColumn("C3", new DBType(DBDatatype.VARCHAR), table1));
 			table1.addColumn(new DefaultDBColumn("C4", new DBType(DBDatatype.UNKNOWN_NUMERIC), table1));
-			Collection<DBTable> tList = Arrays.asList(new DBTable[]{table1});
+			Collection<DBTable> tList = Arrays.asList(new DBTable[]{ table1 });
 
 			// Check the type of the column T1.C1:
 			DBColumn col = table1.getColumn("C1", true);
@@ -113,7 +118,7 @@ public class TestUnknownTypes {
 
 			// Define a UDF, and allow all geometrical functions and coordinate systems:
 			FunctionDef udf1 = FunctionDef.parse("FOO(x INTEGER) -> INTEGER");
-			Collection<FunctionDef> udfList = Arrays.asList(new FunctionDef[]{udf1});
+			Collection<FunctionDef> udfList = Arrays.asList(new FunctionDef[]{ udf1 });
 			Collection<String> geoList = null;
 			Collection<String> csList = null;
 
@@ -155,7 +160,7 @@ public class TestUnknownTypes {
 			assertTrue(pq.getSelect().get(6).getOperand().isNumeric());
 			assertFalse(pq.getSelect().get(6).getOperand().isString());
 			assertFalse(pq.getSelect().get(6).getOperand().isGeometry());
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("The construction, configuration and usage of the parser are correct. Nothing should have failed here. (see console for more details)");
 		}
diff --git a/test/adql/query/TestADQLObjectPosition.java b/test/adql/query/TestADQLObjectPosition.java
index a03b24c398a26e6f45760298357d9fb6a44a2d1e..8ec064d3bcf53686d2bdec0c6eaea0d372761f7b 100644
--- a/test/adql/query/TestADQLObjectPosition.java
+++ b/test/adql/query/TestADQLObjectPosition.java
@@ -9,7 +9,7 @@ import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
 
-import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.query.constraint.Comparison;
 import adql.query.from.ADQLJoin;
@@ -21,37 +21,37 @@ import adql.search.SimpleSearchHandler;
 
 public class TestADQLObjectPosition {
 
-	private ADQLParser parser = new ADQLParser();
+	private ADQLParserFactory parserFactory = new ADQLParserFactory();
 
 	@Before
-	public void setUp(){
+	public void setUp() {
 
 	}
 
 	@Test
-	public void testPositionInAllClauses(){
-		try{
-			ADQLQuery query = parser.parseQuery("SELECT truc, bidule.machin, toto(truc, chose) AS \"super\" FROM foo JOIN bidule USING(id) WHERE truc > 12.5 AND bidule.machin < 5 GROUP BY chose HAVING try > 0 ORDER BY chouetteAlors");
+	public void testPositionInAllClauses() {
+		try {
+			ADQLQuery query = parserFactory.createParser().parseQuery("SELECT truc, bidule.machin, toto(truc, chose) AS \"super\" FROM foo JOIN bidule USING(id) WHERE truc > 12.5 AND bidule.machin < 5 GROUP BY chose HAVING try > 0 ORDER BY chouetteAlors");
 
-			Iterator<ADQLObject> results = query.search(new SimpleSearchHandler(true){
+			Iterator<ADQLObject> results = query.search(new SimpleSearchHandler(true) {
 				@Override
-				protected boolean match(ADQLObject obj){
+				protected boolean match(ADQLObject obj) {
 					return obj.getPosition() == null;
 				}
 			});
-			if (results.hasNext()){
+			if (results.hasNext()) {
 				System.err.println("OBJECT WITH NO DEFINED POSITION:");
 				while(results.hasNext())
 					System.err.println("    * " + results.next().toADQL());
 				fail("At least one item of the generated ADQL tree does not have a position information! (see System.err for more details)");
 			}
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("No error should have occured here: the ADQL query is syntactically correct!");
 		}
 	}
 
-	private void assertEquality(final TextPosition expected, final TextPosition realPos){
+	private void assertEquality(final TextPosition expected, final TextPosition realPos) {
 		assertEquals(expected.beginLine, realPos.beginLine);
 		assertEquals(expected.beginColumn, realPos.beginColumn);
 		assertEquals(expected.endLine, realPos.endLine);
@@ -59,9 +59,9 @@ public class TestADQLObjectPosition {
 	}
 
 	@Test
-	public void testPositionAccuracy(){
-		try{
-			ADQLQuery query = parser.parseQuery("SELECT TOP 1000 oid FROM foo JOIN bar USING(oid)\nWHERE foo || toto = 'truc'\n      AND 2 > 1+0 GROUP BY oid HAVING COUNT(oid) > 10\n\tORDER BY 1 DESC");
+	public void testPositionAccuracy() {
+		try {
+			ADQLQuery query = parserFactory.createParser().parseQuery("SELECT TOP 1000 oid FROM foo JOIN bar USING(oid)\nWHERE foo || toto = 'truc'\n      AND 2 > 1+0 GROUP BY oid HAVING COUNT(oid) > 10\n\tORDER BY 1 DESC");
 			// Test SELECT
 			assertEquality(new TextPosition(1, 1, 1, 20), query.getSelect().getPosition());
 			// Test ADQLColumn (here: "oid")
@@ -130,7 +130,7 @@ public class TestADQLObjectPosition {
 			// Test column index:
 			assertEquality(new TextPosition(4, 18, 4, 19), query.getOrderBy().get(0).getPosition());
 
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			System.err.println("ERROR IN THE ADQL QUERY AT " + pe.getPosition());
 			pe.printStackTrace();
 			fail("No error should have occured here: the ADQL query is syntactically correct!");
diff --git a/test/adql/search/TestSimpleReplaceHandler.java b/test/adql/search/TestSimpleReplaceHandler.java
index 785fddf2722de279eb315b0a2e65dcdaa7bc1b20..8495676d0a3fe9e2c0a9e950cb9a53fa636c4894 100644
--- a/test/adql/search/TestSimpleReplaceHandler.java
+++ b/test/adql/search/TestSimpleReplaceHandler.java
@@ -6,7 +6,7 @@ import static org.junit.Assert.fail;
 import org.junit.Before;
 import org.junit.Test;
 
-import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.query.ADQLObject;
 import adql.query.ADQLQuery;
 import adql.query.operand.function.DefaultUDF;
@@ -15,16 +15,19 @@ import adql.query.operand.function.MathFunctionType;
 
 public class TestSimpleReplaceHandler {
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	@Before
-	public void setUp() throws Exception{}
+	public void setUp() throws Exception {
+	}
 
 	@Test
-	public void testReplaceRecursiveMatch(){
+	public void testReplaceRecursiveMatch() {
 		/* WHY THIS TEST?
-		 * 
+		 *
 		 * When a match item had also a match item inside it (e.g. function parameter or sub-query),
 		 * both matched items (e.g. the parent and the child) must be replaced.
-		 * 
+		 *
 		 * However, if the parent is replaced first, the reference of the new parent is lost by the SimpleReplaceHandler and so,
 		 * the replacement of the child will be performed on the former parent. Thus, after the whole process,
 		 * in the final ADQL query, the replacement of the child won't be visible since the former parent is
@@ -32,22 +35,22 @@ public class TestSimpleReplaceHandler {
 		 */
 
 		String testQuery = "SELECT SQRT(ABS(81)) FROM myTable";
-		try{
+		try {
 			// Parse the query:
-			ADQLQuery query = (new ADQLParser()).parseQuery(testQuery);
+			ADQLQuery query = parserFactory.createParser().parseQuery(testQuery);
 
 			// Check it is as expected, before the replacements:
 			assertEquals(testQuery, query.toADQL().replaceAll("\\n", " "));
 
 			// Create a replace handler:
-			SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler(){
+			SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler() {
 				@Override
-				protected boolean match(ADQLObject obj){
+				protected boolean match(ADQLObject obj) {
 					return obj instanceof MathFunction;
 				}
 
 				@Override
-				protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{
+				protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException {
 					return new DefaultUDF("foo", ((MathFunction)objToReplace).getParameters());
 				}
 			};
@@ -58,7 +61,7 @@ public class TestSimpleReplaceHandler {
 			assertEquals(replaceHandler.getNbMatch(), replaceHandler.getNbReplacement());
 			assertEquals("SELECT foo(foo(81)) FROM myTable", query.toADQL().replaceAll("\\n", " "));
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details.");
 		}
@@ -66,39 +69,39 @@ public class TestSimpleReplaceHandler {
 	}
 
 	@Test
-	public void testWrappingReplacement(){
+	public void testWrappingReplacement() {
 		/* WHY THIS TEST?
-		 * 
+		 *
 		 * In case you just want to wrap a matched object, you replace it by the wrapping object initialized
 		 * with the matched object.
-		 * 
+		 *
 		 * In a first version, the replacement was done and then the ReplaceHandler was going inside the new object to replace
 		 * other matching objects. But of course, it will find again the first matched object and will wrap it again, and so on
 		 * indefinitely => "nasty" infinite loop.
-		 * 
+		 *
 		 * So, the replacement of the matched objects should be always done after having looked inside it.
 		 */
 
 		String testQuery = "SELECT foo(bar(123)) FROM myTable";
-		try{
+		try {
 			// Parse the query:
-			ADQLQuery query = (new ADQLParser()).parseQuery(testQuery);
+			ADQLQuery query = parserFactory.createParser().parseQuery(testQuery);
 
 			// Check it is as expected, before the replacements:
 			assertEquals(testQuery, query.toADQL().replaceAll("\\n", " "));
 
 			// Create a replace handler:
-			SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler(){
+			SimpleReplaceHandler replaceHandler = new SimpleReplaceHandler() {
 				@Override
-				protected boolean match(ADQLObject obj){
+				protected boolean match(ADQLObject obj) {
 					return obj instanceof DefaultUDF && ((DefaultUDF)obj).getName().toLowerCase().matches("(foo|bar)");
 				}
 
 				@Override
-				protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException{
-					try{
+				protected ADQLObject getReplacer(ADQLObject objToReplace) throws UnsupportedOperationException {
+					try {
 						return new MathFunction(MathFunctionType.ROUND, (DefaultUDF)objToReplace);
-					}catch(Exception e){
+					} catch(Exception e) {
 						e.printStackTrace(System.err);
 						fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details.");
 						return null;
@@ -112,7 +115,7 @@ public class TestSimpleReplaceHandler {
 			assertEquals(replaceHandler.getNbMatch(), replaceHandler.getNbReplacement());
 			assertEquals("SELECT ROUND(foo(ROUND(bar(123)))) FROM myTable", query.toADQL().replaceAll("\\n", " "));
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("No error should have occured here since nothing is wrong in the ADQL query used for the test. See the stack trace in the console for more details.");
 		}
diff --git a/test/adql/translator/TestMySQLTranslator.java b/test/adql/translator/TestMySQLTranslator.java
index 97dd5e839bf4ab3d2aac279055f8d16ab068a36a..9c1327a90b8a70d79c042cc4c33e6bec758d08d7 100644
--- a/test/adql/translator/TestMySQLTranslator.java
+++ b/test/adql/translator/TestMySQLTranslator.java
@@ -6,28 +6,30 @@ import static org.junit.Assert.fail;
 import org.junit.Test;
 
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.query.ADQLQuery;
 
 public class TestMySQLTranslator {
 
 	@Test
-	public void testConcat(){
-		try{
+	public void testConcat() {
+		try {
+			ADQLParser parser = ADQLParserFactory.createDefaultParser();
 			MySQLTranslator translator = new MySQLTranslator();
 
 			// Test with an easy translation:
-			ADQLQuery query = (new ADQLParser()).parseQuery("SELECT 'abc' || ' ' || 'def' FROM aTable");
+			ADQLQuery query = parser.parseQuery("SELECT 'abc' || ' ' || 'def' FROM aTable");
 			assertEquals("SELECT CONCAT('abc', ' ', 'def') AS `concat`", translator.translate(query.getSelect()));
 
 			// Test with an easy translation:
-			query = (new ADQLParser()).parseQuery("SELECT 'a||b||c' || ' ' || 'd+e|f' FROM aTable");
+			query = parser.parseQuery("SELECT 'a||b||c' || ' ' || 'd+e|f' FROM aTable");
 			assertEquals("SELECT CONCAT('a||b||c', ' ', 'd+e|f') AS `concat`", translator.translate(query.getSelect()));
 
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
-		}catch(TranslationException te){
+		} catch(TranslationException te) {
 			te.printStackTrace();
 			fail("No error was expected from this translation. (see the console for more details)");
 		}
diff --git a/test/adql/translator/TestSQLServerTranslator.java b/test/adql/translator/TestSQLServerTranslator.java
index 40e5caf1cc30cae052e25b046c639be09156466e..f7001429bf5a0c3bbbad1ff4f865f587a196e40d 100644
--- a/test/adql/translator/TestSQLServerTranslator.java
+++ b/test/adql/translator/TestSQLServerTranslator.java
@@ -14,16 +14,19 @@ import adql.db.DBTable;
 import adql.db.DefaultDBColumn;
 import adql.db.DefaultDBTable;
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.parser.SQLServer_ADQLQueryFactory;
 import adql.query.ADQLQuery;
 
 public class TestSQLServerTranslator {
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	private List<DBTable> tables = null;
 
 	@Before
-	public void setUp() throws Exception{
+	public void setUp() throws Exception {
 		tables = new ArrayList<DBTable>(2);
 		DefaultDBTable t = new DefaultDBTable("aTable");
 		t.addColumn(new DefaultDBColumn("id", t));
@@ -38,11 +41,14 @@ public class TestSQLServerTranslator {
 	}
 
 	@Test
-	public void testNaturalJoin(){
+	public void testNaturalJoin() {
 		final String adqlquery = "SELECT id, name, aColumn, anotherColumn FROM aTable A NATURAL JOIN anotherTable B;";
 
-		try{
-			ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery);
+		try {
+			ADQLParser parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables));
+			parser.setQueryFactory(new SQLServer_ADQLQueryFactory());
+			ADQLQuery query = parser.parseQuery(adqlquery);
 			SQLServerTranslator translator = new SQLServerTranslator();
 
 			// Test the FROM part:
@@ -51,21 +57,24 @@ public class TestSQLServerTranslator {
 			// Test the SELECT part (in order to ensure the usual common columns (due to NATURAL) are actually translated as columns of the first joined table):
 			assertEquals("SELECT \"a\".\"id\" AS \"id\" , \"a\".\"name\" AS \"name\" , \"a\".\"aColumn\" AS \"aColumn\" , \"b\".\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect()));
 
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
-		}catch(TranslationException te){
+		} catch(TranslationException te) {
 			te.printStackTrace();
 			fail("No error was expected from this translation. (see the console for more details)");
 		}
 	}
 
 	@Test
-	public void testJoinWithUSING(){
+	public void testJoinWithUSING() {
 		final String adqlquery = "SELECT B.id, name, aColumn, anotherColumn FROM aTable A JOIN anotherTable B USING(name);";
 
-		try{
-			ADQLQuery query = (new ADQLParser(new DBChecker(tables), new SQLServer_ADQLQueryFactory())).parseQuery(adqlquery);
+		try {
+			ADQLParser parser = parserFactory.createParser();
+			parser.setQueryChecker(new DBChecker(tables));
+			parser.setQueryFactory(new SQLServer_ADQLQueryFactory());
+			ADQLQuery query = parser.parseQuery(adqlquery);
 			SQLServerTranslator translator = new SQLServerTranslator();
 
 			// Test the FROM part:
@@ -74,32 +83,35 @@ public class TestSQLServerTranslator {
 			// Test the SELECT part (in order to ensure the usual common columns (due to USING) are actually translated as columns of the first joined table):
 			assertEquals("SELECT \"b\".\"id\" AS \"id\" , \"a\".\"name\" AS \"name\" , \"a\".\"aColumn\" AS \"aColumn\" , \"b\".\"anotherColumn\" AS \"anotherColumn\"", translator.translate(query.getSelect()));
 
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
-		}catch(TranslationException te){
+		} catch(TranslationException te) {
 			te.printStackTrace();
 			fail("No error was expected from this translation. (see the console for more details)");
 		}
 	}
 
 	@Test
-	public void testConcat(){
-		try{
+	public void testConcat() {
+		try {
 			SQLServerTranslator translator = new SQLServerTranslator();
 
+			ADQLParser parser = parserFactory.createParser();
+			parser.setQueryFactory(new SQLServer_ADQLQueryFactory());
+
 			// Test with an easy translation:
-			ADQLQuery query = (new ADQLParser(new SQLServer_ADQLQueryFactory())).parseQuery("SELECT 'abc' || ' ' || 'def' FROM aTable");
+			ADQLQuery query = parser.parseQuery("SELECT 'abc' || ' ' || 'def' FROM aTable");
 			assertEquals("SELECT 'abc' + ' ' + 'def' AS \"concat\"", translator.translate(query.getSelect()));
 
 			// Test with an easy translation:
-			query = (new ADQLParser(new SQLServer_ADQLQueryFactory())).parseQuery("SELECT 'a||b||c' || ' ' || 'd+e|f' FROM aTable");
+			query = parser.parseQuery("SELECT 'a||b||c' || ' ' || 'd+e|f' FROM aTable");
 			assertEquals("SELECT 'a||b||c' + ' ' + 'd+e|f' AS \"concat\"", translator.translate(query.getSelect()));
 
-		}catch(ParseException pe){
+		} catch(ParseException pe) {
 			pe.printStackTrace();
 			fail("The given ADQL query is completely correct. No error should have occurred while parsing it. (see the console for more details)");
-		}catch(TranslationException te){
+		} catch(TranslationException te) {
 			te.printStackTrace();
 			fail("No error was expected from this translation. (see the console for more details)");
 		}
diff --git a/test/tap/data/TestResultSetTableIterator.java b/test/tap/data/TestResultSetTableIterator.java
index 81c8a5e3648037686d07e68eb2c4007900044cb9..e2bbeda9606518b174555f8e758a1f882027cf03 100644
--- a/test/tap/data/TestResultSetTableIterator.java
+++ b/test/tap/data/TestResultSetTableIterator.java
@@ -13,7 +13,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import adql.db.DBType;
-import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.query.ADQLQuery;
 import adql.translator.AstroH2Translator;
 import tap.db_testtools.DBTools;
@@ -23,33 +23,35 @@ public class TestResultSetTableIterator {
 
 	private static Connection conn;
 
+	ADQLParserFactory parserFactory = new ADQLParserFactory();
+
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{
+	public static void setUpBeforeClass() throws Exception {
 		DBTools.createTestDB();
 		conn = DBTools.createConnection("h2", null, null, DBTools.DB_TEST_PATH, DBTools.DB_TEST_USER, DBTools.DB_TEST_PWD);
 	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{
+	public static void tearDownAfterClass() throws Exception {
 		DBTools.closeConnection(conn);
 		DBTools.dropTestDB();
 	}
 
 	@Test
-	public void testWithRSNULL(){
-		try{
+	public void testWithRSNULL() {
+		try {
 			new ResultSetTableIterator(null);
 			fail("The constructor should have failed, because: the given ResultSet is NULL.");
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			assertEquals("java.lang.NullPointerException", ex.getClass().getName());
 			assertEquals("Missing ResultSet object over which to iterate!", ex.getMessage());
 		}
 	}
 
 	@Test
-	public void testWithData(){
+	public void testWithData() {
 		TableIterator it = null;
-		try{
+		try {
 			ResultSet rs = DBTools.select(conn, "SELECT hip, ra, dec, vmag FROM hipparcos LIMIT 10;");
 
 			it = new ResultSetTableIterator(rs);
@@ -57,12 +59,12 @@ public class TestResultSetTableIterator {
 			assertTrue(it.getMetadata() != null);
 			final int expectedNbLines = 10, expectedNbColumns = 4;
 			int countLines = 0, countColumns = 0;
-			while(it.nextRow()){
+			while(it.nextRow()) {
 				// count lines:
 				countLines++;
 				// reset columns count:
 				countColumns = 0;
-				while(it.hasNextCol()){
+				while(it.hasNextCol()) {
 					it.nextCol();
 					// count columns
 					countColumns++;
@@ -75,22 +77,23 @@ public class TestResultSetTableIterator {
 			// TEST that all lines have been read:
 			assertEquals(expectedNbLines, countLines);
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("An exception occurs while reading a correct ResultSet (containing some valid rows).");
-		}finally{
-			if (it != null){
-				try{
+		} finally {
+			if (it != null) {
+				try {
 					it.close();
-				}catch(DataReadException dre){}
+				} catch(DataReadException dre) {
+				}
 			}
 		}
 	}
 
 	@Test
-	public void testWithEmptySet(){
+	public void testWithEmptySet() {
 		TableIterator it = null;
-		try{
+		try {
 			ResultSet rs = DBTools.select(conn, "SELECT * FROM hipparcos WHERE hip = 1056;");
 
 			it = new ResultSetTableIterator(rs);
@@ -103,21 +106,22 @@ public class TestResultSetTableIterator {
 			// TEST that no line has been read:
 			assertEquals(countLines, 0);
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("An exception occurs while reading a correct ResultSet (containing some valid rows).");
-		}finally{
-			if (it != null){
-				try{
+		} finally {
+			if (it != null) {
+				try {
 					it.close();
-				}catch(DataReadException dre){}
+				} catch(DataReadException dre) {
+				}
 			}
 		}
 	}
 
 	@Test
-	public void testWithClosedSet(){
-		try{
+	public void testWithClosedSet() {
+		try {
 			// create a valid ResultSet:
 			ResultSet rs = DBTools.select(conn, "SELECT * FROM hipparcos WHERE hip = 1056;");
 
@@ -128,15 +132,15 @@ public class TestResultSetTableIterator {
 			new ResultSetTableIterator(rs);
 
 			fail("The constructor should have failed, because: the given ResultSet is closed.");
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			assertEquals(ex.getClass().getName(), "tap.data.DataReadException");
 		}
 	}
 
 	@Test
-	public void testDateFormat(){
+	public void testDateFormat() {
 		ResultSet rs = null;
-		try{
+		try {
 			// create a valid ResultSet:
 			rs = DBTools.select(conn, "SELECT * FROM hipparcos LIMIT 1;");
 
@@ -161,23 +165,24 @@ public class TestResultSetTableIterator {
 			// Try to format it into a simple time (no date indication):
 			assertEquals("15:13:56", rsit.formatColValue(new java.sql.Time(cal.getTimeInMillis())));
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("An exception occurs while formatting dates/times.");
-		}finally{
-			if (rs != null){
-				try{
+		} finally {
+			if (rs != null) {
+				try {
 					rs.close();
-				}catch(Exception ex){}
+				} catch(Exception ex) {
+				}
 			}
 		}
 	}
 
 	@Test
-	public void testGeometryColumns(){
+	public void testGeometryColumns() {
 		ResultSet rs = null;
-		try{
-			ADQLQuery query = (new ADQLParser()).parseQuery("SELECT TOP 1 POINT('', ra, dec), CENTROID(CIRCLE('', ra, dec, 2)), BOX('', ra-1, dec-2, ra+1, dec+2), CIRCLE('', ra, dec, 2) FROM hipparcos;");
+		try {
+			ADQLQuery query = (parserFactory.createParser()).parseQuery("SELECT TOP 1 POINT('', ra, dec), CENTROID(CIRCLE('', ra, dec, 2)), BOX('', ra-1, dec-2, ra+1, dec+2), CIRCLE('', ra, dec, 2) FROM hipparcos;");
 
 			// create a valid ResultSet:
 			rs = DBTools.select(conn, (new AstroH2Translator()).translate(query));
@@ -198,23 +203,24 @@ public class TestResultSetTableIterator {
 			for(int i = 2; i < 3; i++)
 				assertEquals(DBType.DBDatatype.REGION, cols[i].getDatatype().type);
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("An exception occurs while checking geometrical functions datatypes.");
-		}finally{
-			if (rs != null){
-				try{
+		} finally {
+			if (rs != null) {
+				try {
 					rs.close();
-				}catch(Exception ex){}
+				} catch(Exception ex) {
+				}
 			}
 		}
 	}
 
 	@Test
-	public void testSQLFunctions(){
+	public void testSQLFunctions() {
 		ResultSet rs = null;
-		try{
-			ADQLQuery query = (new ADQLParser()).parseQuery("SELECT COUNT(*), MIN(vmag), AVG(plx) FROM hipparcos;");
+		try {
+			ADQLQuery query = (parserFactory.createParser()).parseQuery("SELECT COUNT(*), MIN(vmag), AVG(plx) FROM hipparcos;");
 
 			// create a valid ResultSet:
 			rs = DBTools.select(conn, (new AstroH2Translator()).translate(query));
@@ -234,14 +240,15 @@ public class TestResultSetTableIterator {
 			for(int i = 1; i < 3; i++)
 				assertEquals(DBType.DBDatatype.REAL, cols[i].getDatatype().type);
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("An exception occurs while checking SQL functions datatypes");
-		}finally{
-			if (rs != null){
-				try{
+		} finally {
+			if (rs != null) {
+				try {
 					rs.close();
-				}catch(Exception ex){}
+				} catch(Exception ex) {
+				}
 			}
 		}
 	}
diff --git a/test/tap/db/TestJDBCConnection.java b/test/tap/db/TestJDBCConnection.java
index 320d491ec752ee58c30e15cbce90b5ae05475522..b2da3eb5f85598165251ca417d4a8ca1a23dc18d 100644
--- a/test/tap/db/TestJDBCConnection.java
+++ b/test/tap/db/TestJDBCConnection.java
@@ -28,6 +28,7 @@ import adql.db.DBTable;
 import adql.db.DBType;
 import adql.db.DBType.DBDatatype;
 import adql.parser.ADQLParser;
+import adql.parser.ADQLParserFactory;
 import adql.parser.ParseException;
 import adql.query.ADQLQuery;
 import adql.query.IdentifierField;
@@ -60,7 +61,7 @@ public class TestJDBCConnection {
 	private final static String sqliteDbFile = "./test/tap/db_testtools/db-test/sqlite_testDB.db";
 
 	@BeforeClass
-	public static void setUpBeforeClass() throws Exception{
+	public static void setUpBeforeClass() throws Exception {
 
 		uploadExamplePath = "./test/tap/db/upload_example.vot";
 
@@ -75,7 +76,7 @@ public class TestJDBCConnection {
 	}
 
 	@AfterClass
-	public static void tearDownAfterClass() throws Exception{
+	public static void tearDownAfterClass() throws Exception {
 		// Drop the H2 database:
 		DBTools.dropTestDB();
 
@@ -88,10 +89,10 @@ public class TestJDBCConnection {
 	/* ***** */
 
 	@Test
-	public void testGetTAPSchemaTablesDef(){
+	public void testGetTAPSchemaTablesDef() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 			TAPMetadata meta = createCustomSchema();
 			TAPTable customColumns = meta.getTable(STDSchema.TAPSCHEMA.toString(), STDTable.COLUMNS.toString());
 			TAPTable[] tapTables = conn.mergeTAPSchemaDefs(meta);
@@ -110,12 +111,12 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testSetTAPSchema(){
+	public void testSetTAPSchema() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 			short cnt = -1;
-			while(cnt < 1){
+			while(cnt < 1) {
 				/* NO CUSTOM DEFINITION */
 				// Prepare the test:
 				if (cnt == -1)
@@ -123,14 +124,14 @@ public class TestJDBCConnection {
 				else
 					createTAPSchema(conn);
 				// Do the test:
-				try{
+				try {
 					TAPMetadata meta = new TAPMetadata();
 					int[] expectedCounts = getStats(meta);
 					conn.setTAPSchema(meta);
 					int[] effectiveCounts = getStats(conn, meta);
 					for(int i = 0; i < expectedCounts.length; i++)
 						assertEquals(expectedCounts[i], effectiveCounts[i]);
-				}catch(DBException dbe){
+				} catch(DBException dbe) {
 					dbe.printStackTrace(System.err);
 					fail("[" + conn.getID() + ";no def] No error should happen here ; when an empty list of metadata is given, at least the TAP_SCHEMA should be created and filled with a description of itself.");
 				}
@@ -140,14 +141,14 @@ public class TestJDBCConnection {
 				if (cnt == -1)
 					dropSchema(STDSchema.TAPSCHEMA.label, conn);
 				// Do the test:
-				try{
+				try {
 					TAPMetadata meta = createCustomSchema();
 					int[] expectedCounts = getStats(meta);
 					conn.setTAPSchema(meta);
 					int[] effectiveCounts = getStats(conn, meta);
 					for(int i = 0; i < expectedCounts.length; i++)
 						assertEquals(expectedCounts[i], effectiveCounts[i]);
-				}catch(DBException dbe){
+				} catch(DBException dbe) {
 					dbe.printStackTrace(System.err);
 					fail("[" + conn.getID() + ";custom def] No error should happen here!");
 				}
@@ -158,10 +159,10 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testGetCreationOrder(){
+	public void testGetCreationOrder() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 			assertEquals(-1, conn.getCreationOrder(null));
 			assertEquals(0, conn.getCreationOrder(STDTable.SCHEMAS));
 			assertEquals(1, conn.getCreationOrder(STDTable.TABLES));
@@ -172,7 +173,7 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testGetDBMSDatatype(){
+	public void testGetDBMSDatatype() {
 		assertEquals("VARCHAR", h2JDBCConnection.defaultTypeConversion(null));
 		assertEquals("TEXT", sqliteJDBCConnection.defaultTypeConversion(null));
 
@@ -181,16 +182,16 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testMergeTAPSchemaDefs(){
+	public void testMergeTAPSchemaDefs() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 
 			// TEST WITH NO METADATA OBJECT:
 			// -> expected: throws a NULL exception.
-			try{
+			try {
 				conn.mergeTAPSchemaDefs(null);
-			}catch(Exception e){
+			} catch(Exception e) {
 				assertEquals(NullPointerException.class, e.getClass());
 			}
 
@@ -230,10 +231,10 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testEquals(){
+	public void testEquals() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 			// NULL tests:
 			assertFalse(conn.equals("tap_schema", null, false));
 			assertFalse(conn.equals("tap_schema", null, true));
@@ -243,25 +244,25 @@ public class TestJDBCConnection {
 			assertFalse(conn.equals(null, null, true));
 
 			// CASE SENSITIVE tests:
-			if (conn.supportsMixedCaseQuotedIdentifier || conn.mixedCaseQuoted){
+			if (conn.supportsMixedCaseQuotedIdentifier || conn.mixedCaseQuoted) {
 				assertFalse(conn.equals("tap_schema", "TAP_SCHEMA", true));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", true));
 				assertFalse(conn.equals("TAP_SCHEMA", "tap_schema", true));
 				assertFalse(conn.equals("Columns", "columns", true));
 				assertFalse(conn.equals("columns", "Columns", true));
-			}else if (conn.lowerCaseQuoted){
+			} else if (conn.lowerCaseQuoted) {
 				assertTrue(conn.equals("tap_schema", "TAP_SCHEMA", true));
 				assertFalse(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", true));
 				assertFalse(conn.equals("TAP_SCHEMA", "tap_schema", true));
 				assertFalse(conn.equals("Columns", "columns", true));
 				assertTrue(conn.equals("columns", "Columns", true));
-			}else if (conn.upperCaseQuoted){
+			} else if (conn.upperCaseQuoted) {
 				assertFalse(conn.equals("tap_schema", "TAP_SCHEMA", true));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", true));
 				assertTrue(conn.equals("TAP_SCHEMA", "tap_schema", true));
 				assertFalse(conn.equals("Columns", "columns", true));
 				assertFalse(conn.equals("columns", "Columns", true));
-			}else{
+			} else {
 				assertTrue(conn.equals("tap_schema", "TAP_SCHEMA", true));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", true));
 				assertTrue(conn.equals("TAP_SCHEMA", "tap_schema", true));
@@ -270,25 +271,25 @@ public class TestJDBCConnection {
 			}
 
 			// CASE INSENSITIVE tests:
-			if (conn.supportsMixedCaseUnquotedIdentifier){
+			if (conn.supportsMixedCaseUnquotedIdentifier) {
 				assertTrue(conn.equals("tap_schema", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "tap_schema", false));
 				assertTrue(conn.equals("Columns", "columns", false));
 				assertTrue(conn.equals("columns", "Columns", false));
-			}else if (conn.lowerCaseUnquoted){
+			} else if (conn.lowerCaseUnquoted) {
 				assertTrue(conn.equals("tap_schema", "TAP_SCHEMA", false));
 				assertFalse(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", false));
 				assertFalse(conn.equals("TAP_SCHEMA", "tap_schema", false));
 				assertFalse(conn.equals("Columns", "columns", false));
 				assertTrue(conn.equals("columns", "Columns", false));
-			}else if (conn.upperCaseUnquoted){
+			} else if (conn.upperCaseUnquoted) {
 				assertFalse(conn.equals("tap_schema", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "tap_schema", false));
 				assertFalse(conn.equals("Columns", "columns", false));
 				assertFalse(conn.equals("columns", "Columns", false));
-			}else{
+			} else {
 				assertTrue(conn.equals("tap_schema", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "TAP_SCHEMA", false));
 				assertTrue(conn.equals("TAP_SCHEMA", "tap_schema", false));
@@ -299,38 +300,38 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testGetTAPSchema(){
+	public void testGetTAPSchema() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
-			try{
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
+			try {
 				// Prepare the test:
 				createTAPSchema(conn);
 				// Try to get it (which should work without any problem here):
 				conn.getTAPSchema();
-			}catch(DBException de){
+			} catch(DBException de) {
 				de.printStackTrace(System.err);
 				fail("No pbm should happen here (either for the creation of a std TAP_SCHEMA or for its reading)! CAUSE: " + de.getMessage());
 			}
 
-			try{
+			try {
 				// Prepare the test:
 				dropSchema(STDSchema.TAPSCHEMA.label, conn);
 				// Try to get it (which should work without any problem here):
 				conn.getTAPSchema();
 				fail("DBException expected, because none of the TAP_SCHEMA tables exist.");
-			}catch(DBException de){
+			} catch(DBException de) {
 				assertTrue(de.getMessage().equals("Impossible to load schemas from TAP_SCHEMA.schemas!"));
 			}
 		}
 	}
 
 	@Test
-	public void testIsTableExisting(){
+	public void testIsTableExisting() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
-			try{
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
+			try {
 				// Get the database metadata:
 				DatabaseMetaData dbMeta = conn.connection.getMetaData();
 
@@ -353,7 +354,7 @@ public class TestJDBCConnection {
 				assertFalse(conn.isTableExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.COLUMNS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.COLUMNS.label), dbMeta));
 				assertFalse(conn.isTableExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.KEYS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.KEYS.label), dbMeta));
 				assertFalse(conn.isTableExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.KEY_COLUMNS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.KEY_COLUMNS.label), dbMeta));
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				ex.printStackTrace(System.err);
 				fail("{" + conn.getID() + "} Testing the existence of a table should not throw an error!");
 			}
@@ -361,13 +362,13 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testIsColumnExisting(){
+	public void testIsColumnExisting() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
 		int i = -1;
-		for(JDBCConnection conn : connections){
+		for(JDBCConnection conn : connections) {
 			i++;
-			try{
+			try {
 				// Get the database metadata:
 				DatabaseMetaData dbMeta = conn.connection.getMetaData();
 
@@ -390,7 +391,7 @@ public class TestJDBCConnection {
 				assertFalse(conn.isColumnExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.COLUMNS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.COLUMNS.label), "column_name", dbMeta));
 				assertFalse(conn.isColumnExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.KEYS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.KEYS.label), "key_id", dbMeta));
 				assertFalse(conn.isColumnExisting(STDSchema.TAPSCHEMA.label, (conn.supportsSchema ? STDTable.KEY_COLUMNS.label : STDSchema.TAPSCHEMA.label + "_" + STDTable.KEY_COLUMNS.label), "key_id", dbMeta));
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				ex.printStackTrace(System.err);
 				fail("{" + conn.getID() + "} Testing the existence of a column should not throw an error!");
 			}
@@ -398,13 +399,13 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testAddUploadedTable(){
+	public void testAddUploadedTable() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
 		TAPTable tableDef = null;
-		for(JDBCConnection conn : connections){
+		for(JDBCConnection conn : connections) {
 			InputStream io = null;
-			try{
+			try {
 				io = new FileInputStream(uploadExamplePath);
 				TableIterator it = new VOTableIterator(io);
 
@@ -414,10 +415,10 @@ public class TestJDBCConnection {
 					tableDef.addColumn(c);
 
 				// Test with no schema set:
-				try{
+				try {
 					conn.addUploadedTable(tableDef, it);
 					fail("The table is not inside a TAPSchema, so this test should have failed!");
-				}catch(Exception ex){
+				} catch(Exception ex) {
 					assertTrue(ex instanceof DBException);
 					assertEquals("Missing upload schema! An uploaded table must be inside a schema whose the ADQL name is strictly equals to \"" + STDSchema.UPLOADSCHEMA.label + "\" (but the DB name may be different).", ex.getMessage());
 				}
@@ -429,9 +430,9 @@ public class TestJDBCConnection {
 				// Prepare the test: no TAP_UPLOAD schema and no table TAP_UPLOAD.UploadExample:
 				dropSchema(STDSchema.UPLOADSCHEMA.label, conn);
 				// Test:
-				try{
+				try {
 					assertTrue(conn.addUploadedTable(tableDef, it));
-				}catch(Exception ex){
+				} catch(Exception ex) {
 					ex.printStackTrace(System.err);
 					fail("{" + conn.ID + "} This error should not happen: no TAP_UPLOAD schema.");
 				}
@@ -443,9 +444,9 @@ public class TestJDBCConnection {
 				// Prepare the test: the TAP_UPLOAD schema exist but not the table TAP_UPLOAD.UploadExample:
 				dropTable(tableDef.getDBSchemaName(), tableDef.getDBName(), conn);
 				// Test:
-				try{
+				try {
 					assertTrue(conn.addUploadedTable(tableDef, it));
-				}catch(Exception ex){
+				} catch(Exception ex) {
 					ex.printStackTrace(System.err);
 					fail("{" + conn.ID + "} This error should not happen: no TAP_UPLOAD schema.");
 				}
@@ -457,36 +458,36 @@ public class TestJDBCConnection {
 				// Prepare the test: the TAP_UPLOAD schema and the table TAP_UPLOAD.UploadExample BOTH exist:
 				;
 				// Test:
-				try{
+				try {
 					assertFalse(conn.addUploadedTable(tableDef, it));
-				}catch(Exception ex){
+				} catch(Exception ex) {
 					if (ex instanceof DBException)
 						assertEquals("Impossible to create the user uploaded table in the database: " + conn.translator.getTableName(tableDef, conn.supportsSchema) + "! This table already exists.", ex.getMessage());
-					else{
+					else {
 						ex.printStackTrace(System.err);
 						fail("{" + conn.ID + "} DBException was the expected exception!");
 					}
 				}
 
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				ex.printStackTrace(System.err);
 				fail("{" + conn.ID + "} This error should never happen except there is a problem with the file (" + uploadExamplePath + ").");
-			}finally{
+			} finally {
 				close(io);
 			}
 		}
 	}
 
 	@Test
-	public void testDropUploadedTable(){
+	public void testDropUploadedTable() {
 		TAPTable tableDef = new TAPTable("TableToDrop");
 		TAPSchema uploadSchema = new TAPSchema(STDSchema.UPLOADSCHEMA.label);
 		uploadSchema.addTable(tableDef);
 
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
-			try{
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
+			try {
 				// 1st TEST CASE: the schema TAP_UPLOAD does not exist -> no error should be raised!
 				// drop the TAP_UPLOAD schema:
 				dropSchema(uploadSchema.getDBName(), conn);
@@ -505,7 +506,7 @@ public class TestJDBCConnection {
 				// try to drop the table:
 				assertTrue(conn.dropUploadedTable(tableDef));
 
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				ex.printStackTrace(System.err);
 				fail("{" + conn.ID + "} This error should not happen. The table should be dropped and even if it does not exist, no error should be thrown.");
 			}
@@ -513,17 +514,18 @@ public class TestJDBCConnection {
 	}
 
 	@Test
-	public void testExecuteQuery(){
+	public void testExecuteQuery() {
 		// There should be no difference between a H2 connection and a SQLITE one!
-		JDBCConnection[] connections = new JDBCConnection[]{h2JDBCConnection,sensH2JDBCConnection,sqliteJDBCConnection,sensSqliteJDBCConnection};
-		for(JDBCConnection conn : connections){
+		JDBCConnection[] connections = new JDBCConnection[]{ h2JDBCConnection, sensH2JDBCConnection, sqliteJDBCConnection, sensSqliteJDBCConnection };
+		for(JDBCConnection conn : connections) {
 
 			TAPSchema schema = TAPMetadata.getStdSchema(conn.supportsSchema);
 			ArrayList<DBTable> tables = new ArrayList<DBTable>(schema.getNbTables());
 			for(TAPTable t : schema)
 				tables.add(t);
 
-			ADQLParser parser = new ADQLParser(new DBChecker(tables));
+			ADQLParser parser = (new ADQLParserFactory()).createParser();
+			parser.setQueryChecker(new DBChecker(tables));
 			parser.setDebug(false);
 
 			/*if (conn.ID.equalsIgnoreCase("SQLITE")){
@@ -535,7 +537,7 @@ public class TestJDBCConnection {
 			}*/
 
 			TableIterator result = null;
-			try{
+			try {
 				// Prepare the test: create the TAP_SCHEMA:
 				dropSchema(STDSchema.TAPSCHEMA.label, conn);
 				// Build the ADQLQuery object:
@@ -543,22 +545,23 @@ public class TestJDBCConnection {
 				// Execute the query:
 				result = conn.executeQuery(query);
 				fail("{" + conn.ID + "} This test should have failed because TAP_SCHEMA was supposed to not exist!");
-			}catch(DBException de){
+			} catch(DBException de) {
 				assertTrue(de.getMessage().startsWith("Unexpected error while executing a SQL query: "));
 				assertTrue(de.getMessage().indexOf("tap_schema") > 0 || de.getMessage().indexOf("TAP_SCHEMA") > 0);
-			}catch(ParseException pe){
+			} catch(ParseException pe) {
 				pe.printStackTrace(System.err);
 				fail("There should be no pbm to parse the ADQL expression!");
-			}finally{
-				if (result != null){
-					try{
+			} finally {
+				if (result != null) {
+					try {
 						result.close();
-					}catch(DataReadException de){}
+					} catch(DataReadException de) {
+					}
 					result = null;
 				}
 			}
 
-			try{
+			try {
 				// Prepare the test: create the TAP_SCHEMA:
 				createTAPSchema(conn);
 				// Build the ADQLQuery object:
@@ -567,29 +570,30 @@ public class TestJDBCConnection {
 				result = conn.executeQuery(query);
 				assertEquals(1, result.getMetadata().length);
 				int cntRow = 0;
-				while(result.nextRow()){
+				while(result.nextRow()) {
 					cntRow++;
 					assertTrue(result.hasNextCol());
 					assertNotNull(TAPMetadata.resolveStdTable((String)result.nextCol()));
 					assertFalse(result.hasNextCol());
 				}
 				assertEquals(5, cntRow);
-			}catch(DBException de){
+			} catch(DBException de) {
 				de.printStackTrace(System.err);
 				fail("No ADQL/SQL query error was expected here!");
-			}catch(ParseException pe){
+			} catch(ParseException pe) {
 				fail("There should be no pbm to parse the ADQL expression!");
-			}catch(DataReadException e){
+			} catch(DataReadException e) {
 				e.printStackTrace(System.err);
 				fail("There should be no pbm when accessing rows and the first (and only) columns of the result!");
-			}catch(Exception ex){
+			} catch(Exception ex) {
 				ex.printStackTrace(System.err);
 				fail("There should be no pbm when reading the query result!");
-			}finally{
-				if (result != null){
-					try{
+			} finally {
+				if (result != null) {
+					try {
 						result.close();
-					}catch(DataReadException de){}
+					} catch(DataReadException de) {
+					}
 					result = null;
 				}
 			}
@@ -600,7 +604,7 @@ public class TestJDBCConnection {
 	/* TOOL FUNCTIONS */
 	/* ************** */
 
-	public final static void main(final String[] args) throws Throwable{
+	public final static void main(final String[] args) throws Throwable {
 		JDBCConnection conn = new JDBCConnection(DBTools.createConnection("h2", null, null, DBTools.DB_TEST_PATH, DBTools.DB_TEST_USER, DBTools.DB_TEST_PWD), new AstroH2Translator(), "TEST_H2", null);
 		TestJDBCConnection.createTAPSchema(conn);
 		TestJDBCConnection.dropSchema(STDSchema.TAPSCHEMA.label, conn);
@@ -608,62 +612,62 @@ public class TestJDBCConnection {
 
 	/**
 	 * <p>Build a table prefix with the given schema name.</p>
-	 * 
+	 *
 	 * <p>By default, this function returns: schemaName + "_".</p>
-	 * 
+	 *
 	 * <p><b>CAUTION:
 	 * 	This function is used only when schemas are not supported by the DBMS connection.
 	 * 	It aims to propose an alternative of the schema notion by prefixing the table name by the schema name.
 	 * </b></p>
-	 * 
+	 *
 	 * <p><i>Note:
 	 * 	If the given schema is NULL or is an empty string, an empty string will be returned.
 	 * 	Thus, no prefix will be set....which is very useful when the table name has already been prefixed
 	 * 	(in such case, the DB name of its schema has theoretically set to NULL).
 	 * </i></p>
-	 * 
+	 *
 	 * @param schemaName	(DB) Schema name.
-	 * 
+	 *
 	 * @return	The corresponding table prefix, or "" if the given schema name is an empty string or NULL.
 	 */
-	protected static String getTablePrefix(final String schemaName){
+	protected static String getTablePrefix(final String schemaName) {
 		if (schemaName != null && schemaName.trim().length() > 0)
 			return schemaName + "_";
 		else
 			return "";
 	}
 
-	private static String getOfficialSchemaName(final String schemaName, final JDBCConnection conn){
+	private static String getOfficialSchemaName(final String schemaName, final JDBCConnection conn) {
 		Statement stmt = null;
 		ResultSet rs = null;
-		try{
+		try {
 			stmt = conn.connection.createStatement();
 			rs = conn.connection.getMetaData().getSchemas();
-			while(rs.next()){
+			while(rs.next()) {
 				if (schemaName.equalsIgnoreCase(rs.getString(1)))
 					return rs.getString(1);
 			}
 			close(rs);
 			rs = null;
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			rollback(conn);
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to fetch the official DB schema name of " + schemaName + "!");
-		}finally{
+		} finally {
 			close(rs);
 			close(stmt);
 		}
 		return null;
 	}
 
-	private static void dropSchema(String schemaName, final JDBCConnection conn){
+	private static void dropSchema(String schemaName, final JDBCConnection conn) {
 		Statement stmt = null;
 		ResultSet rs = null;
-		try{
+		try {
 			stmt = conn.connection.createStatement();
 
 			final boolean caseSensitive = conn.translator.isCaseSensitive(IdentifierField.SCHEMA);
-			if (conn.supportsSchema){
+			if (conn.supportsSchema) {
 				// search the official case sensitive schema name:
 				schemaName = getOfficialSchemaName(schemaName, conn);
 				// do nothing if the schema does not exist:
@@ -683,7 +687,7 @@ public class TestJDBCConnection {
 				// finally drop the schema itself:
 				stmt.executeUpdate("DROP SCHEMA IF EXISTS " + formatIdentifier(schemaName, true) + ";");
 				commit(conn);
-			}else{
+			} else {
 				startTransaction(conn);
 				final String tablePrefix = getTablePrefix(schemaName);
 				final int prefixLen = tablePrefix.length();
@@ -691,9 +695,9 @@ public class TestJDBCConnection {
 					return;
 				rs = conn.connection.getMetaData().getTables(null, null, null, null);
 				ArrayList<String> tablesToDrop = new ArrayList<String>();
-				while(rs.next()){
+				while(rs.next()) {
 					String table = rs.getString(3);
-					if (table.length() > prefixLen){
+					if (table.length() > prefixLen) {
 						if (equals(schemaName, table.substring(0, prefixLen - 1), caseSensitive))
 							tablesToDrop.add(table);
 					}
@@ -704,31 +708,31 @@ public class TestJDBCConnection {
 					stmt.executeUpdate("DROP TABLE IF EXISTS \"" + t + "\";");
 				commit(conn);
 			}
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			rollback(conn);
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to prepare a test by: dropping the schema " + schemaName + "!");
-		}finally{
+		} finally {
 			close(rs);
 			close(stmt);
 		}
 	}
 
-	private static void dropTable(final String schemaName, final String tableName, final JDBCConnection conn){
+	private static void dropTable(final String schemaName, final String tableName, final JDBCConnection conn) {
 		Statement stmt = null;
 		ResultSet rs = null;
-		try{
+		try {
 			final boolean sCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.SCHEMA);
 			final boolean tCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.TABLE);
 			stmt = conn.connection.createStatement();
 			if (conn.supportsSchema)
 				stmt.executeUpdate("DROP TABLE IF EXISTS " + formatIdentifier(schemaName, sCaseSensitive) + "." + formatIdentifier(tableName, tCaseSensitive) + ";");
-			else{
+			else {
 				rs = conn.connection.getMetaData().getTables(null, null, null, null);
 				String tableToDrop = null;
-				while(rs.next()){
+				while(rs.next()) {
 					String table = rs.getString(3);
-					if (equals(tableName, table, tCaseSensitive)){
+					if (equals(tableName, table, tCaseSensitive)) {
 						tableToDrop = table;
 						break;
 					}
@@ -737,16 +741,16 @@ public class TestJDBCConnection {
 				if (tableToDrop != null)
 					stmt.executeUpdate("DROP TABLE IF EXISTS \"" + tableToDrop + "\";");
 			}
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to prepare a test by: dropping the table " + schemaName + "." + tableName + "!");
-		}finally{
+		} finally {
 			close(rs);
 			close(stmt);
 		}
 	}
 
-	private static void createSchema(final String schemaName, final JDBCConnection conn){
+	private static void createSchema(final String schemaName, final JDBCConnection conn) {
 		if (!conn.supportsSchema)
 			return;
 
@@ -754,25 +758,25 @@ public class TestJDBCConnection {
 
 		Statement stmt = null;
 		ResultSet rs = null;
-		try{
+		try {
 			final boolean sCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.SCHEMA);
 			stmt = conn.connection.createStatement();
 			stmt.executeUpdate("CREATE SCHEMA " + formatIdentifier(schemaName, sCaseSensitive) + ";");
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to prepare a test by: creating the schema " + schemaName + "!");
-		}finally{
+		} finally {
 			close(rs);
 			close(stmt);
 		}
 	}
 
-	private static void createFooTable(final String schemaName, final String tableName, final JDBCConnection conn){
+	private static void createFooTable(final String schemaName, final String tableName, final JDBCConnection conn) {
 		dropTable(schemaName, tableName, conn);
 
 		Statement stmt = null;
 		ResultSet rs = null;
-		try{
+		try {
 			final boolean sCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.SCHEMA);
 			final boolean tCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.TABLE);
 			String tablePrefix = formatIdentifier(schemaName, sCaseSensitive);
@@ -782,29 +786,29 @@ public class TestJDBCConnection {
 				tablePrefix += ".";
 			stmt = conn.connection.createStatement();
 			stmt.executeUpdate("CREATE TABLE " + tablePrefix + formatIdentifier(tableName, tCaseSensitive) + " (ID integer);");
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to prepare a test by: creating the table " + schemaName + "." + tableName + "!");
-		}finally{
+		} finally {
 			close(rs);
 			close(stmt);
 		}
 	}
 
-	private static TAPMetadata createTAPSchema(final JDBCConnection conn){
+	private static TAPMetadata createTAPSchema(final JDBCConnection conn) {
 		dropSchema(STDSchema.TAPSCHEMA.label, conn);
 
 		TAPMetadata metadata = new TAPMetadata();
 		Statement stmt = null;
-		try{
+		try {
 			final boolean sCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.SCHEMA);
 			final boolean tCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.TABLE);
 			final boolean cCaseSensitive = conn.translator.isCaseSensitive(IdentifierField.COLUMN);
-			String[] tableNames = new String[]{STDTable.SCHEMAS.label,STDTable.TABLES.label,STDTable.COLUMNS.label,STDTable.KEYS.label,STDTable.KEY_COLUMNS.label};
-			if (conn.supportsSchema){
+			String[] tableNames = new String[]{ STDTable.SCHEMAS.label, STDTable.TABLES.label, STDTable.COLUMNS.label, STDTable.KEYS.label, STDTable.KEY_COLUMNS.label };
+			if (conn.supportsSchema) {
 				for(int i = 0; i < tableNames.length; i++)
 					tableNames[i] = formatIdentifier(STDSchema.TAPSCHEMA.label, sCaseSensitive) + "." + formatIdentifier(tableNames[i], tCaseSensitive);
-			}else{
+			} else {
 				for(int i = 0; i < tableNames.length; i++)
 					tableNames[i] = formatIdentifier(getTablePrefix(STDSchema.TAPSCHEMA.label) + tableNames[i], tCaseSensitive);
 			}
@@ -840,14 +844,14 @@ public class TestJDBCConnection {
 			metadata.addSchema(TAPMetadata.getStdSchema(conn.supportsSchema));
 
 			ArrayList<TAPTable> lstTables = new ArrayList<TAPTable>();
-			for(TAPSchema schema : metadata){
+			for(TAPSchema schema : metadata) {
 				stmt.executeUpdate("INSERT INTO " + tableNames[0] + " VALUES('" + schema.getADQLName() + "','" + schema.getDescription() + "','" + schema.getUtype() + "','" + schema.getDBName() + "')");
 				for(TAPTable t : schema)
 					lstTables.add(t);
 			}
 
 			ArrayList<DBColumn> lstCols = new ArrayList<DBColumn>();
-			for(TAPTable table : lstTables){
+			for(TAPTable table : lstTables) {
 				stmt.executeUpdate("INSERT INTO " + tableNames[1] + " VALUES('" + table.getADQLSchemaName() + "','" + table.getADQLName() + "','" + table.getType() + "','" + table.getDescription() + "','" + table.getUtype() + "','" + table.getDBName() + "')");
 				for(DBColumn c : table)
 					lstCols.add(c);
@@ -855,47 +859,50 @@ public class TestJDBCConnection {
 			}
 			lstTables = null;
 
-			for(DBColumn c : lstCols){
+			for(DBColumn c : lstCols) {
 				TAPColumn col = (TAPColumn)c;
 				stmt.executeUpdate("INSERT INTO " + tableNames[2] + " VALUES('" + col.getTable().getADQLName() + "','" + col.getADQLName() + "','" + col.getDescription() + "','" + col.getUnit() + "','" + col.getUcd() + "','" + col.getUtype() + "','" + col.getDatatype().type + "'," + col.getDatatype().length + "," + col.getDatatype().length + "," + (col.isPrincipal() ? 1 : 0) + "," + (col.isIndexed() ? 1 : 0) + "," + (col.isStd() ? 1 : 0) + ",'" + col.getDBName() + "')");
 			}
 
 			commit(conn);
 
-		}catch(Exception ex){
+		} catch(Exception ex) {
 			rollback(conn);
 			ex.printStackTrace(System.err);
 			fail("{" + conn.ID + "} Impossible to prepare a test by: creating TAP_SCHEMA!");
-		}finally{
+		} finally {
 			close(stmt);
 		}
 
 		return metadata;
 	}
 
-	private static void startTransaction(final JDBCConnection conn){
-		try{
+	private static void startTransaction(final JDBCConnection conn) {
+		try {
 			conn.connection.setAutoCommit(false);
-		}catch(SQLException se){}
+		} catch(SQLException se) {
+		}
 	}
 
-	private static void commit(final JDBCConnection conn){
-		try{
+	private static void commit(final JDBCConnection conn) {
+		try {
 			conn.connection.commit();
 			conn.connection.setAutoCommit(true);
-		}catch(SQLException se){}
+		} catch(SQLException se) {
+		}
 
 	}
 
-	private static void rollback(final JDBCConnection conn){
-		try{
+	private static void rollback(final JDBCConnection conn) {
+		try {
 			conn.connection.rollback();
 			conn.connection.setAutoCommit(true);
-		}catch(SQLException se){}
+		} catch(SQLException se) {
+		}
 
 	}
 
-	private static String formatIdentifier(final String identifier, final boolean caseSensitive){
+	private static String formatIdentifier(final String identifier, final boolean caseSensitive) {
 		if (identifier == null)
 			return null;
 		else if (identifier.charAt(0) == '"')
@@ -906,35 +913,35 @@ public class TestJDBCConnection {
 			return identifier;
 	}
 
-	private static boolean equals(final String name1, final String name2, final boolean caseSensitive){
+	private static boolean equals(final String name1, final String name2, final boolean caseSensitive) {
 		return (name1 != null && name2 != null && (caseSensitive ? name1.equals(name2) : name1.equalsIgnoreCase(name2)));
 	}
 
-	private static boolean equals(final TAPTable table1, final TAPTable table2){
-		if (table1 == null || table2 == null){
+	private static boolean equals(final TAPTable table1, final TAPTable table2) {
+		if (table1 == null || table2 == null) {
 			//System.out.println("[EQUALS] tables null!");
 			return false;
 		}
 
-		if (!table1.getFullName().equals(table2.getFullName())){
+		if (!table1.getFullName().equals(table2.getFullName())) {
 			//System.out.println("[EQUALS] tables name different: " + table1.getFullName() + " != " + table2.getFullName() + "!");
 			return false;
 		}
 
-		if (table1.getType() != table2.getType()){
+		if (table1.getType() != table2.getType()) {
 			//System.out.println("[EQUALS] tables type different: " + table1.getType() + " != " + table2.getType() + "!");
 			return false;
 		}
 
-		if (table1.getNbColumns() != table2.getNbColumns()){
+		if (table1.getNbColumns() != table2.getNbColumns()) {
 			//System.out.println("[EQUALS] tables length different: " + table1.getNbColumns() + " columns != " + table2.getNbColumns() + " columns!");
 			return false;
 		}
 
 		Iterator<TAPColumn> it = table1.getColumns();
-		while(it.hasNext()){
+		while(it.hasNext()) {
 			TAPColumn col1 = it.next();
-			if (!equals(col1, table2.getColumn(col1.getADQLName()))){
+			if (!equals(col1, table2.getColumn(col1.getADQLName()))) {
 				//System.out.println("[EQUALS] tables columns different!");
 				return false;
 			}
@@ -943,28 +950,28 @@ public class TestJDBCConnection {
 		return true;
 	}
 
-	private static boolean equals(final TAPColumn col1, final TAPColumn col2){
-		if (col1 == null || col2 == null){
+	private static boolean equals(final TAPColumn col1, final TAPColumn col2) {
+		if (col1 == null || col2 == null) {
 			//System.out.println("[EQUALS] columns null!");
 			return false;
 		}
 
-		if (!col1.getADQLName().equals(col2.getADQLName())){
+		if (!col1.getADQLName().equals(col2.getADQLName())) {
 			//System.out.println("[EQUALS] columns name different: " + col1.getADQLName() + " != " + col2.getADQLName() + "!");
 			return false;
 		}
 
-		if (!equals(col1.getDatatype(), col2.getDatatype())){
+		if (!equals(col1.getDatatype(), col2.getDatatype())) {
 			//System.out.println("[EQUALS] columns type different: " + col1.getDatatype() + " != " + col2.getDatatype() + "!");
 			return false;
 		}
 
-		if (col1.getUnit() != col2.getUnit()){
+		if (col1.getUnit() != col2.getUnit()) {
 			//System.out.println("[EQUALS] columns unit different: " + col1.getUnit() + " != " + col2.getUnit() + "!");
 			return false;
 		}
 
-		if (col1.getUcd() != col2.getUcd()){
+		if (col1.getUcd() != col2.getUcd()) {
 			//System.out.println("[EQUALS] columns ucd different: " + col1.getUcd() + " != " + col2.getUcd() + "!");
 			return false;
 		}
@@ -972,11 +979,11 @@ public class TestJDBCConnection {
 		return true;
 	}
 
-	private static boolean equals(final DBType type1, final DBType type2){
+	private static boolean equals(final DBType type1, final DBType type2) {
 		return type1 != null && type2 != null && type1.type == type2.type && type1.length == type2.length;
 	}
 
-	private static TAPMetadata createCustomSchema(){
+	private static TAPMetadata createCustomSchema() {
 		TAPMetadata tapMeta = new TAPMetadata();
 		TAPSchema tapSchema = new TAPSchema(STDSchema.TAPSCHEMA.toString());
 		TAPTable customColumns = (TAPTable)TAPMetadata.getStdTable(STDTable.COLUMNS).copy("Columns", STDTable.COLUMNS.label);
@@ -992,22 +999,22 @@ public class TestJDBCConnection {
 
 	/**
 	 * <p>Get the expected counts after a call of {@link JDBCConnection#setTAPSchema(TAPMetadata)}.</p>
-	 * 
+	 *
 	 * <p>Counts are computed from the given metadata ; the same metadata that will be given to {@link JDBCConnection#setTAPSchema(TAPMetadata)}.</p>
-	 * 
+	 *
 	 * @param meta
-	 * 
+	 *
 	 * @return	An integer array with the following values: [0]=nbSchemas, [1]=nbTables, [2]=nbColumns, [3]=nbKeys and [4]=nbKeyColumns.
 	 */
-	private static int[] getStats(final TAPMetadata meta){
-		int[] counts = new int[]{1,5,0,0,0};
+	private static int[] getStats(final TAPMetadata meta) {
+		int[] counts = new int[]{ 1, 5, 0, 0, 0 };
 
-		int[] stdColCounts = new int[]{4,6,13,5,3}; // 4,6 because of the addition of `dbname` ; 13 because of the addition of `dbname` and `arraysize` (tap-1.1)
+		int[] stdColCounts = new int[]{ 4, 6, 13, 5, 3 }; // 4,6 because of the addition of `dbname` ; 13 because of the addition of `dbname` and `arraysize` (tap-1.1)
 		for(int c = 0; c < stdColCounts.length; c++)
 			counts[2] += stdColCounts[c];
 
 		Iterator<TAPSchema> itSchemas = meta.iterator();
-		while(itSchemas.hasNext()){
+		while(itSchemas.hasNext()) {
 			TAPSchema schema = itSchemas.next();
 
 			boolean isTapSchema = (schema.getADQLName().equalsIgnoreCase(STDSchema.TAPSCHEMA.toString()));
@@ -1015,22 +1022,22 @@ public class TestJDBCConnection {
 				counts[0]++;
 
 			Iterator<TAPTable> itTables = schema.iterator();
-			while(itTables.hasNext()){
+			while(itTables.hasNext()) {
 				TAPTable table = itTables.next();
-				if (isTapSchema && TAPMetadata.resolveStdTable(table.getADQLName()) != null){
+				if (isTapSchema && TAPMetadata.resolveStdTable(table.getADQLName()) != null) {
 					int ind = h2JDBCConnection.getCreationOrder(TAPMetadata.resolveStdTable(table.getADQLName()));
 					counts[2] -= stdColCounts[ind];
-				}else
+				} else
 					counts[1]++;
 
 				Iterator<DBColumn> itColumns = table.iterator();
-				while(itColumns.hasNext()){
+				while(itColumns.hasNext()) {
 					itColumns.next();
 					counts[2]++;
 				}
 
 				Iterator<TAPForeignKey> itKeys = table.getForeignKeys();
-				while(itKeys.hasNext()){
+				while(itKeys.hasNext()) {
 					TAPForeignKey fk = itKeys.next();
 					counts[3]++;
 					counts[4] += fk.getNbRelations();
@@ -1043,19 +1050,19 @@ public class TestJDBCConnection {
 
 	/**
 	 * <p>Get the effective counts after a call of {@link JDBCConnection#setTAPSchema(TAPMetadata)}.</p>
-	 * 
+	 *
 	 * <p>Counts are computed directly from the DB using the given connection; the same connection used to set the TAP schema in {@link JDBCConnection#setTAPSchema(TAPMetadata)}.</p>
-	 * 
+	 *
 	 * @param conn
 	 * @param meta	Metadata, in order to get the standard TAP tables' name.
-	 * 
+	 *
 	 * @return	An integer array with the following values: [0]=nbSchemas, [1]=nbTables, [2]=nbColumns, [3]=nbKeys and [4]=nbKeyColumns.
 	 */
-	private static int[] getStats(final JDBCConnection conn, final TAPMetadata meta){
+	private static int[] getStats(final JDBCConnection conn, final TAPMetadata meta) {
 		int[] counts = new int[5];
 
 		Statement stmt = null;
-		try{
+		try {
 			stmt = conn.connection.createStatement();
 
 			TAPSchema tapSchema = meta.getSchema(STDSchema.TAPSCHEMA.toString());
@@ -1082,52 +1089,56 @@ public class TestJDBCConnection {
 			tapTable = tapSchema.getTable(STDTable.KEY_COLUMNS.toString());
 			counts[4] = count(stmt, schemaPrefix + formatIdentifier(tapTable.getDBName(), tCaseSensitive), tapSchema.getADQLName() + "." + tapTable.getADQLName());
 
-		}catch(SQLException se){
+		} catch(SQLException se) {
 			fail("Can not create a statement!");
-		}finally{
-			try{
+		} finally {
+			try {
 				if (stmt != null)
 					stmt.close();
-			}catch(SQLException ex){}
+			} catch(SQLException ex) {
+			}
 		}
 		return counts;
 	}
 
-	private static int count(final Statement stmt, final String qualifiedTableName, final String adqlTableName){
+	private static int count(final Statement stmt, final String qualifiedTableName, final String adqlTableName) {
 		ResultSet rs = null;
-		try{
+		try {
 			rs = stmt.executeQuery("SELECT COUNT(*) FROM " + qualifiedTableName + ";");
 			rs.next();
 			return rs.getInt(1);
-		}catch(Exception e){
+		} catch(Exception e) {
 			e.printStackTrace(System.err);
 			fail("Can not count! Maybe " + qualifiedTableName + " (in ADQL: " + adqlTableName + ") does not exist.");
 			return -1;
-		}finally{
+		} finally {
 			close(rs);
 		}
 	}
 
-	private static void close(final ResultSet rs){
+	private static void close(final ResultSet rs) {
 		if (rs == null)
 			return;
-		try{
+		try {
 			rs.close();
-		}catch(SQLException se){}
+		} catch(SQLException se) {
+		}
 	}
 
-	private static void close(final Statement stmt){
-		try{
+	private static void close(final Statement stmt) {
+		try {
 			if (stmt != null)
 				stmt.close();
-		}catch(SQLException se){}
+		} catch(SQLException se) {
+		}
 	}
 
-	private static void close(final InputStream io){
-		try{
+	private static void close(final InputStream io) {
+		try {
 			if (io != null)
 				io.close();
-		}catch(IOException ioe){}
+		} catch(IOException ioe) {
+		}
 	}
 
 }