From d648f48baa15f85c73d2c71a206f7802c037daa5 Mon Sep 17 00:00:00 2001
From: gmantele <gmantele@ari.uni-heidelberg.de>
Date: Wed, 28 May 2014 15:28:58 +0200
Subject: [PATCH] ADQLObject has now a new function: getPosition(). To allow
 it, the parser and all ADQL query tree item have been modified to define this
 function properly. The parser is setting this position for all parsed items.
 The test class/main function "TestGetPositionInAllADQLObject" aims to check
 that after a parsing all items really have a defined position.

---
 src/adql/parser/ADQLParser.java               | 2784 +++++++------
 src/adql/parser/ADQLParserConstants.java      |  505 ++-
 src/adql/parser/ADQLParserTokenManager.java   | 3515 +++++++++--------
 src/adql/parser/ADQLQueryFactory.java         |   39 +-
 src/adql/parser/adqlGrammar.jj                |  469 ++-
 src/adql/query/ADQLList.java                  |   57 +-
 src/adql/query/ADQLObject.java                |   21 +-
 src/adql/query/ADQLQuery.java                 |   58 +-
 src/adql/query/SelectAllColumns.java          |   17 +-
 src/adql/query/SelectItem.java                |   43 +-
 src/adql/query/TextPosition.java              |   30 +-
 src/adql/query/constraint/Between.java        |   42 +-
 src/adql/query/constraint/Comparison.java     |   46 +-
 src/adql/query/constraint/Exists.java         |   45 +-
 src/adql/query/constraint/In.java             |   58 +-
 src/adql/query/constraint/IsNull.java         |   46 +-
 src/adql/query/constraint/NotConstraint.java  |   40 +-
 src/adql/query/from/ADQLJoin.java             |   25 +-
 src/adql/query/from/FromContent.java          |   11 +-
 src/adql/query/operand/ADQLColumn.java        |   13 +-
 src/adql/query/operand/NegativeOperand.java   |   36 +-
 src/adql/query/operand/NumericConstant.java   |   31 +-
 src/adql/query/operand/Operation.java         |   44 +-
 src/adql/query/operand/StringConstant.java    |   31 +-
 src/adql/query/operand/WrappedOperand.java    |   40 +-
 .../query/operand/function/ADQLFunction.java  |   37 +-
 .../query/operand/function/DefaultUDF.java    |    8 +-
 .../query/operand/function/MathFunction.java  |    6 +-
 .../query/operand/function/SQLFunction.java   |   16 +-
 .../function/geometry/AreaFunction.java       |   17 +-
 .../function/geometry/BoxFunction.java        |   17 +-
 .../function/geometry/CentroidFunction.java   |   15 +-
 .../function/geometry/CircleFunction.java     |   16 +-
 .../function/geometry/ContainsFunction.java   |   23 +-
 .../function/geometry/DistanceFunction.java   |   18 +-
 .../function/geometry/ExtractCoord.java       |   15 +-
 .../function/geometry/ExtractCoordSys.java    |   15 +-
 .../function/geometry/GeometryFunction.java   |   40 +-
 .../function/geometry/IntersectsFunction.java |   23 +-
 .../function/geometry/PointFunction.java      |   22 +-
 .../function/geometry/PolygonFunction.java    |   15 +-
 .../function/geometry/RegionFunction.java     |    3 +-
 test/adql/TestGetPositionInAllADQLObject.java |   27 +
 43 files changed, 4846 insertions(+), 3533 deletions(-)
 create mode 100644 test/adql/TestGetPositionInAllADQLObject.java

diff --git a/src/adql/parser/ADQLParser.java b/src/adql/parser/ADQLParser.java
index b1649f8..f5f1e54 100644
--- a/src/adql/parser/ADQLParser.java
+++ b/src/adql/parser/ADQLParser.java
@@ -25,14 +25,21 @@ 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;
@@ -526,6 +533,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public ADQLQuery QueryExpression() throws ParseException{
 		trace_call("QueryExpression");
 		try{
+			TextPosition endPos = null;
 			try{
 				// create the query:
 				query = queryFactory.createQuery();
@@ -538,9 +546,11 @@ public class ADQLParser implements ADQLParserConstants {
 			}
 			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;
@@ -549,6 +559,7 @@ public class ADQLParser implements ADQLParserConstants {
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case GROUP_BY:
 					GroupBy();
+					endPos = query.getGroupBy().getPosition();
 					break;
 				default:
 					jj_la1[2] = jj_gen;
@@ -557,6 +568,7 @@ public class ADQLParser implements ADQLParserConstants {
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case HAVING:
 					Having();
+					endPos = query.getHaving().getPosition();
 					break;
 				default:
 					jj_la1[3] = jj_gen;
@@ -565,11 +577,15 @@ public class ADQLParser implements ADQLParserConstants {
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case ORDER_BY:
 					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())
@@ -591,9 +607,11 @@ public class ADQLParser implements ADQLParserConstants {
 		trace_call("SubQueryExpression");
 		try{
 			ADQLQuery q = null;
-			jj_consume_token(LEFT_PAR);
+			Token start, end;
+			start = jj_consume_token(LEFT_PAR);
 			q = QueryExpression();
-			jj_consume_token(RIGHT_PAR);
+			end = jj_consume_token(RIGHT_PAR);
+			q.setPosition(new TextPosition(start, end));
 			{
 				if (true)
 					return q;
@@ -609,8 +627,8 @@ public class ADQLParser implements ADQLParserConstants {
 		try{
 			ClauseSelect select = query.getSelect();
 			SelectItem item = null;
-			Token t = null;
-			jj_consume_token(SELECT);
+			Token start, t = null;
+			start = jj_consume_token(SELECT);
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case QUANTIFIER:
 					t = jj_consume_token(QUANTIFIER);
@@ -652,6 +670,8 @@ public class ADQLParser implements ADQLParserConstants {
 				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");
 		}
@@ -663,12 +683,16 @@ public class ADQLParser implements ADQLParserConstants {
 			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:
-					jj_consume_token(ASTERISK);
+					starToken = jj_consume_token(ASTERISK);
+					item = new SelectAllColumns(query);
+					item.setPosition(new TextPosition(starToken));
 					{
 						if (true)
-							return new SelectAllColumns(query);
+							return item;
 					}
 					break;
 				default:
@@ -699,12 +723,14 @@ public class ADQLParser implements ADQLParserConstants {
 								jj_la1[9] = jj_gen;
 								;
 						}
-						jj_consume_token(ASTERISK);
+						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 new SelectAllColumns(queryFactory.createTable(identifiers, null));
+									return item;
 							}
 						}catch(Exception ex){
 							{
@@ -783,9 +809,12 @@ public class ADQLParser implements ADQLParserConstants {
 					}
 			}
 			try{
-				SelectItem item = queryFactory.createSelectItem(op, (label == null) ? null : label.identifier);
-				if (label != null)
+				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;
@@ -820,7 +849,9 @@ public class ADQLParser implements ADQLParserConstants {
 					}
 					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){
@@ -839,8 +870,11 @@ public class ADQLParser implements ADQLParserConstants {
 		try{
 			ClauseConstraints where = query.getWhere();
 			ADQLConstraint condition;
-			jj_consume_token(WHERE);
+			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");
 		}
@@ -851,7 +885,8 @@ public class ADQLParser implements ADQLParserConstants {
 		try{
 			ClauseADQL<ColumnReference> groupBy = query.getGroupBy();
 			ColumnReference colRef = null;
-			jj_consume_token(GROUP_BY);
+			Token start;
+			start = jj_consume_token(GROUP_BY);
 			colRef = ColumnRef();
 			groupBy.add(colRef);
 			label_3: while(true){
@@ -867,6 +902,7 @@ public class ADQLParser implements ADQLParserConstants {
 				colRef = ColumnRef();
 				groupBy.add(colRef);
 			}
+			groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn));
 		}finally{
 			trace_return("GroupBy");
 		}
@@ -876,8 +912,11 @@ public class ADQLParser implements ADQLParserConstants {
 		trace_call("Having");
 		try{
 			ClauseConstraints having = query.getHaving();
-			jj_consume_token(HAVING);
+			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");
 		}
@@ -888,7 +927,8 @@ public class ADQLParser implements ADQLParserConstants {
 		try{
 			ClauseADQL<ADQLOrder> orderBy = query.getOrderBy();
 			ADQLOrder order = null;
-			jj_consume_token(ORDER_BY);
+			Token start;
+			start = jj_consume_token(ORDER_BY);
 			order = OrderItem();
 			orderBy.add(order);
 			label_4: while(true){
@@ -904,6 +944,7 @@ public class ADQLParser implements ADQLParserConstants {
 				order = OrderItem();
 				orderBy.add(order);
 			}
+			orderBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, order.getPosition().endLine, order.getPosition().endColumn));
 		}finally{
 			trace_return("OrderBy");
 		}
@@ -1121,10 +1162,13 @@ public class ADQLParser implements ADQLParserConstants {
 			}
 			try{
 				ADQLOrder order = null;
-				if (identifiers != null)
+				if (identifiers != null){
 					order = queryFactory.createOrder(identifiers, desc != null);
-				else
-					order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null, new TextPosition(ind));
+					order.setPosition(identifiers.getPosition());
+				}else{
+					order = queryFactory.createOrder(Integer.parseInt(ind.image), desc != null);
+					order.setPosition(new TextPosition(ind));
+				}
 				{
 					if (true)
 						return order;
@@ -1148,6 +1192,7 @@ public class ADQLParser implements ADQLParserConstants {
 			IdentifierItems identifiers = null;
 			ADQLQuery subQuery = null;
 			FromContent content = null;
+			Token start, end;
 			try{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case DELIMITED_IDENTIFIER:
@@ -1171,9 +1216,14 @@ public class ADQLParser implements ADQLParserConstants {
 								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 queryFactory.createTable(identifiers, alias);
+								return content;
 						}
 						break;
 					default:
@@ -1189,16 +1239,22 @@ public class ADQLParser implements ADQLParserConstants {
 									;
 							}
 							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 queryFactory.createTable(subQuery, alias);
+									return content;
 							}
 						}else{
 							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 								case LEFT_PAR:
-									jj_consume_token(LEFT_PAR);
+									start = jj_consume_token(LEFT_PAR);
 									content = JoinedTable();
-									jj_consume_token(RIGHT_PAR);
+									end = jj_consume_token(RIGHT_PAR);
+									content.setPosition(new TextPosition(start, end));
 									{
 										if (true)
 											return content;
@@ -1286,6 +1342,8 @@ public class ADQLParser implements ADQLParserConstants {
 			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:
@@ -1342,9 +1400,11 @@ public class ADQLParser implements ADQLParserConstants {
 						}
 						jj_consume_token(JOIN);
 						rightTable = TableRef();
+						join = queryFactory.createJoin(type, leftTable, rightTable);
+						join.setPosition(new TextPosition(leftTable.getPosition(), rightTable.getPosition()));
 						{
 							if (true)
-								return queryFactory.createJoin(type, leftTable, rightTable);
+								return join;
 						}
 						break;
 					case INNER:
@@ -1407,9 +1467,11 @@ public class ADQLParser implements ADQLParserConstants {
 							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 queryFactory.createJoin(type, leftTable, rightTable, condition);
+										return join;
 								}
 								break;
 							case USING:
@@ -1430,10 +1492,12 @@ public class ADQLParser implements ADQLParserConstants {
 									id = Identifier();
 									lstColumns.add(queryFactory.createColumn(id));
 								}
-								jj_consume_token(RIGHT_PAR);
+								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 queryFactory.createJoin(type, leftTable, rightTable, lstColumns);
+										return join;
 								}
 								break;
 							default:
@@ -1462,11 +1526,12 @@ public class ADQLParser implements ADQLParserConstants {
 	/* ****** */
 	/* STRING */
 	/* ****** */
-	final public String String() throws ParseException{
+	final public StringConstant String() throws ParseException{
 		trace_call("String");
 		try{
 			Token t;
 			String str = "";
+			StringConstant cst;
 			label_8: while(true){
 				t = jj_consume_token(STRING_LITERAL);
 				str += t.image;
@@ -1479,9 +1544,19 @@ public class ADQLParser implements ADQLParserConstants {
 						break label_8;
 				}
 			}
-			{
-				if (true)
-					return (str != null) ? str.substring(1, str.length() - 1) : str;
+			try{
+				str = (str != null) ? str.substring(1, str.length() - 1) : str;
+				cst = queryFactory.createStringConstant(str);
+				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{
@@ -1492,10 +1567,11 @@ public class ADQLParser implements ADQLParserConstants {
 	/* ************* */
 	/* NUMERIC TYPES */
 	/* ************* */
-	final public String UnsignedNumeric() throws ParseException{
+	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);
@@ -1511,9 +1587,18 @@ public class ADQLParser implements ADQLParserConstants {
 					jj_consume_token(-1);
 					throw new ParseException();
 			}
-			{
-				if (true)
-					return t.image;
+			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{
@@ -1521,10 +1606,11 @@ public class ADQLParser implements ADQLParserConstants {
 		}
 	}
 
-	final public String UnsignedFloat() throws ParseException{
+	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);
@@ -1537,9 +1623,18 @@ public class ADQLParser implements ADQLParserConstants {
 					jj_consume_token(-1);
 					throw new ParseException();
 			}
-			{
-				if (true)
-					return t.image;
+			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{
@@ -1547,10 +1642,11 @@ public class ADQLParser implements ADQLParserConstants {
 		}
 	}
 
-	final public String SignedInteger() throws ParseException{
+	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:
@@ -1572,9 +1668,23 @@ public class ADQLParser implements ADQLParserConstants {
 					;
 			}
 			number = jj_consume_token(UNSIGNED_INTEGER);
-			{
-				if (true)
-					return ((sign == null) ? "" : sign.image) + number.image;
+			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{
@@ -1588,26 +1698,26 @@ public class ADQLParser implements ADQLParserConstants {
 	final public ADQLOperand ValueExpressionPrimary() throws ParseException{
 		trace_call("ValueExpressionPrimary");
 		try{
-			String expr;
 			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
-						expr = UnsignedNumeric();
+						op = UnsignedNumeric();
 						{
 							if (true)
-								return queryFactory.createNumericConstant(expr);
+								return op;
 						}
 						break;
 					case STRING_LITERAL:
-						expr = String();
+						op = String();
 						{
 							if (true)
-								return queryFactory.createStringConstant(expr);
+								return op;
 						}
 						break;
 					case DELIMITED_IDENTIFIER:
@@ -1630,12 +1740,14 @@ public class ADQLParser implements ADQLParserConstants {
 						}
 						break;
 					case LEFT_PAR:
-						jj_consume_token(LEFT_PAR);
+						left = jj_consume_token(LEFT_PAR);
 						op = ValueExpression();
-						jj_consume_token(RIGHT_PAR);
+						right = jj_consume_token(RIGHT_PAR);
+						WrappedOperand wop = queryFactory.createWrappedOperand(op);
+						wop.setPosition(new TextPosition(left, right));
 						{
 							if (true)
-								return queryFactory.createWrappedOperand(op);
+								return wop;
 						}
 						break;
 					default:
@@ -1772,9 +1884,11 @@ public class ADQLParser implements ADQLParserConstants {
 					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 queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+							return operation;
 					}
 				}catch(Exception ex){
 					{
@@ -1821,9 +1935,11 @@ public class ADQLParser implements ADQLParserConstants {
 					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 queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+							return operation;
 					}
 				}catch(Exception ex){
 					{
@@ -1841,7 +1957,8 @@ public class ADQLParser implements ADQLParserConstants {
 	final public ADQLOperand Factor() throws ParseException{
 		trace_call("Factor");
 		try{
-			boolean negative = false;;
+			boolean negative = false;
+			Token minusSign = null;
 			ADQLOperand op;
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case PLUS:
@@ -1851,7 +1968,7 @@ public class ADQLParser implements ADQLParserConstants {
 							jj_consume_token(PLUS);
 							break;
 						case MINUS:
-							jj_consume_token(MINUS);
+							minusSign = jj_consume_token(MINUS);
 							negative = true;
 							break;
 						default:
@@ -1891,6 +2008,8 @@ public class ADQLParser implements ADQLParserConstants {
 			if (negative){
 				try{
 					op = queryFactory.createNegativeOperand(op);
+					NegativeOperand negativeOp = (NegativeOperand)op;
+					negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, negativeOp.getPosition().endLine, negativeOp.getPosition().endColumn));
 				}catch(Exception ex){
 					{
 						if (true)
@@ -1940,6 +2059,10 @@ public class ADQLParser implements ADQLParserConstants {
 				}
 				((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;
@@ -2043,7 +2166,7 @@ public class ADQLParser implements ADQLParserConstants {
 			try{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case NOT:
-						jj_consume_token(NOT);
+						op = jj_consume_token(NOT);
 						notOp = true;
 						break;
 					default:
@@ -2051,9 +2174,13 @@ public class ADQLParser implements ADQLParserConstants {
 						;
 				}
 				constraint = Constraint();
-				if (notOp)
+				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
@@ -2090,9 +2217,13 @@ public class ADQLParser implements ADQLParserConstants {
 							;
 					}
 					constraint = Constraint();
-					if (notOp)
+					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
@@ -2104,6 +2235,11 @@ public class ADQLParser implements ADQLParserConstants {
 						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;
@@ -2118,12 +2254,13 @@ public class ADQLParser implements ADQLParserConstants {
 		trace_call("Constraint");
 		try{
 			ADQLConstraint constraint = null;
+			Token start, end;
 			if (jj_2_9(2147483647)){
 				constraint = Predicate();
 			}else{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case LEFT_PAR:
-						jj_consume_token(LEFT_PAR);
+						start = jj_consume_token(LEFT_PAR);
 						try{
 							constraint = queryFactory.createGroupOfConstraints();
 						}catch(Exception ex){
@@ -2133,7 +2270,8 @@ public class ADQLParser implements ADQLParserConstants {
 							}
 						}
 						ConditionsList((ConstraintsGroup)constraint);
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
+						((ConstraintsGroup)constraint).setPosition(new TextPosition(start, end));
 						break;
 					default:
 						jj_la1[64] = jj_gen;
@@ -2158,16 +2296,18 @@ public class ADQLParser implements ADQLParserConstants {
 			ADQLColumn column = null;
 			ADQLOperand strExpr1 = null, strExpr2 = null;
 			ADQLOperand op;
-			Token notToken = null;
+			Token start, notToken = null, end;
 			ADQLConstraint constraint = null;
 			try{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case EXISTS:
-						jj_consume_token(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 queryFactory.createExists(q);
+								return e;
 						}
 						break;
 					default:
@@ -2183,10 +2323,12 @@ public class ADQLParser implements ADQLParserConstants {
 									jj_la1[65] = jj_gen;
 									;
 							}
-							jj_consume_token(NULL);
+							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 queryFactory.createIsNull((notToken != null), column);
+									return in;
 							}
 						}else if (jj_2_12(2147483647)){
 							strExpr1 = StringExpression();
@@ -2200,9 +2342,11 @@ public class ADQLParser implements ADQLParserConstants {
 							}
 							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 queryFactory.createComparison(strExpr1, (notToken == null) ? ComparisonOperator.LIKE : ComparisonOperator.NOTLIKE, strExpr2);
+									return comp;
 							}
 						}else{
 							switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
@@ -2338,9 +2482,11 @@ public class ADQLParser implements ADQLParserConstants {
 			}
 			rightOp = ValueExpression();
 			try{
+				Comparison comparison = queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
+				comparison.setPosition(new TextPosition(leftOp.getPosition(), rightOp.getPosition()));
 				{
 					if (true)
-						return queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
+						return comparison;
 				}
 			}catch(Exception ex){
 				{
@@ -2357,7 +2503,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public Between BetweenEnd(ADQLOperand leftOp) throws ParseException{
 		trace_call("BetweenEnd");
 		try{
-			Token notToken = null;
+			Token start, notToken = null;
 			ADQLOperand min, max;
 			switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 				case NOT:
@@ -2367,14 +2513,18 @@ public class ADQLParser implements ADQLParserConstants {
 					jj_la1[72] = jj_gen;
 					;
 			}
-			jj_consume_token(BETWEEN);
+			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 queryFactory.createBetween((notToken != null), leftOp, min, max);
+						return bet;
 				}
 			}catch(Exception ex){
 				{
@@ -2391,7 +2541,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public In InEnd(ADQLOperand leftOp) throws ParseException{
 		trace_call("InEnd");
 		try{
-			Token not = null;
+			Token not = null, start;
 			ADQLQuery q = null;
 			ADQLOperand item;
 			Vector<ADQLOperand> items = new Vector<ADQLOperand>();
@@ -2403,7 +2553,7 @@ public class ADQLParser implements ADQLParserConstants {
 					jj_la1[73] = jj_gen;
 					;
 			}
-			jj_consume_token(IN);
+			start = jj_consume_token(IN);
 			if (jj_2_13(2)){
 				q = SubQueryExpression();
 			}else{
@@ -2434,18 +2584,22 @@ public class ADQLParser implements ADQLParserConstants {
 				}
 			}
 			try{
+				In in;
+				start = (not != null) ? not : start;
 				if (q != null){
-					if (true)
-						return queryFactory.createIn(leftOp, q, not != 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;
-					{
-						if (true)
-							return queryFactory.createIn(leftOp, list, not != null);
-					}
+					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){
 				{
@@ -2465,13 +2619,13 @@ public class ADQLParser implements ADQLParserConstants {
 	final public SQLFunction SqlFunction() throws ParseException{
 		trace_call("SqlFunction");
 		try{
-			Token fct, all = null, distinct = null;
+			Token fct, all = null, distinct = null, end;
 			ADQLOperand op = null;
 			SQLFunction funct = null;
 			try{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case COUNT:
-						jj_consume_token(COUNT);
+						fct = jj_consume_token(COUNT);
 						jj_consume_token(LEFT_PAR);
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case QUANTIFIER:
@@ -2542,8 +2696,9 @@ public class ADQLParser implements ADQLParserConstants {
 								jj_consume_token(-1);
 								throw new ParseException();
 						}
-						jj_consume_token(RIGHT_PAR);
+						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:
@@ -2577,8 +2732,9 @@ public class ADQLParser implements ADQLParserConstants {
 								;
 						}
 						op = ValueExpression();
-						jj_consume_token(RIGHT_PAR);
+						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;
@@ -2624,7 +2780,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public GeometryFunction GeometryFunction() throws ParseException{
 		trace_call("GeometryFunction");
 		try{
-			Token t = null;
+			Token fct = null, end;
 			GeometryValue<GeometryFunction> gvf1, gvf2;
 			GeometryValue<PointFunction> gvp1, gvp2;
 			GeometryFunction gf = null;
@@ -2636,10 +2792,10 @@ public class ADQLParser implements ADQLParserConstants {
 					case INTERSECTS:
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case CONTAINS:
-								t = jj_consume_token(CONTAINS);
+								fct = jj_consume_token(CONTAINS);
 								break;
 							case INTERSECTS:
-								t = jj_consume_token(INTERSECTS);
+								fct = jj_consume_token(INTERSECTS);
 								break;
 							default:
 								jj_la1[81] = jj_gen;
@@ -2650,21 +2806,21 @@ public class ADQLParser implements ADQLParserConstants {
 						gvf1 = GeometryExpression();
 						jj_consume_token(COMMA);
 						gvf2 = GeometryExpression();
-						jj_consume_token(RIGHT_PAR);
-						if (t.image.equalsIgnoreCase("contains"))
+						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:
-						jj_consume_token(AREA);
+						fct = jj_consume_token(AREA);
 						jj_consume_token(LEFT_PAR);
 						gvf1 = GeometryExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createArea(gvf1);
 						break;
 					case COORD1:
-						jj_consume_token(COORD1);
+						fct = jj_consume_token(COORD1);
 						jj_consume_token(LEFT_PAR);
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case POINT:
@@ -2681,10 +2837,10 @@ public class ADQLParser implements ADQLParserConstants {
 								jj_consume_token(-1);
 								throw new ParseException();
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case COORD2:
-						jj_consume_token(COORD2);
+						fct = jj_consume_token(COORD2);
 						jj_consume_token(LEFT_PAR);
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case POINT:
@@ -2701,10 +2857,10 @@ public class ADQLParser implements ADQLParserConstants {
 								jj_consume_token(-1);
 								throw new ParseException();
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case DISTANCE:
-						jj_consume_token(DISTANCE);
+						fct = jj_consume_token(DISTANCE);
 						jj_consume_token(LEFT_PAR);
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case POINT:
@@ -2741,7 +2897,7 @@ public class ADQLParser implements ADQLParserConstants {
 							gvp2 = new GeometryValue<PointFunction>(p2);
 						else
 							gvp2 = new GeometryValue<PointFunction>(col2);
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createDistance(gvp1, gvp2);
 						break;
 					default:
@@ -2755,6 +2911,7 @@ public class ADQLParser implements ADQLParserConstants {
 						throw generateParseException(ex);
 				}
 			}
+			gf.setPosition(new TextPosition(fct, end));
 			{
 				if (true)
 					return gf;
@@ -2796,6 +2953,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public GeometryFunction GeometryValueFunction() throws ParseException{
 		trace_call("GeometryValueFunction");
 		try{
+			Token fct = null, end = null;
 			ADQLOperand coordSys;
 			ADQLOperand width, height;
 			ADQLOperand[] coords, tmp;
@@ -2806,7 +2964,7 @@ public class ADQLParser implements ADQLParserConstants {
 			try{
 				switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 					case BOX:
-						jj_consume_token(BOX);
+						fct = jj_consume_token(BOX);
 						jj_consume_token(LEFT_PAR);
 						coordSys = CoordinateSystem();
 						jj_consume_token(COMMA);
@@ -2815,32 +2973,32 @@ public class ADQLParser implements ADQLParserConstants {
 						width = NumericExpression();
 						jj_consume_token(COMMA);
 						height = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);
 						break;
 					case CENTROID:
-						jj_consume_token(CENTROID);
+						fct = jj_consume_token(CENTROID);
 						jj_consume_token(LEFT_PAR);
 						gvf = GeometryExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createCentroid(gvf);
 						break;
 					case CIRCLE:
-						jj_consume_token(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();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);
 						break;
 					case POINT:
 						gf = Point();
 						break;
 					case POLYGON:
-						jj_consume_token(POLYGON);
+						fct = jj_consume_token(POLYGON);
 						jj_consume_token(LEFT_PAR);
 						coordSys = CoordinateSystem();
 						vCoords = new Vector<ADQLOperand>();
@@ -2870,14 +3028,14 @@ public class ADQLParser implements ADQLParserConstants {
 							vCoords.add(tmp[0]);
 							vCoords.add(tmp[1]);
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createPolygon(coordSys, vCoords);
 						break;
 					case REGION:
-						jj_consume_token(REGION);
+						fct = jj_consume_token(REGION);
 						jj_consume_token(LEFT_PAR);
 						op = StringExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						gf = queryFactory.createRegion(op);
 						break;
 					default:
@@ -2891,6 +3049,8 @@ public class ADQLParser implements ADQLParserConstants {
 						throw generateParseException(ex);
 				}
 			}
+			if (fct != null && end != null) // = !(gf instanceof Point)
+				gf.setPosition(new TextPosition(fct, end));
 			{
 				if (true)
 					return gf;
@@ -2904,18 +3064,21 @@ public class ADQLParser implements ADQLParserConstants {
 	final public PointFunction Point() throws ParseException{
 		trace_call("Point");
 		try{
+			Token start, end;
 			ADQLOperand coordSys;
 			ADQLOperand[] coords;
-			jj_consume_token(POINT);
+			start = jj_consume_token(POINT);
 			jj_consume_token(LEFT_PAR);
 			coordSys = CoordinateSystem();
 			jj_consume_token(COMMA);
 			coords = Coordinates();
-			jj_consume_token(RIGHT_PAR);
+			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 queryFactory.createPoint(coordSys, coords[0], coords[1]);
+						return pf;
 				}
 			}catch(Exception ex){
 				{
@@ -2932,15 +3095,18 @@ public class ADQLParser implements ADQLParserConstants {
 	final public GeometryFunction ExtractCoordSys() throws ParseException{
 		trace_call("ExtractCoordSys");
 		try{
+			Token start, end;
 			GeometryValue<GeometryFunction> gvf;
-			jj_consume_token(COORDSYS);
+			start = jj_consume_token(COORDSYS);
 			jj_consume_token(LEFT_PAR);
 			gvf = GeometryExpression();
-			jj_consume_token(RIGHT_PAR);
+			end = jj_consume_token(RIGHT_PAR);
 			try{
+				GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
+				gf.setPosition(new TextPosition(start, end));
 				{
 					if (true)
-						return queryFactory.createExtractCoordSys(gvf);
+						return gf;
 				}
 			}catch(Exception ex){
 				{
@@ -3018,52 +3184,52 @@ public class ADQLParser implements ADQLParserConstants {
 	final public MathFunction MathFunction() throws ParseException{
 		trace_call("MathFunction");
 		try{
-			Token fct = null;
+			Token fct = null, end;
 			ADQLOperand param1 = null, param2 = null;
-			String integerValue = 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();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case CEILING:
 						fct = jj_consume_token(CEILING);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case DEGREES:
 						fct = jj_consume_token(DEGREES);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case EXP:
 						fct = jj_consume_token(EXP);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case FLOOR:
 						fct = jj_consume_token(FLOOR);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case LOG:
 						fct = jj_consume_token(LOG);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case LOG10:
 						fct = jj_consume_token(LOG10);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case MOD:
 						fct = jj_consume_token(MOD);
@@ -3071,12 +3237,12 @@ public class ADQLParser implements ADQLParserConstants {
 						param1 = NumericExpression();
 						jj_consume_token(COMMA);
 						param2 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case PI:
 						fct = jj_consume_token(PI);
 						jj_consume_token(LEFT_PAR);
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case POWER:
 						fct = jj_consume_token(POWER);
@@ -3084,13 +3250,13 @@ public class ADQLParser implements ADQLParserConstants {
 						param1 = NumericExpression();
 						jj_consume_token(COMMA);
 						param2 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case RADIANS:
 						fct = jj_consume_token(RADIANS);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case RAND:
 						fct = jj_consume_token(RAND);
@@ -3145,7 +3311,7 @@ public class ADQLParser implements ADQLParserConstants {
 								jj_la1[90] = jj_gen;
 								;
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case ROUND:
 						fct = jj_consume_token(ROUND);
@@ -3154,20 +3320,19 @@ public class ADQLParser implements ADQLParserConstants {
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case COMMA:
 								jj_consume_token(COMMA);
-								integerValue = SignedInteger();
-								param2 = queryFactory.createNumericConstant(integerValue);
+								param2 = SignedInteger();
 								break;
 							default:
 								jj_la1[91] = jj_gen;
 								;
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case SQRT:
 						fct = jj_consume_token(SQRT);
 						jj_consume_token(LEFT_PAR);
 						param1 = NumericExpression();
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					case TRUNCATE:
 						fct = jj_consume_token(TRUNCATE);
@@ -3176,14 +3341,13 @@ public class ADQLParser implements ADQLParserConstants {
 						switch((jj_ntk == -1) ? jj_ntk() : jj_ntk){
 							case COMMA:
 								jj_consume_token(COMMA);
-								integerValue = SignedInteger();
-								param2 = queryFactory.createNumericConstant(integerValue);
+								param2 = SignedInteger();
 								break;
 							default:
 								jj_la1[92] = jj_gen;
 								;
 						}
-						jj_consume_token(RIGHT_PAR);
+						end = jj_consume_token(RIGHT_PAR);
 						break;
 					default:
 						jj_la1[93] = jj_gen;
@@ -3191,8 +3355,12 @@ public class ADQLParser implements ADQLParserConstants {
 						throw new ParseException();
 				}
 				if (param1 != null){
-					if (true)
-						return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+					MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+					mf.setPosition(new TextPosition(fct, end));
+					{
+						if (true)
+							return mf;
+					}
 				}else{
 					if (true)
 						return null;
@@ -3212,26 +3380,26 @@ public class ADQLParser implements ADQLParserConstants {
 	final public MathFunction TrigFunction() throws ParseException{
 		trace_call("TrigFunction");
 		try{
-			Token fct = null;
+			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();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case ASIN:
 					fct = jj_consume_token(ASIN);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case ATAN:
 					fct = jj_consume_token(ATAN);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case ATAN2:
 					fct = jj_consume_token(ATAN2);
@@ -3239,31 +3407,31 @@ public class ADQLParser implements ADQLParserConstants {
 					param1 = NumericExpression();
 					jj_consume_token(COMMA);
 					param2 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case COS:
 					fct = jj_consume_token(COS);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case COT:
 					fct = jj_consume_token(COT);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case SIN:
 					fct = jj_consume_token(SIN);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				case TAN:
 					fct = jj_consume_token(TAN);
 					jj_consume_token(LEFT_PAR);
 					param1 = NumericExpression();
-					jj_consume_token(RIGHT_PAR);
+					end = jj_consume_token(RIGHT_PAR);
 					break;
 				default:
 					jj_la1[94] = jj_gen;
@@ -3272,8 +3440,12 @@ public class ADQLParser implements ADQLParserConstants {
 			}
 			try{
 				if (param1 != null){
-					if (true)
-						return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+					MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+					mf.setPosition(new TextPosition(fct, end));
+					{
+						if (true)
+							return mf;
+					}
 				}else{
 					if (true)
 						return null;
@@ -3294,7 +3466,7 @@ public class ADQLParser implements ADQLParserConstants {
 	final public UserDefinedFunction UserDefinedFunction() throws ParseException{
 		trace_call("UserDefinedFunction");
 		try{
-			Token fct;
+			Token fct, end;
 			Vector<ADQLOperand> params = new Vector<ADQLOperand>();
 			ADQLOperand op;
 			fct = jj_consume_token(REGULAR_IDENTIFIER);
@@ -3370,15 +3542,17 @@ public class ADQLParser implements ADQLParserConstants {
 					jj_la1[96] = jj_gen;
 					;
 			}
-			jj_consume_token(RIGHT_PAR);
+			end = jj_consume_token(RIGHT_PAR);
 			//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{
 				ADQLOperand[] parameters = new ADQLOperand[params.size()];
 				for(int i = 0; i < params.size(); i++)
 					parameters[i] = params.get(i);
+				UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
+				udf.setPosition(new TextPosition(fct, end));
 				{
 					if (true)
-						return queryFactory.createUserDefinedFunction(fct.image, parameters);
+						return udf;
 				}
 			}catch(UnsupportedOperationException uoe){
 				{
@@ -3563,37 +3737,111 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_113(){
-		if (jj_3R_101())
+	private boolean jj_3R_68(){
+		if (jj_3R_23())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_152(){
+	private boolean jj_3R_67(){
+		if (jj_3R_116())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_66(){
+		if (jj_3R_115())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_124(){
+		if (jj_scan_token(BOX))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_157())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_109(){
+		if (jj_scan_token(FULL))
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_122(){
+		if (jj_3R_144())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_49(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_164())
+		if (jj_3R_66()){
 			jj_scanpos = xsp;
-		if (jj_3R_165())
-			return true;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_166()){
+			if (jj_3R_67()){
 				jj_scanpos = xsp;
-				break;
+				if (jj_3R_68()){
+					jj_scanpos = xsp;
+					if (jj_3R_69()){
+						jj_scanpos = xsp;
+						if (jj_3R_70())
+							return true;
+					}
+				}
 			}
 		}
 		return false;
 	}
 
-	private boolean jj_3R_122(){
-		if (jj_3R_144())
+	private boolean jj_3R_121(){
+		if (jj_3R_143())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_121(){
-		if (jj_3R_143())
+	private boolean jj_3R_101(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_124()){
+			jj_scanpos = xsp;
+			if (jj_3R_125()){
+				jj_scanpos = xsp;
+				if (jj_3R_126()){
+					jj_scanpos = xsp;
+					if (jj_3R_127()){
+						jj_scanpos = xsp;
+						if (jj_3R_128()){
+							jj_scanpos = xsp;
+							if (jj_3R_129())
+								return true;
+						}
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	private boolean jj_3R_190(){
+		if (jj_3R_23())
 			return true;
 		return false;
 	}
@@ -3610,58 +3858,39 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_112(){
-		if (jj_3R_23())
+	private boolean jj_3R_185(){
+		if (jj_3R_147())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_162(){
-		if (jj_3R_49())
+	private boolean jj_3R_183(){
+		if (jj_3R_147())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_64(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_112()){
-			jj_scanpos = xsp;
-			if (jj_3R_113())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_32(){
-		if (jj_3R_49())
+	private boolean jj_3R_149(){
+		if (jj_3R_41())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3_8(){
-		if (jj_3R_20())
+	private boolean jj_3R_188(){
+		if (jj_3R_23())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_31(){
-		if (jj_3R_48())
+	private boolean jj_3R_189(){
+		if (jj_3R_147())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_18(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_31()){
-			jj_scanpos = xsp;
-			if (jj_3_8()){
-				jj_scanpos = xsp;
-				if (jj_3R_32())
-					return true;
-			}
-		}
+	private boolean jj_3R_105(){
+		if (jj_scan_token(RIGHT))
+			return true;
 		return false;
 	}
 
@@ -3686,754 +3915,748 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_65(){
-		if (jj_3R_41())
-			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_114()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_182(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_191())
+	private boolean jj_3R_157(){
+		if (jj_3R_24())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_43(){
-		if (jj_scan_token(CONCAT))
-			return true;
-		if (jj_3R_18())
-			return true;
+	private boolean jj_3R_192(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(8)){
+			jj_scanpos = xsp;
+			if (jj_scan_token(9))
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_181(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_191())
+	private boolean jj_3R_191(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_192())
+			jj_scanpos = xsp;
+		if (jj_scan_token(UNSIGNED_INTEGER))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_106(){
-		if (jj_scan_token(FULL))
+	private boolean jj_3R_187(){
+		if (jj_3R_147())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_170(){
-		if (jj_scan_token(MINUS))
+	private boolean jj_3R_108(){
+		if (jj_scan_token(RIGHT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_24(){
-		if (jj_3R_18())
+	private boolean jj_3R_98(){
+		if (jj_scan_token(DISTANCE))
 			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_43()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3_7(){
-		if (jj_3R_19())
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_161(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(8)){
+		if (jj_3R_187()){
 			jj_scanpos = xsp;
-			if (jj_3R_170())
+			if (jj_3R_188())
 				return true;
 		}
-		return false;
-	}
-
-	private boolean jj_3R_160(){
-		Token xsp;
+		if (jj_scan_token(COMMA))
+			return true;
 		xsp = jj_scanpos;
-		if (jj_scan_token(10)){
+		if (jj_3R_189()){
 			jj_scanpos = xsp;
-			if (jj_scan_token(11))
+			if (jj_3R_190())
 				return true;
 		}
-		if (jj_3R_130())
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_148(){
+	private boolean jj_3R_97(){
+		if (jj_scan_token(COORD2))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_161())
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_3_7()){
+		if (jj_3R_185()){
 			jj_scanpos = xsp;
-			if (jj_3R_162())
+			if (jj_3R_186())
 				return true;
 		}
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_20(){
-		if (jj_scan_token(REGULAR_IDENTIFIER))
+	private boolean jj_3R_96(){
+		if (jj_scan_token(COORD1))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_65())
+		if (jj_3R_183()){
 			jj_scanpos = xsp;
+			if (jj_3R_184())
+				return true;
+		}
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_109(){
-		if (jj_scan_token(FULL))
+	private boolean jj_3R_95(){
+		if (jj_scan_token(AREA))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_64())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_180(){
-		if (jj_3R_102())
+	private boolean jj_3R_179(){
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_14())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_145(){
+	private boolean jj_3R_94(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(8)){
+		if (jj_scan_token(58)){
 			jj_scanpos = xsp;
-			if (jj_scan_token(9))
+			if (jj_scan_token(59))
 				return true;
 		}
-		if (jj_3R_102())
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_93(){
-		if (jj_scan_token(TAN))
+		if (jj_3R_64())
 			return true;
-		if (jj_scan_token(LEFT_PAR))
+		if (jj_scan_token(COMMA))
 			return true;
-		if (jj_3R_102())
+		if (jj_3R_64())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_92(){
-		if (jj_scan_token(SIN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_104(){
+		if (jj_scan_token(LEFT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_130(){
-		if (jj_3R_148())
-			return true;
+	private boolean jj_3R_115(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_160())
+		if (jj_scan_token(99)){
 			jj_scanpos = xsp;
+			if (jj_scan_token(100)){
+				jj_scanpos = xsp;
+				if (jj_scan_token(101))
+					return true;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_91(){
-		if (jj_scan_token(COT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
+	private boolean jj_3R_61(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_104()){
+			jj_scanpos = xsp;
+			if (jj_3R_105()){
+				jj_scanpos = xsp;
+				if (jj_3R_106())
+					return true;
+			}
+		}
+		xsp = jj_scanpos;
+		if (jj_scan_token(25))
+			jj_scanpos = xsp;
+		return false;
+	}
+
+	private boolean jj_3R_45(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(24)){
+			jj_scanpos = xsp;
+			if (jj_3R_61())
+				return true;
+		}
+		return false;
+	}
+
+	private boolean jj_3R_52(){
+		Token xsp;
+		xsp = jj_scanpos;
+		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_146(){
+		if (jj_scan_token(COMMA))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_41())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_90(){
-		if (jj_scan_token(COS))
+	private boolean jj_3R_178(){
+		if (jj_scan_token(USING))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_102())
+		if (jj_3R_14())
 			return true;
+		Token xsp;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_179()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_89(){
-		if (jj_scan_token(ATAN2))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
+	private boolean jj_3R_133(){
+		if (jj_scan_token(STRING_LITERAL))
 			return true;
+		return false;
+	}
+
+	private boolean jj_3R_158(){
 		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(COMMA))
 			return true;
 		if (jj_3R_102())
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
 		return false;
 	}
 
-	private boolean jj_3R_88(){
-		if (jj_scan_token(ATAN))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_105(){
-		if (jj_scan_token(RIGHT))
+	private boolean jj_3R_116(){
+		Token xsp;
+		if (jj_3R_133())
 			return true;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_133()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_87(){
-		if (jj_scan_token(ASIN))
-			return true;
+	private boolean jj_3R_135(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(47)){
+			jj_scanpos = xsp;
+			if (jj_scan_token(48)){
+				jj_scanpos = xsp;
+				if (jj_scan_token(49)){
+					jj_scanpos = xsp;
+					if (jj_scan_token(50))
+						return true;
+				}
+			}
+		}
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_102())
+		xsp = jj_scanpos;
+		if (jj_scan_token(19))
+			jj_scanpos = xsp;
+		if (jj_3R_41())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_86(){
-		if (jj_scan_token(ACOS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_107(){
+		if (jj_scan_token(LEFT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_51(){
+	private boolean jj_3R_62(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_86()){
+		if (jj_3R_107()){
 			jj_scanpos = xsp;
-			if (jj_3R_87()){
+			if (jj_3R_108()){
 				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())
-										return true;
-								}
-							}
-						}
-					}
-				}
+				if (jj_3R_109())
+					return true;
 			}
 		}
+		xsp = jj_scanpos;
+		if (jj_scan_token(25))
+			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3_6(){
-		if (jj_3R_18())
-			return true;
-		if (jj_scan_token(CONCAT))
+	private boolean jj_3R_177(){
+		if (jj_scan_token(ON))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3_5(){
-		if (jj_scan_token(COORDSYS))
+		if (jj_3R_152())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_85(){
-		if (jj_scan_token(TRUNCATE))
+	private boolean jj_3R_134(){
+		if (jj_scan_token(COUNT))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_102())
-			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_182())
+		if (jj_scan_token(19))
+			jj_scanpos = xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(10)){
 			jj_scanpos = xsp;
+			if (jj_3R_149())
+				return true;
+		}
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3_4(){
+	private boolean jj_3R_46(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(8)){
+		if (jj_scan_token(24)){
 			jj_scanpos = xsp;
-			if (jj_scan_token(9))
+			if (jj_3R_62())
 				return true;
 		}
 		return false;
 	}
 
-	private boolean jj_3R_84(){
-		if (jj_scan_token(SQRT))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
+	private boolean jj_3R_30(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_46())
+			jj_scanpos = xsp;
+		if (jj_scan_token(JOIN))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_47())
 			return true;
+		xsp = jj_scanpos;
+		if (jj_3R_177()){
+			jj_scanpos = xsp;
+			if (jj_3R_178())
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_83(){
-		if (jj_scan_token(ROUND))
+	private boolean jj_3R_29(){
+		if (jj_scan_token(NATURAL))
 			return true;
-		if (jj_scan_token(LEFT_PAR))
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_45())
+			jj_scanpos = xsp;
+		if (jj_scan_token(JOIN))
 			return true;
-		if (jj_3R_102())
+		if (jj_3R_47())
 			return true;
+		return false;
+	}
+
+	private boolean jj_3R_117(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_181())
+		if (jj_3R_134()){
 			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
+			if (jj_3R_135())
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_82(){
-		if (jj_scan_token(RAND))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
+	private boolean jj_3R_17(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_180())
+		if (jj_3R_29()){
 			jj_scanpos = xsp;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
+			if (jj_3R_30())
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_81(){
-		if (jj_scan_token(RADIANS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_176(){
+		if (jj_3R_17())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_102(){
-		if (jj_3R_130())
-			return true;
+	private boolean jj_3R_171(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_145())
+		if (jj_scan_token(22))
 			jj_scanpos = xsp;
-		return false;
-	}
-
-	private boolean jj_3R_80(){
-		if (jj_scan_token(POWER))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_14())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_79(){
-		if (jj_scan_token(PI))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
+	private boolean jj_3R_172(){
+		if (jj_3R_63())
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		Token xsp;
+		if (jj_3R_176())
 			return true;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_176()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_78(){
-		if (jj_scan_token(MOD))
-			return true;
+	private boolean jj_3R_111(){
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_102())
+		if (jj_3R_172())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_59(){
-		if (jj_3R_102())
+	private boolean jj_3_3(){
+		if (jj_3R_17())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_77(){
-		if (jj_scan_token(LOG10))
-			return true;
+	private boolean jj_3R_123(){
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_102())
+		if (jj_3R_41())
 			return true;
+		Token xsp;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_146()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_58(){
-		if (jj_3R_24())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_76(){
-		if (jj_scan_token(LOG))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
+	private boolean jj_3R_169(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(45)){
+			jj_scanpos = xsp;
+			if (jj_scan_token(46))
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_57(){
-		if (jj_3R_24())
+	private boolean jj_3R_47(){
+		if (jj_3R_63())
 			return true;
+		Token xsp;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3_3()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_75(){
-		if (jj_scan_token(FLOOR))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3_13(){
+		if (jj_3R_16())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_70(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_41())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_100(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(35))
+			jj_scanpos = xsp;
+		if (jj_scan_token(IN))
 			return true;
+		xsp = jj_scanpos;
+		if (jj_3_13()){
+			jj_scanpos = xsp;
+			if (jj_3R_123())
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_56(){
-		if (jj_3R_102())
+	private boolean jj_3_2(){
+		if (jj_3R_16())
+			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(22))
+			jj_scanpos = xsp;
+		if (jj_3R_14())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_74(){
-		if (jj_scan_token(EXP))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_110(){
+		if (jj_3R_103())
 			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_171())
+			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_73(){
-		if (jj_scan_token(DEGREES))
+	private boolean jj_3R_22(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(35))
+			jj_scanpos = xsp;
+		if (jj_scan_token(BETWEEN))
 			return true;
-		if (jj_scan_token(LEFT_PAR))
+		if (jj_3R_41())
 			return true;
-		if (jj_3R_102())
+		if (jj_scan_token(AND))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_41())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_69(){
-		if (jj_3R_117())
+	private boolean jj_3R_54(){
+		if (jj_3R_100())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_55(){
-		if (jj_3R_101())
+	private boolean jj_3_10(){
+		if (jj_3R_22())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_72(){
-		if (jj_scan_token(CEILING))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(RIGHT_PAR))
+	private boolean jj_3R_53(){
+		if (jj_3R_99())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_41(){
+	private boolean jj_3R_99(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_55()){
+		if (jj_scan_token(12)){
 			jj_scanpos = xsp;
-			if (jj_3R_56()){
+			if (jj_scan_token(13)){
 				jj_scanpos = xsp;
-				if (jj_3R_57()){
+				if (jj_scan_token(14)){
 					jj_scanpos = xsp;
-					if (jj_3R_58()){
+					if (jj_scan_token(15)){
 						jj_scanpos = xsp;
-						if (jj_3R_59())
-							return true;
+						if (jj_scan_token(16)){
+							jj_scanpos = xsp;
+							if (jj_scan_token(17))
+								return true;
+						}
 					}
 				}
 			}
 		}
-		return false;
-	}
-
-	private boolean jj_3R_68(){
-		if (jj_3R_23())
+		if (jj_3R_41())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_71(){
-		if (jj_scan_token(ABS))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_102())
+	private boolean jj_3_12(){
+		if (jj_3R_24())
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(35))
+			jj_scanpos = xsp;
+		if (jj_scan_token(LIKE))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_67(){
-		if (jj_3R_116())
-			return true;
+	private boolean jj_3R_63(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_110()){
+			jj_scanpos = xsp;
+			if (jj_3_2()){
+				jj_scanpos = xsp;
+				if (jj_3R_111())
+					return true;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_108(){
-		if (jj_scan_token(RIGHT))
+	private boolean jj_3R_40(){
+		if (jj_3R_41())
 			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_53()){
+			jj_scanpos = xsp;
+			if (jj_3_10()){
+				jj_scanpos = xsp;
+				if (jj_3R_54())
+					return true;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_66(){
-		if (jj_3R_115())
+	private boolean jj_3_11(){
+		if (jj_3R_23())
+			return true;
+		if (jj_scan_token(IS))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_50(){
+	private boolean jj_3R_39(){
+		if (jj_3R_24())
+			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_71()){
+		if (jj_scan_token(35))
 			jj_scanpos = xsp;
-			if (jj_3R_72()){
-				jj_scanpos = xsp;
-				if (jj_3R_73()){
-					jj_scanpos = xsp;
-					if (jj_3R_74()){
-						jj_scanpos = xsp;
-						if (jj_3R_75()){
-							jj_scanpos = xsp;
-							if (jj_3R_76()){
-								jj_scanpos = xsp;
-								if (jj_3R_77()){
-									jj_scanpos = xsp;
-									if (jj_3R_78()){
-										jj_scanpos = xsp;
-										if (jj_3R_79()){
-											jj_scanpos = xsp;
-											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()){
-															jj_scanpos = xsp;
-															if (jj_3R_84()){
-																jj_scanpos = xsp;
-																if (jj_3R_85())
-																	return true;
-															}
-														}
-													}
-												}
-											}
-										}
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_179(){
-		if (jj_scan_token(COMMA))
+		if (jj_scan_token(LIKE))
 			return true;
-		if (jj_3R_14())
+		if (jj_3R_24())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_36(){
-		if (jj_3R_20())
+	private boolean jj_3R_38(){
+		if (jj_3R_23())
+			return true;
+		if (jj_scan_token(IS))
+			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(35))
+			jj_scanpos = xsp;
+		if (jj_scan_token(NULL))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_35(){
-		if (jj_3R_52())
+	private boolean jj_3R_168(){
+		if (jj_3R_42())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_34(){
-		if (jj_3R_51())
+	private boolean jj_3R_114(){
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_41())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_49(){
+	private boolean jj_3R_155(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_66()){
+		if (jj_3R_168()){
 			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_3R_70())
-							return true;
-					}
-				}
-			}
+			if (jj_scan_token(101))
+				return true;
 		}
+		xsp = jj_scanpos;
+		if (jj_3R_169())
+			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_104(){
-		if (jj_scan_token(LEFT))
+	private boolean jj_3R_37(){
+		if (jj_scan_token(EXISTS))
+			return true;
+		if (jj_3R_16())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_33(){
-		if (jj_3R_50())
+	private boolean jj_3R_167(){
+		if (jj_3R_42())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_61(){
+	private boolean jj_3R_153(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_104()){
+		if (jj_3R_167()){
 			jj_scanpos = xsp;
-			if (jj_3R_105()){
-				jj_scanpos = xsp;
-				if (jj_3R_106())
-					return true;
-			}
+			if (jj_scan_token(101))
+				return true;
 		}
-		xsp = jj_scanpos;
-		if (jj_scan_token(25))
-			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_19(){
+	private boolean jj_3R_21(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_33()){
+		if (jj_3R_37()){
 			jj_scanpos = xsp;
-			if (jj_3R_34()){
+			if (jj_3R_38()){
 				jj_scanpos = xsp;
-				if (jj_3R_35()){
+				if (jj_3R_39()){
 					jj_scanpos = xsp;
-					if (jj_3R_36())
+					if (jj_3R_40())
 						return true;
 				}
 			}
@@ -4441,176 +4664,204 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_192(){
+	private boolean jj_3R_60(){
+		if (jj_scan_token(DOT))
+			return true;
+		if (jj_3R_103())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3_9(){
+		if (jj_3R_21())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_23(){
+		if (jj_3R_42())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_174(){
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_152())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_173(){
+		if (jj_3R_21())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_165(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(8)){
+		if (jj_3R_173()){
 			jj_scanpos = xsp;
-			if (jj_scan_token(9))
+			if (jj_3R_174())
 				return true;
 		}
 		return false;
 	}
 
-	private boolean jj_3R_191(){
+	private boolean jj_3R_42(){
+		if (jj_3R_14())
+			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_192())
+		if (jj_3R_60())
 			jj_scanpos = xsp;
-		if (jj_scan_token(UNSIGNED_INTEGER))
-			return true;
 		return false;
 	}
 
-	private boolean jj_3R_45(){
+	private boolean jj_3R_65(){
+		if (jj_3R_41())
+			return true;
 		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(24)){
-			jj_scanpos = xsp;
-			if (jj_3R_61())
-				return true;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_114()){
+				jj_scanpos = xsp;
+				break;
+			}
 		}
 		return false;
 	}
 
-	private boolean jj_3R_48(){
-		if (jj_scan_token(COORDSYS))
+	private boolean jj_3R_132(){
+		if (jj_scan_token(DOT))
 			return true;
-		if (jj_scan_token(LEFT_PAR))
+		if (jj_3R_14())
 			return true;
-		if (jj_3R_64())
+		return false;
+	}
+
+	private boolean jj_3R_131(){
+		if (jj_scan_token(DOT))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_14())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_159(){
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_158())
+	private boolean jj_3R_175(){
+		if (jj_scan_token(NOT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_115(){
+	private boolean jj_3R_166(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(99)){
+		if (jj_scan_token(33)){
 			jj_scanpos = xsp;
-			if (jj_scan_token(100)){
-				jj_scanpos = xsp;
-				if (jj_scan_token(101))
-					return true;
-			}
+			if (jj_scan_token(34))
+				return true;
 		}
+		xsp = jj_scanpos;
+		if (jj_3R_175())
+			jj_scanpos = xsp;
+		if (jj_3R_165())
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_186(){
-		if (jj_3R_23())
+	private boolean jj_3R_182(){
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_191())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_178(){
-		if (jj_scan_token(USING))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
+	private boolean jj_3R_103(){
 		if (jj_3R_14())
 			return true;
 		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_179()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		if (jj_scan_token(RIGHT_PAR))
+		xsp = jj_scanpos;
+		if (jj_3R_131())
+			jj_scanpos = xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_132())
+			jj_scanpos = xsp;
+		return false;
+	}
+
+	private boolean jj_3R_181(){
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_191())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_107(){
-		if (jj_scan_token(LEFT))
+	private boolean jj_3R_26(){
+		if (jj_scan_token(DELIMITED_IDENTIFIER))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_184(){
-		if (jj_3R_23())
+	private boolean jj_3R_25(){
+		if (jj_scan_token(REGULAR_IDENTIFIER))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_62(){
+	private boolean jj_3R_14(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_107()){
+		if (jj_3R_25()){
 			jj_scanpos = xsp;
-			if (jj_3R_108()){
-				jj_scanpos = xsp;
-				if (jj_3R_109())
-					return true;
-			}
+			if (jj_3R_26())
+				return true;
 		}
-		xsp = jj_scanpos;
-		if (jj_scan_token(25))
-			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_177(){
-		if (jj_scan_token(ON))
-			return true;
-		if (jj_3R_152())
+	private boolean jj_3R_164(){
+		if (jj_scan_token(NOT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_129(){
-		if (jj_scan_token(REGION))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_24())
+	private boolean jj_3R_156(){
+		if (jj_scan_token(COMMA))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_3R_155())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_147(){
-		if (jj_scan_token(POINT))
+	private boolean jj_3R_20(){
+		if (jj_scan_token(REGULAR_IDENTIFIER))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_157())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_158())
-			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_65())
+			jj_scanpos = xsp;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_133(){
-		if (jj_scan_token(STRING_LITERAL))
+	private boolean jj_3R_144(){
+		if (jj_scan_token(ORDER_BY))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_116(){
-		Token xsp;
-		if (jj_3R_133())
+		if (jj_3R_155())
 			return true;
+		Token xsp;
 		while(true){
 			xsp = jj_scanpos;
-			if (jj_3R_133()){
+			if (jj_3R_156()){
 				jj_scanpos = xsp;
 				break;
 			}
@@ -4618,109 +4869,95 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_46(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(24)){
-			jj_scanpos = xsp;
-			if (jj_3R_62())
-				return true;
-		}
+	private boolean jj_3R_113(){
+		if (jj_3R_101())
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_30(){
+	private boolean jj_3R_152(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_46())
+		if (jj_3R_164())
 			jj_scanpos = xsp;
-		if (jj_scan_token(JOIN))
-			return true;
-		if (jj_3R_47())
+		if (jj_3R_165())
 			return true;
-		xsp = jj_scanpos;
-		if (jj_3R_177()){
-			jj_scanpos = xsp;
-			if (jj_3R_178())
-				return true;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_166()){
+				jj_scanpos = xsp;
+				break;
+			}
 		}
 		return false;
 	}
 
-	private boolean jj_3R_128(){
-		if (jj_scan_token(POLYGON))
-			return true;
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_157())
+	private boolean jj_3R_180(){
+		if (jj_3R_102())
 			return true;
-		if (jj_scan_token(COMMA))
+		return false;
+	}
+
+	private boolean jj_3R_143(){
+		if (jj_scan_token(HAVING))
 			return true;
-		if (jj_3R_158())
+		if (jj_3R_152())
 			return true;
+		return false;
+	}
+
+	private boolean jj_3R_154(){
 		if (jj_scan_token(COMMA))
 			return true;
-		if (jj_3R_158())
+		if (jj_3R_153())
 			return true;
-		if (jj_scan_token(COMMA))
+		return false;
+	}
+
+	private boolean jj_3R_142(){
+		if (jj_scan_token(GROUP_BY))
 			return true;
-		if (jj_3R_158())
+		if (jj_3R_153())
 			return true;
 		Token xsp;
 		while(true){
 			xsp = jj_scanpos;
-			if (jj_3R_159()){
+			if (jj_3R_154()){
 				jj_scanpos = xsp;
 				break;
 			}
 		}
-		if (jj_scan_token(RIGHT_PAR))
-			return true;
 		return false;
 	}
 
-	private boolean jj_3R_29(){
-		if (jj_scan_token(NATURAL))
-			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_45())
-			jj_scanpos = xsp;
-		if (jj_scan_token(JOIN))
+	private boolean jj_3R_93(){
+		if (jj_scan_token(TAN))
 			return true;
-		if (jj_3R_47())
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_127(){
-		if (jj_3R_147())
+		if (jj_3R_102())
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_171(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(22))
-			jj_scanpos = xsp;
-		if (jj_3R_14())
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_126(){
-		if (jj_scan_token(CIRCLE))
+	private boolean jj_3R_92(){
+		if (jj_scan_token(SIN))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_157())
+		if (jj_3R_102())
 			return true;
-		if (jj_scan_token(COMMA))
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
-		if (jj_3R_158())
+		return false;
+	}
+
+	private boolean jj_3R_91(){
+		if (jj_scan_token(COT))
 			return true;
-		if (jj_scan_token(COMMA))
+		if (jj_scan_token(LEFT_PAR))
 			return true;
 		if (jj_3R_102())
 			return true;
@@ -4729,42 +4966,40 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_125(){
-		if (jj_scan_token(CENTROID))
+	private boolean jj_3R_112(){
+		if (jj_3R_23())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_90(){
+		if (jj_scan_token(COS))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_64())
+		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_169(){
+	private boolean jj_3R_64(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(45)){
+		if (jj_3R_112()){
 			jj_scanpos = xsp;
-			if (jj_scan_token(46))
+			if (jj_3R_113())
 				return true;
 		}
 		return false;
 	}
 
-	private boolean jj_3R_124(){
-		if (jj_scan_token(BOX))
+	private boolean jj_3R_89(){
+		if (jj_scan_token(ATAN2))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_157())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
-		if (jj_3R_158())
-			return true;
-		if (jj_scan_token(COMMA))
-			return true;
 		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(COMMA))
@@ -4776,76 +5011,83 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_17(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_29()){
-			jj_scanpos = xsp;
-			if (jj_3R_30())
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_176(){
-		if (jj_3R_17())
+	private boolean jj_3R_88(){
+		if (jj_scan_token(ATAN))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_111(){
+	private boolean jj_3R_87(){
+		if (jj_scan_token(ASIN))
+			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_172())
+		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_172(){
-		if (jj_3R_63())
+	private boolean jj_3R_32(){
+		if (jj_3R_49())
 			return true;
-		Token xsp;
-		if (jj_3R_176())
+		return false;
+	}
+
+	private boolean jj_3R_141(){
+		if (jj_scan_token(WHERE))
+			return true;
+		if (jj_3R_152())
 			return true;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_176()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
 		return false;
 	}
 
-	private boolean jj_3R_190(){
-		if (jj_3R_23())
+	private boolean jj_3_8(){
+		if (jj_3R_20())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3_3(){
-		if (jj_3R_17())
+	private boolean jj_3R_86(){
+		if (jj_scan_token(ACOS))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_101(){
+	private boolean jj_3R_51(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_124()){
+		if (jj_3R_86()){
 			jj_scanpos = xsp;
-			if (jj_3R_125()){
+			if (jj_3R_87()){
 				jj_scanpos = xsp;
-				if (jj_3R_126()){
+				if (jj_3R_88()){
 					jj_scanpos = xsp;
-					if (jj_3R_127()){
+					if (jj_3R_89()){
 						jj_scanpos = xsp;
-						if (jj_3R_128()){
+						if (jj_3R_90()){
 							jj_scanpos = xsp;
-							if (jj_3R_129())
-								return true;
+							if (jj_3R_91()){
+								jj_scanpos = xsp;
+								if (jj_3R_92()){
+									jj_scanpos = xsp;
+									if (jj_3R_93())
+										return true;
+								}
+							}
 						}
 					}
 				}
@@ -4854,859 +5096,791 @@ public class ADQLParser implements ADQLParserConstants {
 		return false;
 	}
 
-	private boolean jj_3R_149(){
-		if (jj_3R_41())
+	private boolean jj_3R_31(){
+		if (jj_3R_48())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_110(){
-		if (jj_3R_103())
-			return true;
+	private boolean jj_3R_18(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_171())
+		if (jj_3R_31()){
 			jj_scanpos = xsp;
+			if (jj_3_8()){
+				jj_scanpos = xsp;
+				if (jj_3R_32())
+					return true;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_47(){
-		if (jj_3R_63())
+	private boolean jj_3R_162(){
+		if (jj_3R_49())
 			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3_3()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
 		return false;
 	}
 
-	private boolean jj_3R_188(){
-		if (jj_3R_23())
+	private boolean jj_3R_163(){
+		if (jj_scan_token(AS))
+			return true;
+		if (jj_3R_14())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_185(){
-		if (jj_3R_147())
+	private boolean jj_3R_140(){
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_47())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3_2(){
-		if (jj_3R_16())
+	private boolean jj_3R_85(){
+		if (jj_scan_token(TRUNCATE))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
 			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(22))
+		if (jj_3R_182())
 			jj_scanpos = xsp;
-		if (jj_3R_14())
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_183(){
-		if (jj_3R_147())
+	private boolean jj_3R_84(){
+		if (jj_scan_token(SQRT))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_189(){
-		if (jj_3R_147())
+	private boolean jj_3R_83(){
+		if (jj_scan_token(ROUND))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_181())
+			jj_scanpos = xsp;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_157(){
-		if (jj_3R_24())
+	private boolean jj_3R_82(){
+		if (jj_scan_token(RAND))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_3R_180())
+			jj_scanpos = xsp;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_187(){
-		if (jj_3R_147())
+	private boolean jj_3R_81(){
+		if (jj_scan_token(RADIANS))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_63(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_110()){
-			jj_scanpos = xsp;
-			if (jj_3_2()){
-				jj_scanpos = xsp;
-				if (jj_3R_111())
-					return true;
-			}
-		}
+	private boolean jj_3R_80(){
+		if (jj_scan_token(POWER))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_98(){
-		if (jj_scan_token(DISTANCE))
+	private boolean jj_3R_79(){
+		if (jj_scan_token(PI))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_187()){
-			jj_scanpos = xsp;
-			if (jj_3R_188())
-				return true;
-		}
-		if (jj_scan_token(COMMA))
-			return true;
-		xsp = jj_scanpos;
-		if (jj_3R_189()){
-			jj_scanpos = xsp;
-			if (jj_3R_190())
-				return true;
-		}
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_97(){
-		if (jj_scan_token(COORD2))
+	private boolean jj_3R_78(){
+		if (jj_scan_token(MOD))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_185()){
-			jj_scanpos = xsp;
-			if (jj_3R_186())
-				return true;
-		}
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_102())
+			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_96(){
-		if (jj_scan_token(COORD1))
+	private boolean jj_3R_77(){
+		if (jj_scan_token(LOG10))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_183()){
-			jj_scanpos = xsp;
-			if (jj_3R_184())
-				return true;
-		}
+		if (jj_3R_102())
+			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_95(){
-		if (jj_scan_token(AREA))
+	private boolean jj_3R_76(){
+		if (jj_scan_token(LOG))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_64())
+		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_168(){
-		if (jj_3R_42())
+	private boolean jj_3R_118(){
+		if (jj_scan_token(FROM))
+			return true;
+		if (jj_3R_47())
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_155(){
 		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_168()){
-			jj_scanpos = xsp;
-			if (jj_scan_token(101))
-				return true;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_140()){
+				jj_scanpos = xsp;
+				break;
+			}
 		}
-		xsp = jj_scanpos;
-		if (jj_3R_169())
-			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_94(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(58)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(59))
-				return true;
-		}
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_64())
+	private boolean jj_3R_75(){
+		if (jj_scan_token(FLOOR))
 			return true;
-		if (jj_scan_token(COMMA))
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		if (jj_3R_64())
+		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_146(){
-		if (jj_scan_token(COMMA))
+	private boolean jj_3R_74(){
+		if (jj_scan_token(EXP))
 			return true;
-		if (jj_3R_41())
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_167(){
-		if (jj_3R_42())
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_153(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_167()){
-			jj_scanpos = xsp;
-			if (jj_scan_token(101))
-				return true;
-		}
-		return false;
-	}
-
-	private boolean jj_3R_60(){
-		if (jj_scan_token(DOT))
+	private boolean jj_3R_73(){
+		if (jj_scan_token(DEGREES))
 			return true;
-		if (jj_3R_103())
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_52(){
-		Token xsp;
-		xsp = jj_scanpos;
-		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_135(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(47)){
-			jj_scanpos = xsp;
-			if (jj_scan_token(48)){
-				jj_scanpos = xsp;
-				if (jj_scan_token(49)){
-					jj_scanpos = xsp;
-					if (jj_scan_token(50))
-						return true;
-				}
-			}
-		}
+	private boolean jj_3R_72(){
+		if (jj_scan_token(CEILING))
+			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		xsp = jj_scanpos;
-		if (jj_scan_token(19))
-			jj_scanpos = xsp;
-		if (jj_3R_41())
+		if (jj_3R_102())
 			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_158(){
-		if (jj_3R_102())
-			return true;
-		if (jj_scan_token(COMMA))
+	private boolean jj_3R_27(){
+		if (jj_3R_14())
 			return true;
-		if (jj_3R_102())
+		if (jj_scan_token(DOT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_23(){
-		if (jj_3R_42())
+	private boolean jj_3R_43(){
+		if (jj_scan_token(CONCAT))
+			return true;
+		if (jj_3R_18())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_134(){
-		if (jj_scan_token(COUNT))
+	private boolean jj_3R_71(){
+		if (jj_scan_token(ABS))
 			return true;
 		if (jj_scan_token(LEFT_PAR))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(19))
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(10)){
-			jj_scanpos = xsp;
-			if (jj_3R_149())
-				return true;
-		}
+		if (jj_3R_102())
+			return true;
 		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_42(){
-		if (jj_3R_14())
+	private boolean jj_3R_151(){
+		if (jj_3R_41())
 			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_60())
+		if (jj_3R_163())
 			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_132(){
-		if (jj_scan_token(DOT))
-			return true;
+	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_27())
+			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_131(){
-		if (jj_scan_token(DOT))
-			return true;
-		if (jj_3R_14())
+	private boolean jj_3R_24(){
+		if (jj_3R_18())
 			return true;
+		Token xsp;
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_43()){
+				jj_scanpos = xsp;
+				break;
+			}
+		}
 		return false;
 	}
 
-	private boolean jj_3R_117(){
+	private boolean jj_3R_50(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_134()){
+		if (jj_3R_71()){
 			jj_scanpos = xsp;
-			if (jj_3R_135())
-				return true;
+			if (jj_3R_72()){
+				jj_scanpos = xsp;
+				if (jj_3R_73()){
+					jj_scanpos = xsp;
+					if (jj_3R_74()){
+						jj_scanpos = xsp;
+						if (jj_3R_75()){
+							jj_scanpos = xsp;
+							if (jj_3R_76()){
+								jj_scanpos = xsp;
+								if (jj_3R_77()){
+									jj_scanpos = xsp;
+									if (jj_3R_78()){
+										jj_scanpos = xsp;
+										if (jj_3R_79()){
+											jj_scanpos = xsp;
+											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()){
+															jj_scanpos = xsp;
+															if (jj_3R_84()){
+																jj_scanpos = xsp;
+																if (jj_3R_85())
+																	return true;
+															}
+														}
+													}
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
 		}
 		return false;
 	}
 
-	private boolean jj_3R_103(){
-		if (jj_3R_14())
+	private boolean jj_3R_170(){
+		if (jj_scan_token(MINUS))
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_36(){
+		if (jj_3R_20())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_35(){
+		if (jj_3R_52())
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_131())
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_132())
-			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_26(){
-		if (jj_scan_token(DELIMITED_IDENTIFIER))
+	private boolean jj_3R_34(){
+		if (jj_3R_51())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_25(){
-		if (jj_scan_token(REGULAR_IDENTIFIER))
+	private boolean jj_3R_33(){
+		if (jj_3R_50())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_123(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_41())
-			return true;
+	private boolean jj_3R_19(){
 		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_146()){
+		xsp = jj_scanpos;
+		if (jj_3R_33()){
+			jj_scanpos = xsp;
+			if (jj_3R_34()){
 				jj_scanpos = xsp;
-				break;
+				if (jj_3R_35()){
+					jj_scanpos = xsp;
+					if (jj_3R_36())
+						return true;
+				}
 			}
 		}
-		if (jj_scan_token(RIGHT_PAR))
+		return false;
+	}
+
+	private boolean jj_3_7(){
+		if (jj_3R_19())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_14(){
+	private boolean jj_3R_161(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_25()){
+		if (jj_scan_token(8)){
 			jj_scanpos = xsp;
-			if (jj_3R_26())
+			if (jj_3R_170())
 				return true;
 		}
 		return false;
 	}
 
-	private boolean jj_3_13(){
-		if (jj_3R_16())
+	private boolean jj_3R_160(){
+		Token xsp;
+		xsp = jj_scanpos;
+		if (jj_scan_token(10)){
+			jj_scanpos = xsp;
+			if (jj_scan_token(11))
+				return true;
+		}
+		if (jj_3R_130())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_100(){
+	private boolean jj_3R_148(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(35))
+		if (jj_3R_161())
 			jj_scanpos = xsp;
-		if (jj_scan_token(IN))
-			return true;
 		xsp = jj_scanpos;
-		if (jj_3_13()){
+		if (jj_3_7()){
 			jj_scanpos = xsp;
-			if (jj_3R_123())
+			if (jj_3R_162())
 				return true;
 		}
 		return false;
 	}
 
-	private boolean jj_3R_156(){
-		if (jj_scan_token(COMMA))
+	private boolean jj_3R_48(){
+		if (jj_scan_token(COORDSYS))
 			return true;
-		if (jj_3R_155())
+		if (jj_scan_token(LEFT_PAR))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_144(){
-		if (jj_scan_token(ORDER_BY))
+		if (jj_3R_64())
 			return true;
-		if (jj_3R_155())
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_156()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
 		return false;
 	}
 
-	private boolean jj_3R_143(){
-		if (jj_scan_token(HAVING))
-			return true;
-		if (jj_3R_152())
+	private boolean jj_3R_150(){
+		if (jj_scan_token(ASTERISK))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_154(){
-		if (jj_scan_token(COMMA))
+	private boolean jj_3_1(){
+		if (jj_3R_14())
 			return true;
-		if (jj_3R_153())
+		if (jj_scan_token(DOT))
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_22(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(35))
+		if (jj_3R_15())
 			jj_scanpos = xsp;
-		if (jj_scan_token(BETWEEN))
-			return true;
-		if (jj_3R_41())
-			return true;
-		if (jj_scan_token(AND))
-			return true;
-		if (jj_3R_41())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_163(){
-		if (jj_scan_token(AS))
-			return true;
-		if (jj_3R_14())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_142(){
-		if (jj_scan_token(GROUP_BY))
-			return true;
-		if (jj_3R_153())
-			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_154()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
-		return false;
-	}
-
-	private boolean jj_3R_54(){
-		if (jj_3R_100())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_10(){
-		if (jj_3R_22())
+		if (jj_scan_token(ASTERISK))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_140(){
+	private boolean jj_3R_159(){
 		if (jj_scan_token(COMMA))
 			return true;
-		if (jj_3R_47())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_141(){
-		if (jj_scan_token(WHERE))
-			return true;
-		if (jj_3R_152())
+		if (jj_3R_158())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3_12(){
-		if (jj_3R_24())
-			return true;
+	private boolean jj_3R_145(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(35))
+		if (jj_scan_token(8)){
 			jj_scanpos = xsp;
-		if (jj_scan_token(LIKE))
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_53(){
-		if (jj_3R_99())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3_11(){
-		if (jj_3R_23())
-			return true;
-		if (jj_scan_token(IS))
+			if (jj_scan_token(9))
+				return true;
+		}
+		if (jj_3R_102())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_99(){
+	private boolean jj_3R_138(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(12)){
+		if (jj_3R_150()){
 			jj_scanpos = xsp;
-			if (jj_scan_token(13)){
+			if (jj_3_1()){
 				jj_scanpos = xsp;
-				if (jj_scan_token(14)){
-					jj_scanpos = xsp;
-					if (jj_scan_token(15)){
-						jj_scanpos = xsp;
-						if (jj_scan_token(16)){
-							jj_scanpos = xsp;
-							if (jj_scan_token(17))
-								return true;
-						}
-					}
-				}
+				if (jj_3R_151())
+					return true;
 			}
 		}
-		if (jj_3R_41())
-			return true;
 		return false;
 	}
 
-	private boolean jj_3R_27(){
-		if (jj_3R_14())
-			return true;
-		if (jj_scan_token(DOT))
+	private boolean jj_3R_186(){
+		if (jj_3R_23())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_118(){
-		if (jj_scan_token(FROM))
-			return true;
-		if (jj_3R_47())
+	private boolean jj_3R_184(){
+		if (jj_3R_23())
 			return true;
-		Token xsp;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_140()){
-				jj_scanpos = xsp;
-				break;
-			}
-		}
 		return false;
 	}
 
-	private boolean jj_3R_40(){
-		if (jj_3R_41())
+	private boolean jj_3R_130(){
+		if (jj_3R_148())
 			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_53()){
+		if (jj_3R_160())
 			jj_scanpos = xsp;
-			if (jj_3_10()){
-				jj_scanpos = xsp;
-				if (jj_3R_54())
-					return true;
-			}
-		}
 		return false;
 	}
 
-	private boolean jj_3R_39(){
-		if (jj_3R_24())
+	private boolean jj_3R_147(){
+		if (jj_scan_token(POINT))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_157())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_129(){
+		if (jj_scan_token(REGION))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(35))
-			jj_scanpos = xsp;
-		if (jj_scan_token(LIKE))
+		if (jj_scan_token(LEFT_PAR))
 			return true;
 		if (jj_3R_24())
 			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_38(){
-		if (jj_3R_23())
-			return true;
-		if (jj_scan_token(IS))
+	private boolean jj_3R_139(){
+		if (jj_scan_token(COMMA))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_scan_token(35))
-			jj_scanpos = xsp;
-		if (jj_scan_token(NULL))
+		if (jj_3R_138())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_37(){
-		if (jj_scan_token(EXISTS))
+	private boolean jj_3_6(){
+		if (jj_3R_18())
 			return true;
-		if (jj_3R_16())
+		if (jj_scan_token(CONCAT))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_151(){
-		if (jj_3R_41())
+	private boolean jj_3_5(){
+		if (jj_scan_token(COORDSYS))
 			return true;
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_163())
-			jj_scanpos = xsp;
 		return false;
 	}
 
-	private boolean jj_3R_15(){
-		if (jj_3R_14())
-			return true;
-		if (jj_scan_token(DOT))
-			return true;
+	private boolean jj_3_4(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_27())
+		if (jj_scan_token(8)){
 			jj_scanpos = xsp;
+			if (jj_scan_token(9))
+				return true;
+		}
 		return false;
 	}
 
-	private boolean jj_3R_21(){
+	private boolean jj_3R_128(){
+		if (jj_scan_token(POLYGON))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_157())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
 		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_37()){
-			jj_scanpos = xsp;
-			if (jj_3R_38()){
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_159()){
 				jj_scanpos = xsp;
-				if (jj_3R_39()){
-					jj_scanpos = xsp;
-					if (jj_3R_40())
-						return true;
-				}
+				break;
 			}
 		}
-		return false;
-	}
-
-	private boolean jj_3_9(){
-		if (jj_3R_21())
-			return true;
-		return false;
-	}
-
-	private boolean jj_3R_150(){
-		if (jj_scan_token(ASTERISK))
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_174(){
-		if (jj_scan_token(LEFT_PAR))
-			return true;
-		if (jj_3R_152())
+	private boolean jj_3R_137(){
+		if (jj_scan_token(TOP))
 			return true;
-		if (jj_scan_token(RIGHT_PAR))
+		if (jj_scan_token(UNSIGNED_INTEGER))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_173(){
-		if (jj_3R_21())
+	private boolean jj_3R_136(){
+		if (jj_scan_token(QUANTIFIER))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_165(){
+	private boolean jj_3R_102(){
+		if (jj_3R_130())
+			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_173()){
+		if (jj_3R_145())
 			jj_scanpos = xsp;
-			if (jj_3R_174())
-				return true;
-		}
 		return false;
 	}
 
-	private boolean jj_3R_175(){
-		if (jj_scan_token(NOT))
+	private boolean jj_3R_106(){
+		if (jj_scan_token(FULL))
 			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))
+	private boolean jj_3R_127(){
+		if (jj_3R_147())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_166(){
+	private boolean jj_3R_44(){
+		if (jj_scan_token(SELECT))
+			return true;
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_scan_token(33)){
+		if (jj_3R_136())
 			jj_scanpos = xsp;
-			if (jj_scan_token(34))
-				return true;
-		}
 		xsp = jj_scanpos;
-		if (jj_3R_175())
+		if (jj_3R_137())
 			jj_scanpos = xsp;
-		if (jj_3R_165())
+		if (jj_3R_138())
 			return true;
-		return false;
-	}
-
-	private boolean jj_3R_138(){
-		Token xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_150()){
-			jj_scanpos = xsp;
-			if (jj_3_1()){
+		while(true){
+			xsp = jj_scanpos;
+			if (jj_3R_139()){
 				jj_scanpos = xsp;
-				if (jj_3R_151())
-					return true;
+				break;
 			}
 		}
 		return false;
 	}
 
-	private boolean jj_3R_139(){
-		if (jj_scan_token(COMMA))
+	private boolean jj_3R_59(){
+		if (jj_3R_102())
 			return true;
-		if (jj_3R_138())
+		return false;
+	}
+
+	private boolean jj_3R_58(){
+		if (jj_3R_24())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_114(){
-		if (jj_scan_token(COMMA))
+	private boolean jj_3R_57(){
+		if (jj_3R_24())
+			return true;
+		return false;
+	}
+
+	private boolean jj_3R_70(){
+		if (jj_scan_token(LEFT_PAR))
 			return true;
 		if (jj_3R_41())
 			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
 		return false;
 	}
 
-	private boolean jj_3R_137(){
-		if (jj_scan_token(TOP))
-			return true;
-		if (jj_scan_token(UNSIGNED_INTEGER))
+	private boolean jj_3R_56(){
+		if (jj_3R_102())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_136(){
-		if (jj_scan_token(QUANTIFIER))
+	private boolean jj_3R_126(){
+		if (jj_scan_token(CIRCLE))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_157())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_158())
+			return true;
+		if (jj_scan_token(COMMA))
+			return true;
+		if (jj_3R_102())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_164(){
-		if (jj_scan_token(NOT))
+	private boolean jj_3R_69(){
+		if (jj_3R_117())
 			return true;
 		return false;
 	}
 
-	private boolean jj_3R_44(){
-		if (jj_scan_token(SELECT))
+	private boolean jj_3R_55(){
+		if (jj_3R_101())
 			return true;
+		return false;
+	}
+
+	private boolean jj_3R_41(){
 		Token xsp;
 		xsp = jj_scanpos;
-		if (jj_3R_136())
-			jj_scanpos = xsp;
-		xsp = jj_scanpos;
-		if (jj_3R_137())
+		if (jj_3R_55()){
 			jj_scanpos = xsp;
-		if (jj_3R_138())
-			return true;
-		while(true){
-			xsp = jj_scanpos;
-			if (jj_3R_139()){
+			if (jj_3R_56()){
 				jj_scanpos = xsp;
-				break;
+				if (jj_3R_57()){
+					jj_scanpos = xsp;
+					if (jj_3R_58()){
+						jj_scanpos = xsp;
+						if (jj_3R_59())
+							return true;
+					}
+				}
 			}
 		}
 		return false;
 	}
 
+	private boolean jj_3R_125(){
+		if (jj_scan_token(CENTROID))
+			return true;
+		if (jj_scan_token(LEFT_PAR))
+			return true;
+		if (jj_3R_64())
+			return true;
+		if (jj_scan_token(RIGHT_PAR))
+			return true;
+		return false;
+	}
+
 	/** Generated Token Manager. */
 	public ADQLParserTokenManager token_source;
 	SimpleCharStream jj_input_stream;
diff --git a/src/adql/parser/ADQLParserConstants.java b/src/adql/parser/ADQLParserConstants.java
index cf75565..e69af55 100644
--- a/src/adql/parser/ADQLParserConstants.java
+++ b/src/adql/parser/ADQLParserConstants.java
@@ -1,213 +1,318 @@
 /* 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 LEFT_PAR = 2;
-	/** RegularExpression Id. */
-	int RIGHT_PAR = 3;
-	/** RegularExpression Id. */
-	int DOT = 4;
-	/** RegularExpression Id. */
-	int COMMA = 5;
-	/** RegularExpression Id. */
-	int EOQ = 6;
-	/** RegularExpression Id. */
-	int CONCAT = 7;
-	/** RegularExpression Id. */
-	int PLUS = 8;
-	/** RegularExpression Id. */
-	int MINUS = 9;
-	/** RegularExpression Id. */
-	int ASTERISK = 10;
-	/** RegularExpression Id. */
-	int DIVIDE = 11;
-	/** RegularExpression Id. */
-	int EQUAL = 12;
-	/** RegularExpression Id. */
-	int NOT_EQUAL = 13;
-	/** RegularExpression Id. */
-	int LESS_THAN = 14;
-	/** RegularExpression Id. */
-	int LESS_EQUAL_THAN = 15;
-	/** RegularExpression Id. */
-	int GREATER_THAN = 16;
-	/** RegularExpression Id. */
-	int GREATER_EQUAL_THAN = 17;
-	/** RegularExpression Id. */
-	int SELECT = 18;
-	/** RegularExpression Id. */
-	int QUANTIFIER = 19;
-	/** RegularExpression Id. */
-	int TOP = 20;
-	/** RegularExpression Id. */
-	int FROM = 21;
-	/** RegularExpression Id. */
-	int AS = 22;
-	/** RegularExpression Id. */
-	int NATURAL = 23;
-	/** RegularExpression Id. */
-	int INNER = 24;
-	/** RegularExpression Id. */
-	int OUTER = 25;
-	/** RegularExpression Id. */
-	int RIGHT = 26;
-	/** RegularExpression Id. */
-	int LEFT = 27;
-	/** RegularExpression Id. */
-	int FULL = 28;
-	/** RegularExpression Id. */
-	int JOIN = 29;
-	/** RegularExpression Id. */
-	int ON = 30;
-	/** RegularExpression Id. */
-	int USING = 31;
-	/** RegularExpression Id. */
-	int WHERE = 32;
-	/** RegularExpression Id. */
-	int AND = 33;
-	/** RegularExpression Id. */
-	int OR = 34;
-	/** RegularExpression Id. */
-	int NOT = 35;
-	/** RegularExpression Id. */
-	int IS = 36;
-	/** RegularExpression Id. */
-	int NULL = 37;
-	/** RegularExpression Id. */
-	int BETWEEN = 38;
-	/** RegularExpression Id. */
-	int LIKE = 39;
-	/** RegularExpression Id. */
-	int IN = 40;
-	/** RegularExpression Id. */
-	int EXISTS = 41;
-	/** RegularExpression Id. */
-	int GROUP_BY = 42;
-	/** RegularExpression Id. */
-	int HAVING = 43;
-	/** RegularExpression Id. */
-	int ORDER_BY = 44;
-	/** RegularExpression Id. */
-	int ASC = 45;
-	/** RegularExpression Id. */
-	int DESC = 46;
-	/** RegularExpression Id. */
-	int AVG = 47;
-	/** RegularExpression Id. */
-	int MAX = 48;
-	/** RegularExpression Id. */
-	int MIN = 49;
-	/** RegularExpression Id. */
-	int SUM = 50;
-	/** RegularExpression Id. */
-	int COUNT = 51;
-	/** RegularExpression Id. */
-	int BOX = 52;
-	/** RegularExpression Id. */
-	int CENTROID = 53;
-	/** RegularExpression Id. */
-	int CIRCLE = 54;
-	/** RegularExpression Id. */
-	int POINT = 55;
-	/** RegularExpression Id. */
-	int POLYGON = 56;
-	/** RegularExpression Id. */
-	int REGION = 57;
-	/** RegularExpression Id. */
-	int CONTAINS = 58;
-	/** RegularExpression Id. */
-	int INTERSECTS = 59;
-	/** RegularExpression Id. */
-	int AREA = 60;
-	/** RegularExpression Id. */
-	int COORD1 = 61;
-	/** RegularExpression Id. */
-	int COORD2 = 62;
-	/** RegularExpression Id. */
-	int COORDSYS = 63;
-	/** RegularExpression Id. */
-	int DISTANCE = 64;
-	/** RegularExpression Id. */
-	int ABS = 65;
-	/** RegularExpression Id. */
-	int CEILING = 66;
-	/** RegularExpression Id. */
-	int DEGREES = 67;
-	/** RegularExpression Id. */
-	int EXP = 68;
-	/** RegularExpression Id. */
-	int FLOOR = 69;
-	/** RegularExpression Id. */
-	int LOG = 70;
-	/** RegularExpression Id. */
-	int LOG10 = 71;
-	/** RegularExpression Id. */
-	int MOD = 72;
-	/** RegularExpression Id. */
-	int PI = 73;
-	/** RegularExpression Id. */
-	int POWER = 74;
-	/** RegularExpression Id. */
-	int RADIANS = 75;
-	/** RegularExpression Id. */
-	int RAND = 76;
-	/** RegularExpression Id. */
-	int ROUND = 77;
-	/** RegularExpression Id. */
-	int SQRT = 78;
-	/** RegularExpression Id. */
-	int TRUNCATE = 79;
-	/** RegularExpression Id. */
-	int ACOS = 80;
-	/** RegularExpression Id. */
-	int ASIN = 81;
-	/** RegularExpression Id. */
-	int ATAN = 82;
-	/** RegularExpression Id. */
-	int ATAN2 = 83;
-	/** RegularExpression Id. */
-	int COS = 84;
-	/** RegularExpression Id. */
-	int COT = 85;
-	/** RegularExpression Id. */
-	int SIN = 86;
-	/** RegularExpression Id. */
-	int TAN = 87;
-	/** RegularExpression Id. */
-	int STRING_LITERAL = 93;
-	/** RegularExpression Id. */
-	int DELIMITED_IDENTIFIER = 96;
-	/** RegularExpression Id. */
-	int REGULAR_IDENTIFIER = 97;
-	/** RegularExpression Id. */
-	int Letter = 98;
-	/** RegularExpression Id. */
-	int SCIENTIFIC_NUMBER = 99;
-	/** RegularExpression Id. */
-	int UNSIGNED_FLOAT = 100;
-	/** RegularExpression Id. */
-	int UNSIGNED_INTEGER = 101;
-	/** RegularExpression Id. */
-	int DIGIT = 102;
+  /** End of File. */
+  int EOF = 0;
+  /** RegularExpression Id. */
+  int LEFT_PAR = 2;
+  /** RegularExpression Id. */
+  int RIGHT_PAR = 3;
+  /** RegularExpression Id. */
+  int DOT = 4;
+  /** RegularExpression Id. */
+  int COMMA = 5;
+  /** RegularExpression Id. */
+  int EOQ = 6;
+  /** RegularExpression Id. */
+  int CONCAT = 7;
+  /** RegularExpression Id. */
+  int PLUS = 8;
+  /** RegularExpression Id. */
+  int MINUS = 9;
+  /** RegularExpression Id. */
+  int ASTERISK = 10;
+  /** RegularExpression Id. */
+  int DIVIDE = 11;
+  /** RegularExpression Id. */
+  int EQUAL = 12;
+  /** RegularExpression Id. */
+  int NOT_EQUAL = 13;
+  /** RegularExpression Id. */
+  int LESS_THAN = 14;
+  /** RegularExpression Id. */
+  int LESS_EQUAL_THAN = 15;
+  /** RegularExpression Id. */
+  int GREATER_THAN = 16;
+  /** RegularExpression Id. */
+  int GREATER_EQUAL_THAN = 17;
+  /** RegularExpression Id. */
+  int SELECT = 18;
+  /** RegularExpression Id. */
+  int QUANTIFIER = 19;
+  /** RegularExpression Id. */
+  int TOP = 20;
+  /** RegularExpression Id. */
+  int FROM = 21;
+  /** RegularExpression Id. */
+  int AS = 22;
+  /** RegularExpression Id. */
+  int NATURAL = 23;
+  /** RegularExpression Id. */
+  int INNER = 24;
+  /** RegularExpression Id. */
+  int OUTER = 25;
+  /** RegularExpression Id. */
+  int RIGHT = 26;
+  /** RegularExpression Id. */
+  int LEFT = 27;
+  /** RegularExpression Id. */
+  int FULL = 28;
+  /** RegularExpression Id. */
+  int JOIN = 29;
+  /** RegularExpression Id. */
+  int ON = 30;
+  /** RegularExpression Id. */
+  int USING = 31;
+  /** RegularExpression Id. */
+  int WHERE = 32;
+  /** RegularExpression Id. */
+  int AND = 33;
+  /** RegularExpression Id. */
+  int OR = 34;
+  /** RegularExpression Id. */
+  int NOT = 35;
+  /** RegularExpression Id. */
+  int IS = 36;
+  /** RegularExpression Id. */
+  int NULL = 37;
+  /** RegularExpression Id. */
+  int BETWEEN = 38;
+  /** RegularExpression Id. */
+  int LIKE = 39;
+  /** RegularExpression Id. */
+  int IN = 40;
+  /** RegularExpression Id. */
+  int EXISTS = 41;
+  /** RegularExpression Id. */
+  int GROUP_BY = 42;
+  /** RegularExpression Id. */
+  int HAVING = 43;
+  /** RegularExpression Id. */
+  int ORDER_BY = 44;
+  /** RegularExpression Id. */
+  int ASC = 45;
+  /** RegularExpression Id. */
+  int DESC = 46;
+  /** RegularExpression Id. */
+  int AVG = 47;
+  /** RegularExpression Id. */
+  int MAX = 48;
+  /** RegularExpression Id. */
+  int MIN = 49;
+  /** RegularExpression Id. */
+  int SUM = 50;
+  /** RegularExpression Id. */
+  int COUNT = 51;
+  /** RegularExpression Id. */
+  int BOX = 52;
+  /** RegularExpression Id. */
+  int CENTROID = 53;
+  /** RegularExpression Id. */
+  int CIRCLE = 54;
+  /** RegularExpression Id. */
+  int POINT = 55;
+  /** RegularExpression Id. */
+  int POLYGON = 56;
+  /** RegularExpression Id. */
+  int REGION = 57;
+  /** RegularExpression Id. */
+  int CONTAINS = 58;
+  /** RegularExpression Id. */
+  int INTERSECTS = 59;
+  /** RegularExpression Id. */
+  int AREA = 60;
+  /** RegularExpression Id. */
+  int COORD1 = 61;
+  /** RegularExpression Id. */
+  int COORD2 = 62;
+  /** RegularExpression Id. */
+  int COORDSYS = 63;
+  /** RegularExpression Id. */
+  int DISTANCE = 64;
+  /** RegularExpression Id. */
+  int ABS = 65;
+  /** RegularExpression Id. */
+  int CEILING = 66;
+  /** RegularExpression Id. */
+  int DEGREES = 67;
+  /** RegularExpression Id. */
+  int EXP = 68;
+  /** RegularExpression Id. */
+  int FLOOR = 69;
+  /** RegularExpression Id. */
+  int LOG = 70;
+  /** RegularExpression Id. */
+  int LOG10 = 71;
+  /** RegularExpression Id. */
+  int MOD = 72;
+  /** RegularExpression Id. */
+  int PI = 73;
+  /** RegularExpression Id. */
+  int POWER = 74;
+  /** RegularExpression Id. */
+  int RADIANS = 75;
+  /** RegularExpression Id. */
+  int RAND = 76;
+  /** RegularExpression Id. */
+  int ROUND = 77;
+  /** RegularExpression Id. */
+  int SQRT = 78;
+  /** RegularExpression Id. */
+  int TRUNCATE = 79;
+  /** RegularExpression Id. */
+  int ACOS = 80;
+  /** RegularExpression Id. */
+  int ASIN = 81;
+  /** RegularExpression Id. */
+  int ATAN = 82;
+  /** RegularExpression Id. */
+  int ATAN2 = 83;
+  /** RegularExpression Id. */
+  int COS = 84;
+  /** RegularExpression Id. */
+  int COT = 85;
+  /** RegularExpression Id. */
+  int SIN = 86;
+  /** RegularExpression Id. */
+  int TAN = 87;
+  /** RegularExpression Id. */
+  int STRING_LITERAL = 93;
+  /** RegularExpression Id. */
+  int DELIMITED_IDENTIFIER = 96;
+  /** RegularExpression Id. */
+  int REGULAR_IDENTIFIER = 97;
+  /** RegularExpression Id. */
+  int Letter = 98;
+  /** RegularExpression Id. */
+  int SCIENTIFIC_NUMBER = 99;
+  /** RegularExpression Id. */
+  int UNSIGNED_FLOAT = 100;
+  /** RegularExpression Id. */
+  int UNSIGNED_INTEGER = 101;
+  /** RegularExpression Id. */
+  int DIGIT = 102;
 
-	/** Lexical state. */
-	int DEFAULT = 0;
-	/** Lexical state. */
-	int WithinComment = 1;
-	/** Lexical state. */
-	int WithinString = 2;
-	/** Lexical state. */
-	int WithinDelimitedId = 3;
+  /** Lexical state. */
+  int DEFAULT = 0;
+  /** Lexical state. */
+  int WithinComment = 1;
+  /** Lexical state. */
+  int WithinString = 2;
+  /** Lexical state. */
+  int WithinDelimitedId = 3;
 
-	/** Literal token values. */
-	String[] tokenImage = {"<EOF>","<token of kind 1>","\"(\"","\")\"","\".\"","\",\"","\";\"","\"||\"","\"+\"","\"-\"","\"*\"","\"/\"","\"=\"","<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\"","\"GROUP BY\"","\"HAVING\"","\"ORDER BY\"","\"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 88>","<token of kind 89>","<token of kind 90>","\"\\\'\"","<token of kind 92>","\"\\\'\"","\"\\\"\"","<token of kind 95>","\"\\\"\"","<REGULAR_IDENTIFIER>","<Letter>","<SCIENTIFIC_NUMBER>","<UNSIGNED_FLOAT>","<UNSIGNED_INTEGER>","<DIGIT>",};
+  /** Literal token values. */
+  String[] tokenImage = {
+    "<EOF>",
+    "<token of kind 1>",
+    "\"(\"",
+    "\")\"",
+    "\".\"",
+    "\",\"",
+    "\";\"",
+    "\"||\"",
+    "\"+\"",
+    "\"-\"",
+    "\"*\"",
+    "\"/\"",
+    "\"=\"",
+    "<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\"",
+    "\"GROUP BY\"",
+    "\"HAVING\"",
+    "\"ORDER BY\"",
+    "\"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 88>",
+    "<token of kind 89>",
+    "<token of kind 90>",
+    "\"\\\'\"",
+    "<token of kind 92>",
+    "\"\\\'\"",
+    "\"\\\"\"",
+    "<token of kind 95>",
+    "\"\\\"\"",
+    "<REGULAR_IDENTIFIER>",
+    "<Letter>",
+    "<SCIENTIFIC_NUMBER>",
+    "<UNSIGNED_FLOAT>",
+    "<UNSIGNED_INTEGER>",
+    "<DIGIT>",
+  };
 
 }
diff --git a/src/adql/parser/ADQLParserTokenManager.java b/src/adql/parser/ADQLParserTokenManager.java
index 4e4d9cc..1544161 100644
--- a/src/adql/parser/ADQLParserTokenManager.java
+++ b/src/adql/parser/ADQLParserTokenManager.java
@@ -1,6 +1,5 @@
 /* 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;
@@ -21,1716 +20,1842 @@ 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_3(int pos, long active0, long active1){
-		switch(pos){
-			default:
-				return -1;
-		}
-	}
-
-	private final int jjStartNfa_3(int pos, long active0, long active1){
-		return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0, active1), pos + 1);
-	}
-
-	private int jjStopAtPos(int pos, int kind){
-		jjmatchedKind = kind;
-		jjmatchedPos = pos;
-		return pos + 1;
-	}
-
-	private int jjMoveStringLiteralDfa0_3(){
-		switch(curChar){
-			case 34:
-				return jjStartNfaWithStates_3(0, 96, 1);
-			default:
-				return jjMoveNfa_3(0, 0);
-		}
-	}
-
-	private int jjStartNfaWithStates_3(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_3(state, pos + 1);
-	}
-
-	static final long[] jjbitVec0 = {0x0L,0x0L,0xffffffffffffffffL,0xffffffffffffffffL};
-
-	private int jjMoveNfa_3(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 > 95)
-									kind = 95;
-							}else if (curChar == 34)
-								jjstateSet[jjnewStateCnt++] = 1;
-							break;
-						case 1:
-							if (curChar == 34 && kind > 95)
-								kind = 95;
-							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 = 95;
-							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 > 95)
-								kind = 95;
-							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 & 0xefff1ffdffb40000L) != 0L || (active1 & 0xf0fff4L) != 0L){
-					jjmatchedKind = 97;
-					return 37;
-				}
-				if ((active0 & 0x1000a00200400000L) != 0L || (active1 & 0xf0002L) != 0L){
-					jjmatchedKind = 97;
-					return 16;
-				}
-				if ((active0 & 0x10L) != 0L)
-					return 38;
-				if ((active0 & 0x400000000000L) != 0L || (active1 & 0x9L) != 0L){
-					jjmatchedKind = 97;
-					return 13;
-				}
-				if ((active0 & 0xc000L) != 0L)
-					return 3;
-				if ((active0 & 0x200L) != 0L)
-					return 19;
-				return -1;
-			case 1:
-				if ((active0 & 0xf7ffceebbeb40000L) != 0L || (active1 & 0xfdfdfeL) != 0L){
-					if (jjmatchedPos != 1){
-						jjmatchedKind = 97;
-						jjmatchedPos = 1;
-					}
-					return 37;
-				}
-				if ((active0 & 0x800311441400000L) != 0L || (active1 & 0x20200L) != 0L)
-					return 37;
-				if ((active1 & 0x1L) != 0L){
-					if (jjmatchedPos != 1){
-						jjmatchedKind = 97;
-						jjmatchedPos = 1;
-					}
-					return 12;
-				}
-				return -1;
-			case 2:
-				if ((active1 & 0x1L) != 0L){
-					if (jjmatchedPos != 2){
-						jjmatchedKind = 97;
-						jjmatchedPos = 2;
-					}
-					return 11;
-				}
-				if ((active0 & 0x17a00a00100000L) != 0L || (active1 & 0xf001d2L) != 0L)
-					return 37;
-				if ((active0 & 0xffe85ee1bfa40000L) != 0L || (active1 & 0xffc2cL) != 0L){
-					if (jjmatchedPos != 2){
-						jjmatchedKind = 97;
-						jjmatchedPos = 2;
-					}
-					return 37;
-				}
-				return -1;
-			case 3:
-				if ((active0 & 0xefe81e4187840000L) != 0L || (active1 & 0xac2cL) != 0L){
-					if (jjmatchedPos != 3){
-						jjmatchedKind = 97;
-						jjmatchedPos = 3;
-					}
-					return 37;
-				}
-				if ((active0 & 0x100040a038200000L) != 0L || (active1 & 0xf5000L) != 0L)
-					return 37;
-				if ((active1 & 0x80L) != 0L){
-					if (jjmatchedPos != 3){
-						jjmatchedKind = 97;
-						jjmatchedPos = 3;
-					}
-					return 21;
-				}
-				if ((active1 & 0x1L) != 0L){
-					if (jjmatchedPos != 3){
-						jjmatchedKind = 97;
-						jjmatchedPos = 3;
-					}
-					return 10;
-				}
-				return -1;
-			case 4:
-				if ((active0 & 0xef601e4000840000L) != 0L || (active1 & 0x880dL) != 0L){
-					jjmatchedKind = 97;
-					jjmatchedPos = 4;
-					return 37;
-				}
-				if ((active0 & 0x88000187000000L) != 0L || (active1 & 0x2420L) != 0L)
-					return 37;
-				if ((active1 & 0x80080L) != 0L)
-					return 21;
-				return -1;
-			case 5:
-				if ((active0 & 0x2400a0000040000L) != 0L)
-					return 37;
-				if ((active0 & 0x6000000000000000L) != 0L)
-					return 21;
-				if ((active0 & 0x8d20004000800000L) != 0L || (active1 & 0x880dL) != 0L){
-					jjmatchedKind = 97;
-					jjmatchedPos = 5;
-					return 37;
-				}
-				if ((active0 & 0x140000000000L) != 0L){
-					if (jjmatchedPos < 4){
-						jjmatchedKind = 97;
-						jjmatchedPos = 4;
-					}
-					return -1;
-				}
-				return -1;
-			case 6:
-				if ((active0 & 0x8c20000000000000L) != 0L || (active1 & 0x8001L) != 0L){
-					jjmatchedKind = 97;
-					jjmatchedPos = 6;
-					return 37;
-				}
-				if ((active0 & 0x100004000800000L) != 0L || (active1 & 0x80cL) != 0L)
-					return 37;
-				if ((active0 & 0x140000000000L) != 0L){
-					if (jjmatchedPos < 4){
-						jjmatchedKind = 97;
-						jjmatchedPos = 4;
-					}
-					return -1;
-				}
-				return -1;
-			case 7:
-				if ((active0 & 0x800000000000000L) != 0L){
-					jjmatchedKind = 97;
-					jjmatchedPos = 7;
-					return 37;
-				}
-				if ((active0 & 0x8420000000000000L) != 0L || (active1 & 0x8001L) != 0L)
-					return 37;
-				if ((active0 & 0x140000000000L) != 0L){
-					if (jjmatchedPos < 4){
-						jjmatchedKind = 97;
-						jjmatchedPos = 4;
-					}
-					return -1;
-				}
-				return -1;
-			case 8:
-				if ((active0 & 0x800000000000000L) != 0L){
-					jjmatchedKind = 97;
-					jjmatchedPos = 8;
-					return 37;
-				}
-				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, 94);
-			case 39:
-				return jjStopAtPos(0, 91);
-			case 40:
-				return jjStopAtPos(0, 2);
-			case 41:
-				return jjStopAtPos(0, 3);
-			case 42:
-				return jjStopAtPos(0, 10);
-			case 43:
-				return jjStopAtPos(0, 8);
-			case 44:
-				return jjStopAtPos(0, 5);
-			case 45:
-				return jjStartNfaWithStates_0(0, 9, 19);
-			case 46:
-				return jjStartNfaWithStates_0(0, 4, 38);
-			case 47:
-				return jjStopAtPos(0, 11);
-			case 59:
-				return jjStopAtPos(0, 6);
-			case 60:
-				jjmatchedKind = 14;
-				return jjMoveStringLiteralDfa1_0(0x8000L, 0x0L);
-			case 61:
-				return jjStopAtPos(0, 12);
-			case 62:
-				jjmatchedKind = 16;
-				return jjMoveStringLiteralDfa1_0(0x20000L, 0x0L);
-			case 65:
-			case 97:
-				return jjMoveStringLiteralDfa1_0(0x1000a00200400000L, 0xf0002L);
-			case 66:
-			case 98:
-				return jjMoveStringLiteralDfa1_0(0x10004000000000L, 0x0L);
-			case 67:
-			case 99:
-				return jjMoveStringLiteralDfa1_0(0xe468000000000000L, 0x300004L);
-			case 68:
-			case 100:
-				return jjMoveStringLiteralDfa1_0(0x400000000000L, 0x9L);
-			case 69:
-			case 101:
-				return jjMoveStringLiteralDfa1_0(0x20000000000L, 0x10L);
-			case 70:
-			case 102:
-				return jjMoveStringLiteralDfa1_0(0x10200000L, 0x20L);
-			case 71:
-			case 103:
-				return jjMoveStringLiteralDfa1_0(0x40000000000L, 0x0L);
-			case 72:
-			case 104:
-				return jjMoveStringLiteralDfa1_0(0x80000000000L, 0x0L);
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa1_0(0x800011001000000L, 0x0L);
-			case 74:
-			case 106:
-				return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L);
-			case 76:
-			case 108:
-				return jjMoveStringLiteralDfa1_0(0x8008000000L, 0xc0L);
-			case 77:
-			case 109:
-				return jjMoveStringLiteralDfa1_0(0x3000000000000L, 0x100L);
-			case 78:
-			case 110:
-				return jjMoveStringLiteralDfa1_0(0x2800800000L, 0x0L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa1_0(0x100442000000L, 0x0L);
-			case 80:
-			case 112:
-				return jjMoveStringLiteralDfa1_0(0x180000000000000L, 0x600L);
-			case 82:
-			case 114:
-				return jjMoveStringLiteralDfa1_0(0x200000004000000L, 0x3800L);
-			case 83:
-			case 115:
-				return jjMoveStringLiteralDfa1_0(0x4000000040000L, 0x404000L);
-			case 84:
-			case 116:
-				return jjMoveStringLiteralDfa1_0(0x100000L, 0x808000L);
-			case 85:
-			case 117:
-				return jjMoveStringLiteralDfa1_0(0x80000000L, 0x0L);
-			case 87:
-			case 119:
-				return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L);
-			case 124:
-				return jjMoveStringLiteralDfa1_0(0x80L, 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 & 0x8000L) != 0L)
-					return jjStopAtPos(1, 15);
-				else if ((active0 & 0x20000L) != 0L)
-					return jjStopAtPos(1, 17);
-				break;
-			case 65:
-			case 97:
-				return jjMoveStringLiteralDfa2_0(active0, 0x1080000800000L, active1, 0x801800L);
-			case 66:
-			case 98:
-				return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2L);
-			case 67:
-			case 99:
-				return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000L);
-			case 69:
-			case 101:
-				return jjMoveStringLiteralDfa2_0(active0, 0x220404008040000L, active1, 0xcL);
-			case 72:
-			case 104:
-				return jjMoveStringLiteralDfa2_0(active0, 0x100000000L, active1, 0L);
-			case 73:
-			case 105:
-				if ((active1 & 0x200L) != 0L)
-					return jjStartNfaWithStates_0(1, 73, 37);
-				return jjMoveStringLiteralDfa2_0(active0, 0x42008004000000L, active1, 0x400001L);
-			case 76:
-			case 108:
-				return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x20L);
-			case 78:
-			case 110:
-				if ((active0 & 0x40000000L) != 0L)
-					return jjStartNfaWithStates_0(1, 30, 37);
-				else if ((active0 & 0x10000000000L) != 0L){
-					jjmatchedKind = 40;
-					jjmatchedPos = 1;
-				}
-				return jjMoveStringLiteralDfa2_0(active0, 0x800000201000000L, active1, 0L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa2_0(active0, 0xe598000820100000L, active1, 0x3025c0L);
-			case 81:
-			case 113:
-				return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x4000L);
-			case 82:
-			case 114:
-				if ((active0 & 0x400000000L) != 0L){
-					jjmatchedKind = 34;
-					jjmatchedPos = 1;
-				}
-				return jjMoveStringLiteralDfa2_0(active0, 0x1000140000200000L, active1, 0x8000L);
-			case 83:
-			case 115:
-				if ((active0 & 0x400000L) != 0L){
-					jjmatchedKind = 22;
-					jjmatchedPos = 1;
-				}else if ((active0 & 0x1000000000L) != 0L)
-					return jjStartNfaWithStates_0(1, 36, 37);
-				return jjMoveStringLiteralDfa2_0(active0, 0x200080000000L, active1, 0x20000L);
-			case 84:
-			case 116:
-				return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0xc0000L);
-			case 85:
-			case 117:
-				return jjMoveStringLiteralDfa2_0(active0, 0x4002012000000L, active1, 0L);
-			case 86:
-			case 118:
-				return jjMoveStringLiteralDfa2_0(active0, 0x800000000000L, active1, 0L);
-			case 88:
-			case 120:
-				return jjMoveStringLiteralDfa2_0(active0, 0x20000000000L, active1, 0x10L);
-			case 124:
-				if ((active0 & 0x80L) != 0L)
-					return jjStopAtPos(1, 7);
-				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, 0xc0000L);
-			case 67:
-			case 99:
-				if ((active0 & 0x200000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 45, 37);
-				break;
-			case 68:
-			case 100:
-				if ((active0 & 0x200000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 33, 37);
-				else if ((active1 & 0x100L) != 0L)
-					return jjStartNfaWithStates_0(2, 72, 37);
-				return jjMoveStringLiteralDfa3_0(active0, 0x100000000000L, active1, 0x800L);
-			case 69:
-			case 101:
-				return jjMoveStringLiteralDfa3_0(active0, 0x1000000100000000L, active1, 0L);
-			case 70:
-			case 102:
-				return jjMoveStringLiteralDfa3_0(active0, 0x8000000L, active1, 0L);
-			case 71:
-			case 103:
-				if ((active0 & 0x800000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 47, 37);
-				else if ((active1 & 0x40L) != 0L){
-					jjmatchedKind = 70;
-					jjmatchedPos = 2;
-				}
-				return jjMoveStringLiteralDfa3_0(active0, 0x200000004000000L, active1, 0x88L);
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa3_0(active0, 0x800200a0000000L, active1, 0x20004L);
-			case 75:
-			case 107:
-				return jjMoveStringLiteralDfa3_0(active0, 0x8000000000L, active1, 0L);
-			case 76:
-			case 108:
-				return jjMoveStringLiteralDfa3_0(active0, 0x100002010040000L, active1, 0L);
-			case 77:
-			case 109:
-				if ((active0 & 0x4000000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 50, 37);
-				break;
-			case 78:
-			case 110:
-				if ((active0 & 0x2000000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 49, 37);
-				else if ((active1 & 0x400000L) != 0L)
-					return jjStartNfaWithStates_0(2, 86, 37);
-				else if ((active1 & 0x800000L) != 0L)
-					return jjStartNfaWithStates_0(2, 87, 37);
-				return jjMoveStringLiteralDfa3_0(active0, 0x420000001000000L, active1, 0x1000L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa3_0(active0, 0xe000040000200000L, active1, 0x10020L);
-			case 80:
-			case 112:
-				if ((active0 & 0x100000L) != 0L)
-					return jjStartNfaWithStates_0(2, 20, 37);
-				else if ((active1 & 0x10L) != 0L)
-					return jjStartNfaWithStates_0(2, 68, 37);
-				break;
-			case 82:
-			case 114:
-				return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000L, active1, 0x4000L);
-			case 83:
-			case 115:
-				if ((active1 & 0x2L) != 0L)
-					return jjStartNfaWithStates_0(2, 65, 37);
-				else if ((active1 & 0x100000L) != 0L)
-					return jjStartNfaWithStates_0(2, 84, 37);
-				return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0x1L);
-			case 84:
-			case 116:
-				if ((active0 & 0x800000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 35, 37);
-				else if ((active1 & 0x200000L) != 0L)
-					return jjStartNfaWithStates_0(2, 85, 37);
-				return jjMoveStringLiteralDfa3_0(active0, 0x800004002800000L, active1, 0L);
-			case 85:
-			case 117:
-				return jjMoveStringLiteralDfa3_0(active0, 0x8000000000000L, active1, 0xa000L);
-			case 86:
-			case 118:
-				return jjMoveStringLiteralDfa3_0(active0, 0x80000000000L, active1, 0L);
-			case 87:
-			case 119:
-				return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400L);
-			case 88:
-			case 120:
-				if ((active0 & 0x1000000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 48, 37);
-				else if ((active0 & 0x10000000000000L) != 0L)
-					return jjStartNfaWithStates_0(2, 52, 37);
-				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, 0x80L);
-			case 65:
-			case 97:
-				if ((active0 & 0x1000000000000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 60, 37);
-				break;
-			case 67:
-			case 99:
-				if ((active0 & 0x400000000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 46, 37);
-				return jjMoveStringLiteralDfa4_0(active0, 0x40000000000000L, active1, 0L);
-			case 68:
-			case 100:
-				if ((active1 & 0x1000L) != 0L)
-					return jjStartNfaWithStates_0(3, 76, 37);
-				break;
-			case 69:
-			case 101:
-				if ((active0 & 0x8000000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 39, 37);
-				return jjMoveStringLiteralDfa4_0(active0, 0x800100003040000L, active1, 0x400L);
-			case 72:
-			case 104:
-				return jjMoveStringLiteralDfa4_0(active0, 0x4000000L, active1, 0L);
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa4_0(active0, 0x200080000000000L, active1, 0x800L);
-			case 76:
-			case 108:
-				if ((active0 & 0x10000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 28, 37);
-				else if ((active0 & 0x2000000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 37, 37);
-				return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x4L);
-			case 77:
-			case 109:
-				if ((active0 & 0x200000L) != 0L)
-					return jjStartNfaWithStates_0(3, 21, 37);
-				break;
-			case 78:
-			case 110:
-				if ((active0 & 0x20000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 29, 37);
-				else if ((active1 & 0x20000L) != 0L)
-					return jjStartNfaWithStates_0(3, 81, 37);
-				else if ((active1 & 0x40000L) != 0L){
-					jjmatchedKind = 82;
-					jjmatchedPos = 3;
-				}
-				return jjMoveStringLiteralDfa4_0(active0, 0x88000080000000L, active1, 0x8a000L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x20L);
-			case 82:
-			case 114:
-				return jjMoveStringLiteralDfa4_0(active0, 0xe000000100000000L, active1, 0x8L);
-			case 83:
-			case 115:
-				if ((active1 & 0x10000L) != 0L)
-					return jjStartNfaWithStates_0(3, 80, 37);
-				return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L);
-			case 84:
-			case 116:
-				if ((active0 & 0x8000000L) != 0L)
-					return jjStartNfaWithStates_0(3, 27, 37);
-				else if ((active1 & 0x4000L) != 0L)
-					return jjStartNfaWithStates_0(3, 78, 37);
-				return jjMoveStringLiteralDfa4_0(active0, 0x420000000000000L, active1, 0x1L);
-			case 85:
-			case 117:
-				return jjMoveStringLiteralDfa4_0(active0, 0x40000800000L, active1, 0L);
-			case 87:
-			case 119:
-				return jjMoveStringLiteralDfa4_0(active0, 0x4000000000L, active1, 0L);
-			case 89:
-			case 121:
-				return jjMoveStringLiteralDfa4_0(active0, 0x100000000000000L, 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 & 0x80L) != 0L)
-					return jjStartNfaWithStates_0(4, 71, 21);
-				break;
-			case 50:
-				if ((active1 & 0x80000L) != 0L)
-					return jjStartNfaWithStates_0(4, 83, 21);
-				break;
-			case 65:
-			case 97:
-				return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0x801L);
-			case 67:
-			case 99:
-				return jjMoveStringLiteralDfa5_0(active0, 0x40000L, active1, 0x8000L);
-			case 68:
-			case 100:
-				if ((active1 & 0x2000L) != 0L)
-					return jjStartNfaWithStates_0(4, 77, 37);
-				return jjMoveStringLiteralDfa5_0(active0, 0xe000000000000000L, active1, 0L);
-			case 69:
-			case 101:
-				if ((active0 & 0x100000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 32, 37);
-				return jjMoveStringLiteralDfa5_0(active0, 0x4000000000L, active1, 0x8L);
-			case 71:
-			case 103:
-				if ((active0 & 0x80000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 31, 37);
-				return jjMoveStringLiteralDfa5_0(active0, 0x100000000000000L, active1, 0L);
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x4L);
-			case 76:
-			case 108:
-				return jjMoveStringLiteralDfa5_0(active0, 0x40000000000000L, active1, 0L);
-			case 78:
-			case 110:
-				return jjMoveStringLiteralDfa5_0(active0, 0x80000000000L, active1, 0L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa5_0(active0, 0x200000000000000L, active1, 0L);
-			case 80:
-			case 112:
-				return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L);
-			case 82:
-			case 114:
-				if ((active0 & 0x1000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 24, 37);
-				else if ((active0 & 0x2000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 25, 37);
-				else if ((active1 & 0x20L) != 0L)
-					return jjStartNfaWithStates_0(4, 69, 37);
-				else if ((active1 & 0x400L) != 0L)
-					return jjStartNfaWithStates_0(4, 74, 37);
-				return jjMoveStringLiteralDfa5_0(active0, 0x820100000800000L, active1, 0L);
-			case 84:
-			case 116:
-				if ((active0 & 0x4000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 26, 37);
-				else if ((active0 & 0x8000000000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 51, 37);
-				else if ((active0 & 0x80000000000000L) != 0L)
-					return jjStartNfaWithStates_0(4, 55, 37);
-				return jjMoveStringLiteralDfa5_0(active0, 0x20000000000L, 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 32:
-				return jjMoveStringLiteralDfa6_0(active0, 0x140000000000L, active1, 0L);
-			case 49:
-				if ((active0 & 0x2000000000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 61, 21);
-				break;
-			case 50:
-				if ((active0 & 0x4000000000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 62, 21);
-				break;
-			case 65:
-			case 97:
-				return jjMoveStringLiteralDfa6_0(active0, 0x800000L, active1, 0x8000L);
-			case 69:
-			case 101:
-				if ((active0 & 0x40000000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 54, 37);
-				return jjMoveStringLiteralDfa6_0(active0, 0x4000000000L, active1, 0x8L);
-			case 71:
-			case 103:
-				if ((active0 & 0x80000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 43, 37);
-				break;
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa6_0(active0, 0x400000000000000L, active1, 0L);
-			case 78:
-			case 110:
-				if ((active0 & 0x200000000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 57, 37);
-				return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x805L);
-			case 79:
-			case 111:
-				return jjMoveStringLiteralDfa6_0(active0, 0x120000000000000L, active1, 0L);
-			case 83:
-			case 115:
-				if ((active0 & 0x20000000000L) != 0L)
-					return jjStartNfaWithStates_0(5, 41, 37);
-				return jjMoveStringLiteralDfa6_0(active0, 0x8800000000000000L, active1, 0L);
-			case 84:
-			case 116:
-				if ((active0 & 0x40000L) != 0L)
-					return jjStartNfaWithStates_0(5, 18, 37);
-				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 66:
-			case 98:
-				return jjMoveStringLiteralDfa7_0(active0, 0x140000000000L, active1, 0L);
-			case 67:
-			case 99:
-				return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x1L);
-			case 69:
-			case 101:
-				return jjMoveStringLiteralDfa7_0(active0, 0x800000000000000L, active1, 0L);
-			case 71:
-			case 103:
-				if ((active1 & 0x4L) != 0L)
-					return jjStartNfaWithStates_0(6, 66, 37);
-				break;
-			case 73:
-			case 105:
-				return jjMoveStringLiteralDfa7_0(active0, 0x20000000000000L, active1, 0L);
-			case 76:
-			case 108:
-				if ((active0 & 0x800000L) != 0L)
-					return jjStartNfaWithStates_0(6, 23, 37);
-				break;
-			case 78:
-			case 110:
-				if ((active0 & 0x4000000000L) != 0L)
-					return jjStartNfaWithStates_0(6, 38, 37);
-				else if ((active0 & 0x100000000000000L) != 0L)
-					return jjStartNfaWithStates_0(6, 56, 37);
-				return jjMoveStringLiteralDfa7_0(active0, 0x400000000000000L, active1, 0L);
-			case 83:
-			case 115:
-				if ((active1 & 0x8L) != 0L)
-					return jjStartNfaWithStates_0(6, 67, 37);
-				else if ((active1 & 0x800L) != 0L)
-					return jjStartNfaWithStates_0(6, 75, 37);
-				break;
-			case 84:
-			case 116:
-				return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x8000L);
-			case 89:
-			case 121:
-				return jjMoveStringLiteralDfa7_0(active0, 0x8000000000000000L, active1, 0L);
-			default:
-				break;
-		}
-		return jjStartNfa_0(5, active0, active1);
-	}
+public class ADQLParserTokenManager implements ADQLParserConstants
+{
 
-	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, 0x800000000000000L, active1, 0L);
-			case 68:
-			case 100:
-				if ((active0 & 0x20000000000000L) != 0L)
-					return jjStartNfaWithStates_0(7, 53, 37);
-				break;
-			case 69:
-			case 101:
-				if ((active1 & 0x1L) != 0L)
-					return jjStartNfaWithStates_0(7, 64, 37);
-				else if ((active1 & 0x8000L) != 0L)
-					return jjStartNfaWithStates_0(7, 79, 37);
-				break;
-			case 83:
-			case 115:
-				if ((active0 & 0x400000000000000L) != 0L)
-					return jjStartNfaWithStates_0(7, 58, 37);
-				else if ((active0 & 0x8000000000000000L) != 0L)
-					return jjStartNfaWithStates_0(7, 63, 37);
-				break;
-			case 89:
-			case 121:
-				if ((active0 & 0x40000000000L) != 0L)
-					return jjStopAtPos(7, 42);
-				else if ((active0 & 0x100000000000L) != 0L)
-					return jjStopAtPos(7, 44);
-				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, 0x800000000000000L);
-			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 & 0x800000000000000L) != 0L)
-					return jjStartNfaWithStates_0(9, 59, 37);
-				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 = 37;
-		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 12:
-						case 21:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 38:
-							if ((0x3ff000000000000L & l) != 0L){
-								if (kind > 100)
-									kind = 100;
-								jjCheckNAdd(27);
-							}
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(23, 24);
-							break;
-						case 37:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 0:
-							if ((0x3ff000000000000L & l) != 0L){
-								if (kind > 101)
-									kind = 101;
-								jjCheckNAddStates(0, 6);
-							}else if ((0x100002600L & l) != 0L){
-								if (kind > 1)
-									kind = 1;
-							}else if (curChar == 46)
-								jjCheckNAddTwoStates(23, 27);
-							else if (curChar == 45)
-								jjCheckNAdd(19);
-							else if (curChar == 33)
-								jjstateSet[jjnewStateCnt++] = 5;
-							else if (curChar == 60)
-								jjstateSet[jjnewStateCnt++] = 3;
-							if (curChar == 13)
-								jjstateSet[jjnewStateCnt++] = 1;
-							break;
-						case 11:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 16:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 13:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 10:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 1:
-							if (curChar == 10 && kind > 1)
-								kind = 1;
-							break;
-						case 2:
-							if (curChar == 13)
-								jjstateSet[jjnewStateCnt++] = 1;
-							break;
-						case 3:
-							if (curChar == 62)
-								kind = 13;
-							break;
-						case 4:
-							if (curChar == 60)
-								jjstateSet[jjnewStateCnt++] = 3;
-							break;
-						case 5:
-							if (curChar == 61)
-								kind = 13;
-							break;
-						case 6:
-							if (curChar == 33)
-								jjstateSet[jjnewStateCnt++] = 5;
-							break;
-						case 18:
-							if (curChar == 45)
-								jjCheckNAdd(19);
-							break;
-						case 19:
-							if (curChar != 45)
-								break;
-							if (kind > 88)
-								kind = 88;
-							jjCheckNAdd(19);
-							break;
-						case 22:
-							if (curChar == 46)
-								jjCheckNAddTwoStates(23, 27);
-							break;
-						case 23:
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(23, 24);
-							break;
-						case 25:
-							if ((0x280000000000L & l) != 0L)
-								jjCheckNAdd(26);
-							break;
-						case 26:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 99)
-								kind = 99;
-							jjCheckNAdd(26);
-							break;
-						case 27:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 100)
-								kind = 100;
-							jjCheckNAdd(27);
-							break;
-						case 28:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 101)
-								kind = 101;
-							jjCheckNAddStates(0, 6);
-							break;
-						case 29:
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(29, 24);
-							break;
-						case 30:
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(30, 31);
-							break;
-						case 31:
-							if (curChar == 46)
-								jjCheckNAddTwoStates(32, 24);
-							break;
-						case 32:
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(32, 24);
-							break;
-						case 33:
-							if ((0x3ff000000000000L & l) != 0L)
-								jjCheckNAddTwoStates(33, 34);
-							break;
-						case 34:
-							if (curChar != 46)
-								break;
-							if (kind > 100)
-								kind = 100;
-							jjCheckNAdd(35);
-							break;
-						case 35:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 100)
-								kind = 100;
-							jjCheckNAdd(35);
-							break;
-						case 36:
-							if ((0x3ff000000000000L & l) == 0L)
-								break;
-							if (kind > 101)
-								kind = 101;
-							jjCheckNAdd(36);
-							break;
-						default:
-							break;
-					}
-				}while(i != startsAt);
-			}else if (curChar < 128){
-				long l = 1L << (curChar & 077);
-				do{
-					switch(jjstateSet[--i]){
-						case 12:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x8000000080000L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 11;
-							break;
-						case 37:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							break;
-						case 0:
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x200000002L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 16;
-							else if ((0x1000000010L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 13;
-							break;
-						case 11:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x10000000100000L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 10;
-							break;
-						case 16:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x100000001000L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 15;
-							break;
-						case 13:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x20000000200L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 12;
-							break;
-						case 10:
-							if ((0x7fffffe87fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAdd(21);
-							}
-							if ((0x7fffffe07fffffeL & l) != 0L){
-								if (kind > 97)
-									kind = 97;
-								jjCheckNAddTwoStates(20, 21);
-							}
-							if ((0x20000000200L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 9;
-							break;
-						case 7:
-							if ((0x10000000100000L & l) != 0L && kind > 19)
-								kind = 19;
-							break;
-						case 8:
-							if ((0x800000008L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 7;
-							break;
-						case 9:
-							if ((0x400000004000L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 8;
-							break;
-						case 14:
-							if ((0x1000000010L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 13;
-							break;
-						case 15:
-							if ((0x100000001000L & l) != 0L && kind > 19)
-								kind = 19;
-							break;
-						case 17:
-							if ((0x200000002L & l) != 0L)
-								jjstateSet[jjnewStateCnt++] = 16;
-							break;
-						case 20:
-							if ((0x7fffffe07fffffeL & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAddTwoStates(20, 21);
-							break;
-						case 21:
-							if ((0x7fffffe87fffffeL & l) == 0L)
-								break;
-							if (kind > 97)
-								kind = 97;
-							jjCheckNAdd(21);
-							break;
-						case 24:
-							if ((0x2000000020L & l) != 0L)
-								jjAddStates(7, 8);
-							break;
-						default:
-							break;
-					}
-				}while(i != startsAt);
-			}else{
-				int i2 = (curChar & 0xff) >> 6;
-				long l2 = 1L << (curChar & 077);
-				do{
-					switch(jjstateSet[--i]){
-						default:
-							break;
-					}
-				}while(i != startsAt);
-			}
-			if (kind != 0x7fffffff){
-				jjmatchedKind = kind;
-				jjmatchedPos = curPos;
-				kind = 0x7fffffff;
-			}
-			++curPos;
-			if ((i = jjnewStateCnt) == (startsAt = 37 - (jjnewStateCnt = startsAt)))
-				return curPos;
-			try{
-				curChar = input_stream.readChar();
-			}catch(java.io.IOException e){
-				return curPos;
-			}
-		}
-	}
-
-	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 jjMoveStringLiteralDfa0_2(){
-		switch(curChar){
-			case 39:
-				return jjStartNfaWithStates_2(0, 93, 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);
-	}
-
-	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 ((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;
-			}
-		}
-	}
-
-	private int jjMoveStringLiteralDfa0_1(){
-		return jjMoveNfa_1(0, 0);
-	}
-
-	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 ((0x2400L & l) != 0L){
-								if (kind > 89)
-									kind = 89;
-							}
-							if (curChar == 13)
-								jjstateSet[jjnewStateCnt++] = 1;
-							break;
-						case 1:
-							if (curChar == 10 && kind > 89)
-								kind = 89;
-							break;
-						case 2:
-							if (curChar == 13)
-								jjstateSet[jjnewStateCnt++] = 1;
-							break;
-						default:
-							break;
-					}
-				}while(i != startsAt);
-			}else if (curChar < 128){
-				long l = 1L << (curChar & 077);
-				do{
-					switch(jjstateSet[--i]){
-						default:
-							break;
-					}
-				}while(i != startsAt);
-			}else{
-				int i2 = (curChar & 0xff) >> 6;
-				long l2 = 1L << (curChar & 077);
-				do{
-					switch(jjstateSet[--i]){
-						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 = {29,30,31,24,33,34,36,25,26,};
-
-	/** Token literal values. */
-	public static final String[] jjstrLiteralImages = {"",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,null,};
-
-	/** Lexer state names. */
-	public static final String[] lexStateNames = {"DEFAULT","WithinComment","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,0,-1,2,-1,0,3,-1,0,-1,-1,-1,-1,-1,-1,};
-	static final long[] jjtoToken = {0xfffffffffffffffdL,0x3b20ffffffL,};
-	static final long[] jjtoSkip = {0x2L,0x2000000L,};
-	static final long[] jjtoMore = {0x0L,0xdd000000L,};
-	protected SimpleCharStream input_stream;
-	private final int[] jjrounds = new int[37];
-	private final int[] jjstateSet = new int[74];
-	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;
-	}
+  /** 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_3(int pos, long active0, long active1)
+{
+   switch (pos)
+   {
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_3(int pos, long active0, long active1)
+{
+   return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0, active1), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_3()
+{
+   switch(curChar)
+   {
+      case 34:
+         return jjStartNfaWithStates_3(0, 96, 1);
+      default :
+         return jjMoveNfa_3(0, 0);
+   }
+}
+private int jjStartNfaWithStates_3(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_3(state, pos + 1);
+}
+static final long[] jjbitVec0 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+private int jjMoveNfa_3(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 > 95)
+                        kind = 95;
+                  }
+                  else if (curChar == 34)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 1:
+                  if (curChar == 34 && kind > 95)
+                     kind = 95;
+                  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 = 95;
+                  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 > 95)
+                     kind = 95;
+                  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 & 0xefff1ffdffb40000L) != 0L || (active1 & 0xf0fff4L) != 0L)
+         {
+            jjmatchedKind = 97;
+            return 37;
+         }
+         if ((active0 & 0x1000a00200400000L) != 0L || (active1 & 0xf0002L) != 0L)
+         {
+            jjmatchedKind = 97;
+            return 16;
+         }
+         if ((active0 & 0x10L) != 0L)
+            return 38;
+         if ((active0 & 0x400000000000L) != 0L || (active1 & 0x9L) != 0L)
+         {
+            jjmatchedKind = 97;
+            return 13;
+         }
+         if ((active0 & 0xc000L) != 0L)
+            return 3;
+         if ((active0 & 0x200L) != 0L)
+            return 19;
+         return -1;
+      case 1:
+         if ((active0 & 0xf7ffceebbeb40000L) != 0L || (active1 & 0xfdfdfeL) != 0L)
+         {
+            if (jjmatchedPos != 1)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 1;
+            }
+            return 37;
+         }
+         if ((active0 & 0x800311441400000L) != 0L || (active1 & 0x20200L) != 0L)
+            return 37;
+         if ((active1 & 0x1L) != 0L)
+         {
+            if (jjmatchedPos != 1)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 1;
+            }
+            return 12;
+         }
+         return -1;
+      case 2:
+         if ((active1 & 0x1L) != 0L)
+         {
+            if (jjmatchedPos != 2)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 2;
+            }
+            return 11;
+         }
+         if ((active0 & 0x17a00a00100000L) != 0L || (active1 & 0xf001d2L) != 0L)
+            return 37;
+         if ((active0 & 0xffe85ee1bfa40000L) != 0L || (active1 & 0xffc2cL) != 0L)
+         {
+            if (jjmatchedPos != 2)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 2;
+            }
+            return 37;
+         }
+         return -1;
+      case 3:
+         if ((active0 & 0xefe81e4187840000L) != 0L || (active1 & 0xac2cL) != 0L)
+         {
+            if (jjmatchedPos != 3)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 3;
+            }
+            return 37;
+         }
+         if ((active0 & 0x100040a038200000L) != 0L || (active1 & 0xf5000L) != 0L)
+            return 37;
+         if ((active1 & 0x80L) != 0L)
+         {
+            if (jjmatchedPos != 3)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 3;
+            }
+            return 21;
+         }
+         if ((active1 & 0x1L) != 0L)
+         {
+            if (jjmatchedPos != 3)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 3;
+            }
+            return 10;
+         }
+         return -1;
+      case 4:
+         if ((active0 & 0xef601e4000840000L) != 0L || (active1 & 0x880dL) != 0L)
+         {
+            jjmatchedKind = 97;
+            jjmatchedPos = 4;
+            return 37;
+         }
+         if ((active0 & 0x88000187000000L) != 0L || (active1 & 0x2420L) != 0L)
+            return 37;
+         if ((active1 & 0x80080L) != 0L)
+            return 21;
+         return -1;
+      case 5:
+         if ((active0 & 0x2400a0000040000L) != 0L)
+            return 37;
+         if ((active0 & 0x6000000000000000L) != 0L)
+            return 21;
+         if ((active0 & 0x8d20004000800000L) != 0L || (active1 & 0x880dL) != 0L)
+         {
+            jjmatchedKind = 97;
+            jjmatchedPos = 5;
+            return 37;
+         }
+         if ((active0 & 0x140000000000L) != 0L)
+         {
+            if (jjmatchedPos < 4)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 4;
+            }
+            return -1;
+         }
+         return -1;
+      case 6:
+         if ((active0 & 0x8c20000000000000L) != 0L || (active1 & 0x8001L) != 0L)
+         {
+            jjmatchedKind = 97;
+            jjmatchedPos = 6;
+            return 37;
+         }
+         if ((active0 & 0x100004000800000L) != 0L || (active1 & 0x80cL) != 0L)
+            return 37;
+         if ((active0 & 0x140000000000L) != 0L)
+         {
+            if (jjmatchedPos < 4)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 4;
+            }
+            return -1;
+         }
+         return -1;
+      case 7:
+         if ((active0 & 0x800000000000000L) != 0L)
+         {
+            jjmatchedKind = 97;
+            jjmatchedPos = 7;
+            return 37;
+         }
+         if ((active0 & 0x8420000000000000L) != 0L || (active1 & 0x8001L) != 0L)
+            return 37;
+         if ((active0 & 0x140000000000L) != 0L)
+         {
+            if (jjmatchedPos < 4)
+            {
+               jjmatchedKind = 97;
+               jjmatchedPos = 4;
+            }
+            return -1;
+         }
+         return -1;
+      case 8:
+         if ((active0 & 0x800000000000000L) != 0L)
+         {
+            jjmatchedKind = 97;
+            jjmatchedPos = 8;
+            return 37;
+         }
+         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, 94);
+      case 39:
+         return jjStopAtPos(0, 91);
+      case 40:
+         return jjStopAtPos(0, 2);
+      case 41:
+         return jjStopAtPos(0, 3);
+      case 42:
+         return jjStopAtPos(0, 10);
+      case 43:
+         return jjStopAtPos(0, 8);
+      case 44:
+         return jjStopAtPos(0, 5);
+      case 45:
+         return jjStartNfaWithStates_0(0, 9, 19);
+      case 46:
+         return jjStartNfaWithStates_0(0, 4, 38);
+      case 47:
+         return jjStopAtPos(0, 11);
+      case 59:
+         return jjStopAtPos(0, 6);
+      case 60:
+         jjmatchedKind = 14;
+         return jjMoveStringLiteralDfa1_0(0x8000L, 0x0L);
+      case 61:
+         return jjStopAtPos(0, 12);
+      case 62:
+         jjmatchedKind = 16;
+         return jjMoveStringLiteralDfa1_0(0x20000L, 0x0L);
+      case 65:
+      case 97:
+         return jjMoveStringLiteralDfa1_0(0x1000a00200400000L, 0xf0002L);
+      case 66:
+      case 98:
+         return jjMoveStringLiteralDfa1_0(0x10004000000000L, 0x0L);
+      case 67:
+      case 99:
+         return jjMoveStringLiteralDfa1_0(0xe468000000000000L, 0x300004L);
+      case 68:
+      case 100:
+         return jjMoveStringLiteralDfa1_0(0x400000000000L, 0x9L);
+      case 69:
+      case 101:
+         return jjMoveStringLiteralDfa1_0(0x20000000000L, 0x10L);
+      case 70:
+      case 102:
+         return jjMoveStringLiteralDfa1_0(0x10200000L, 0x20L);
+      case 71:
+      case 103:
+         return jjMoveStringLiteralDfa1_0(0x40000000000L, 0x0L);
+      case 72:
+      case 104:
+         return jjMoveStringLiteralDfa1_0(0x80000000000L, 0x0L);
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa1_0(0x800011001000000L, 0x0L);
+      case 74:
+      case 106:
+         return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L);
+      case 76:
+      case 108:
+         return jjMoveStringLiteralDfa1_0(0x8008000000L, 0xc0L);
+      case 77:
+      case 109:
+         return jjMoveStringLiteralDfa1_0(0x3000000000000L, 0x100L);
+      case 78:
+      case 110:
+         return jjMoveStringLiteralDfa1_0(0x2800800000L, 0x0L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa1_0(0x100442000000L, 0x0L);
+      case 80:
+      case 112:
+         return jjMoveStringLiteralDfa1_0(0x180000000000000L, 0x600L);
+      case 82:
+      case 114:
+         return jjMoveStringLiteralDfa1_0(0x200000004000000L, 0x3800L);
+      case 83:
+      case 115:
+         return jjMoveStringLiteralDfa1_0(0x4000000040000L, 0x404000L);
+      case 84:
+      case 116:
+         return jjMoveStringLiteralDfa1_0(0x100000L, 0x808000L);
+      case 85:
+      case 117:
+         return jjMoveStringLiteralDfa1_0(0x80000000L, 0x0L);
+      case 87:
+      case 119:
+         return jjMoveStringLiteralDfa1_0(0x100000000L, 0x0L);
+      case 124:
+         return jjMoveStringLiteralDfa1_0(0x80L, 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 & 0x8000L) != 0L)
+            return jjStopAtPos(1, 15);
+         else if ((active0 & 0x20000L) != 0L)
+            return jjStopAtPos(1, 17);
+         break;
+      case 65:
+      case 97:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1080000800000L, active1, 0x801800L);
+      case 66:
+      case 98:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2L);
+      case 67:
+      case 99:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000L);
+      case 69:
+      case 101:
+         return jjMoveStringLiteralDfa2_0(active0, 0x220404008040000L, active1, 0xcL);
+      case 72:
+      case 104:
+         return jjMoveStringLiteralDfa2_0(active0, 0x100000000L, active1, 0L);
+      case 73:
+      case 105:
+         if ((active1 & 0x200L) != 0L)
+            return jjStartNfaWithStates_0(1, 73, 37);
+         return jjMoveStringLiteralDfa2_0(active0, 0x42008004000000L, active1, 0x400001L);
+      case 76:
+      case 108:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x20L);
+      case 78:
+      case 110:
+         if ((active0 & 0x40000000L) != 0L)
+            return jjStartNfaWithStates_0(1, 30, 37);
+         else if ((active0 & 0x10000000000L) != 0L)
+         {
+            jjmatchedKind = 40;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0x800000201000000L, active1, 0L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa2_0(active0, 0xe598000820100000L, active1, 0x3025c0L);
+      case 81:
+      case 113:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x4000L);
+      case 82:
+      case 114:
+         if ((active0 & 0x400000000L) != 0L)
+         {
+            jjmatchedKind = 34;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000140000200000L, active1, 0x8000L);
+      case 83:
+      case 115:
+         if ((active0 & 0x400000L) != 0L)
+         {
+            jjmatchedKind = 22;
+            jjmatchedPos = 1;
+         }
+         else if ((active0 & 0x1000000000L) != 0L)
+            return jjStartNfaWithStates_0(1, 36, 37);
+         return jjMoveStringLiteralDfa2_0(active0, 0x200080000000L, active1, 0x20000L);
+      case 84:
+      case 116:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0xc0000L);
+      case 85:
+      case 117:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4002012000000L, active1, 0L);
+      case 86:
+      case 118:
+         return jjMoveStringLiteralDfa2_0(active0, 0x800000000000L, active1, 0L);
+      case 88:
+      case 120:
+         return jjMoveStringLiteralDfa2_0(active0, 0x20000000000L, active1, 0x10L);
+      case 124:
+         if ((active0 & 0x80L) != 0L)
+            return jjStopAtPos(1, 7);
+         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, 0xc0000L);
+      case 67:
+      case 99:
+         if ((active0 & 0x200000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 45, 37);
+         break;
+      case 68:
+      case 100:
+         if ((active0 & 0x200000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 33, 37);
+         else if ((active1 & 0x100L) != 0L)
+            return jjStartNfaWithStates_0(2, 72, 37);
+         return jjMoveStringLiteralDfa3_0(active0, 0x100000000000L, active1, 0x800L);
+      case 69:
+      case 101:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000000100000000L, active1, 0L);
+      case 70:
+      case 102:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000000L, active1, 0L);
+      case 71:
+      case 103:
+         if ((active0 & 0x800000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 47, 37);
+         else if ((active1 & 0x40L) != 0L)
+         {
+            jjmatchedKind = 70;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0x200000004000000L, active1, 0x88L);
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa3_0(active0, 0x800200a0000000L, active1, 0x20004L);
+      case 75:
+      case 107:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000000000L, active1, 0L);
+      case 76:
+      case 108:
+         return jjMoveStringLiteralDfa3_0(active0, 0x100002010040000L, active1, 0L);
+      case 77:
+      case 109:
+         if ((active0 & 0x4000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 50, 37);
+         break;
+      case 78:
+      case 110:
+         if ((active0 & 0x2000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 49, 37);
+         else if ((active1 & 0x400000L) != 0L)
+            return jjStartNfaWithStates_0(2, 86, 37);
+         else if ((active1 & 0x800000L) != 0L)
+            return jjStartNfaWithStates_0(2, 87, 37);
+         return jjMoveStringLiteralDfa3_0(active0, 0x420000001000000L, active1, 0x1000L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa3_0(active0, 0xe000040000200000L, active1, 0x10020L);
+      case 80:
+      case 112:
+         if ((active0 & 0x100000L) != 0L)
+            return jjStartNfaWithStates_0(2, 20, 37);
+         else if ((active1 & 0x10L) != 0L)
+            return jjStartNfaWithStates_0(2, 68, 37);
+         break;
+      case 82:
+      case 114:
+         return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000L, active1, 0x4000L);
+      case 83:
+      case 115:
+         if ((active1 & 0x2L) != 0L)
+            return jjStartNfaWithStates_0(2, 65, 37);
+         else if ((active1 & 0x100000L) != 0L)
+            return jjStartNfaWithStates_0(2, 84, 37);
+         return jjMoveStringLiteralDfa3_0(active0, 0x400000000000L, active1, 0x1L);
+      case 84:
+      case 116:
+         if ((active0 & 0x800000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 35, 37);
+         else if ((active1 & 0x200000L) != 0L)
+            return jjStartNfaWithStates_0(2, 85, 37);
+         return jjMoveStringLiteralDfa3_0(active0, 0x800004002800000L, active1, 0L);
+      case 85:
+      case 117:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000000000000L, active1, 0xa000L);
+      case 86:
+      case 118:
+         return jjMoveStringLiteralDfa3_0(active0, 0x80000000000L, active1, 0L);
+      case 87:
+      case 119:
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x400L);
+      case 88:
+      case 120:
+         if ((active0 & 0x1000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 48, 37);
+         else if ((active0 & 0x10000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 52, 37);
+         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, 0x80L);
+      case 65:
+      case 97:
+         if ((active0 & 0x1000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 60, 37);
+         break;
+      case 67:
+      case 99:
+         if ((active0 & 0x400000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 46, 37);
+         return jjMoveStringLiteralDfa4_0(active0, 0x40000000000000L, active1, 0L);
+      case 68:
+      case 100:
+         if ((active1 & 0x1000L) != 0L)
+            return jjStartNfaWithStates_0(3, 76, 37);
+         break;
+      case 69:
+      case 101:
+         if ((active0 & 0x8000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 39, 37);
+         return jjMoveStringLiteralDfa4_0(active0, 0x800100003040000L, active1, 0x400L);
+      case 72:
+      case 104:
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000L, active1, 0L);
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa4_0(active0, 0x200080000000000L, active1, 0x800L);
+      case 76:
+      case 108:
+         if ((active0 & 0x10000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 28, 37);
+         else if ((active0 & 0x2000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 37, 37);
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x4L);
+      case 77:
+      case 109:
+         if ((active0 & 0x200000L) != 0L)
+            return jjStartNfaWithStates_0(3, 21, 37);
+         break;
+      case 78:
+      case 110:
+         if ((active0 & 0x20000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 29, 37);
+         else if ((active1 & 0x20000L) != 0L)
+            return jjStartNfaWithStates_0(3, 81, 37);
+         else if ((active1 & 0x40000L) != 0L)
+         {
+            jjmatchedKind = 82;
+            jjmatchedPos = 3;
+         }
+         return jjMoveStringLiteralDfa4_0(active0, 0x88000080000000L, active1, 0x8a000L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x20L);
+      case 82:
+      case 114:
+         return jjMoveStringLiteralDfa4_0(active0, 0xe000000100000000L, active1, 0x8L);
+      case 83:
+      case 115:
+         if ((active1 & 0x10000L) != 0L)
+            return jjStartNfaWithStates_0(3, 80, 37);
+         return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L);
+      case 84:
+      case 116:
+         if ((active0 & 0x8000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 27, 37);
+         else if ((active1 & 0x4000L) != 0L)
+            return jjStartNfaWithStates_0(3, 78, 37);
+         return jjMoveStringLiteralDfa4_0(active0, 0x420000000000000L, active1, 0x1L);
+      case 85:
+      case 117:
+         return jjMoveStringLiteralDfa4_0(active0, 0x40000800000L, active1, 0L);
+      case 87:
+      case 119:
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000000L, active1, 0L);
+      case 89:
+      case 121:
+         return jjMoveStringLiteralDfa4_0(active0, 0x100000000000000L, 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 & 0x80L) != 0L)
+            return jjStartNfaWithStates_0(4, 71, 21);
+         break;
+      case 50:
+         if ((active1 & 0x80000L) != 0L)
+            return jjStartNfaWithStates_0(4, 83, 21);
+         break;
+      case 65:
+      case 97:
+         return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0x801L);
+      case 67:
+      case 99:
+         return jjMoveStringLiteralDfa5_0(active0, 0x40000L, active1, 0x8000L);
+      case 68:
+      case 100:
+         if ((active1 & 0x2000L) != 0L)
+            return jjStartNfaWithStates_0(4, 77, 37);
+         return jjMoveStringLiteralDfa5_0(active0, 0xe000000000000000L, active1, 0L);
+      case 69:
+      case 101:
+         if ((active0 & 0x100000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 32, 37);
+         return jjMoveStringLiteralDfa5_0(active0, 0x4000000000L, active1, 0x8L);
+      case 71:
+      case 103:
+         if ((active0 & 0x80000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 31, 37);
+         return jjMoveStringLiteralDfa5_0(active0, 0x100000000000000L, active1, 0L);
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x4L);
+      case 76:
+      case 108:
+         return jjMoveStringLiteralDfa5_0(active0, 0x40000000000000L, active1, 0L);
+      case 78:
+      case 110:
+         return jjMoveStringLiteralDfa5_0(active0, 0x80000000000L, active1, 0L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa5_0(active0, 0x200000000000000L, active1, 0L);
+      case 80:
+      case 112:
+         return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L);
+      case 82:
+      case 114:
+         if ((active0 & 0x1000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 24, 37);
+         else if ((active0 & 0x2000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 25, 37);
+         else if ((active1 & 0x20L) != 0L)
+            return jjStartNfaWithStates_0(4, 69, 37);
+         else if ((active1 & 0x400L) != 0L)
+            return jjStartNfaWithStates_0(4, 74, 37);
+         return jjMoveStringLiteralDfa5_0(active0, 0x820100000800000L, active1, 0L);
+      case 84:
+      case 116:
+         if ((active0 & 0x4000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 26, 37);
+         else if ((active0 & 0x8000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 51, 37);
+         else if ((active0 & 0x80000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 55, 37);
+         return jjMoveStringLiteralDfa5_0(active0, 0x20000000000L, 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 32:
+         return jjMoveStringLiteralDfa6_0(active0, 0x140000000000L, active1, 0L);
+      case 49:
+         if ((active0 & 0x2000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 61, 21);
+         break;
+      case 50:
+         if ((active0 & 0x4000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 62, 21);
+         break;
+      case 65:
+      case 97:
+         return jjMoveStringLiteralDfa6_0(active0, 0x800000L, active1, 0x8000L);
+      case 69:
+      case 101:
+         if ((active0 & 0x40000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 54, 37);
+         return jjMoveStringLiteralDfa6_0(active0, 0x4000000000L, active1, 0x8L);
+      case 71:
+      case 103:
+         if ((active0 & 0x80000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 43, 37);
+         break;
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa6_0(active0, 0x400000000000000L, active1, 0L);
+      case 78:
+      case 110:
+         if ((active0 & 0x200000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 57, 37);
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x805L);
+      case 79:
+      case 111:
+         return jjMoveStringLiteralDfa6_0(active0, 0x120000000000000L, active1, 0L);
+      case 83:
+      case 115:
+         if ((active0 & 0x20000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 41, 37);
+         return jjMoveStringLiteralDfa6_0(active0, 0x8800000000000000L, active1, 0L);
+      case 84:
+      case 116:
+         if ((active0 & 0x40000L) != 0L)
+            return jjStartNfaWithStates_0(5, 18, 37);
+         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 66:
+      case 98:
+         return jjMoveStringLiteralDfa7_0(active0, 0x140000000000L, active1, 0L);
+      case 67:
+      case 99:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x1L);
+      case 69:
+      case 101:
+         return jjMoveStringLiteralDfa7_0(active0, 0x800000000000000L, active1, 0L);
+      case 71:
+      case 103:
+         if ((active1 & 0x4L) != 0L)
+            return jjStartNfaWithStates_0(6, 66, 37);
+         break;
+      case 73:
+      case 105:
+         return jjMoveStringLiteralDfa7_0(active0, 0x20000000000000L, active1, 0L);
+      case 76:
+      case 108:
+         if ((active0 & 0x800000L) != 0L)
+            return jjStartNfaWithStates_0(6, 23, 37);
+         break;
+      case 78:
+      case 110:
+         if ((active0 & 0x4000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 38, 37);
+         else if ((active0 & 0x100000000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 56, 37);
+         return jjMoveStringLiteralDfa7_0(active0, 0x400000000000000L, active1, 0L);
+      case 83:
+      case 115:
+         if ((active1 & 0x8L) != 0L)
+            return jjStartNfaWithStates_0(6, 67, 37);
+         else if ((active1 & 0x800L) != 0L)
+            return jjStartNfaWithStates_0(6, 75, 37);
+         break;
+      case 84:
+      case 116:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x8000L);
+      case 89:
+      case 121:
+         return jjMoveStringLiteralDfa7_0(active0, 0x8000000000000000L, active1, 0L);
+      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, 0x800000000000000L, active1, 0L);
+      case 68:
+      case 100:
+         if ((active0 & 0x20000000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 53, 37);
+         break;
+      case 69:
+      case 101:
+         if ((active1 & 0x1L) != 0L)
+            return jjStartNfaWithStates_0(7, 64, 37);
+         else if ((active1 & 0x8000L) != 0L)
+            return jjStartNfaWithStates_0(7, 79, 37);
+         break;
+      case 83:
+      case 115:
+         if ((active0 & 0x400000000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 58, 37);
+         else if ((active0 & 0x8000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 63, 37);
+         break;
+      case 89:
+      case 121:
+         if ((active0 & 0x40000000000L) != 0L)
+            return jjStopAtPos(7, 42);
+         else if ((active0 & 0x100000000000L) != 0L)
+            return jjStopAtPos(7, 44);
+         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, 0x800000000000000L);
+      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 & 0x800000000000000L) != 0L)
+            return jjStartNfaWithStates_0(9, 59, 37);
+         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 = 37;
+   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 12:
+               case 21:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 38:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 100)
+                        kind = 100;
+                     jjCheckNAdd(27);
+                  }
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(23, 24);
+                  break;
+               case 37:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 101)
+                        kind = 101;
+                     jjCheckNAddStates(0, 6);
+                  }
+                  else if ((0x100002600L & l) != 0L)
+                  {
+                     if (kind > 1)
+                        kind = 1;
+                  }
+                  else if (curChar == 46)
+                     jjCheckNAddTwoStates(23, 27);
+                  else if (curChar == 45)
+                     jjCheckNAdd(19);
+                  else if (curChar == 33)
+                     jjstateSet[jjnewStateCnt++] = 5;
+                  else if (curChar == 60)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 11:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 16:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 13:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 10:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 1:
+                  if (curChar == 10 && kind > 1)
+                     kind = 1;
+                  break;
+               case 2:
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 3:
+                  if (curChar == 62)
+                     kind = 13;
+                  break;
+               case 4:
+                  if (curChar == 60)
+                     jjstateSet[jjnewStateCnt++] = 3;
+                  break;
+               case 5:
+                  if (curChar == 61)
+                     kind = 13;
+                  break;
+               case 6:
+                  if (curChar == 33)
+                     jjstateSet[jjnewStateCnt++] = 5;
+                  break;
+               case 18:
+                  if (curChar == 45)
+                     jjCheckNAdd(19);
+                  break;
+               case 19:
+                  if (curChar != 45)
+                     break;
+                  if (kind > 88)
+                     kind = 88;
+                  jjCheckNAdd(19);
+                  break;
+               case 22:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(23, 27);
+                  break;
+               case 23:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(23, 24);
+                  break;
+               case 25:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(26);
+                  break;
+               case 26:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 99)
+                     kind = 99;
+                  jjCheckNAdd(26);
+                  break;
+               case 27:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 100)
+                     kind = 100;
+                  jjCheckNAdd(27);
+                  break;
+               case 28:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 101)
+                     kind = 101;
+                  jjCheckNAddStates(0, 6);
+                  break;
+               case 29:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(29, 24);
+                  break;
+               case 30:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(30, 31);
+                  break;
+               case 31:
+                  if (curChar == 46)
+                     jjCheckNAddTwoStates(32, 24);
+                  break;
+               case 32:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(32, 24);
+                  break;
+               case 33:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(33, 34);
+                  break;
+               case 34:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 100)
+                     kind = 100;
+                  jjCheckNAdd(35);
+                  break;
+               case 35:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 100)
+                     kind = 100;
+                  jjCheckNAdd(35);
+                  break;
+               case 36:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 101)
+                     kind = 101;
+                  jjCheckNAdd(36);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 12:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x8000000080000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 11;
+                  break;
+               case 37:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  break;
+               case 0:
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x200000002L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 16;
+                  else if ((0x1000000010L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 13;
+                  break;
+               case 11:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x10000000100000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 10;
+                  break;
+               case 16:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x100000001000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 15;
+                  break;
+               case 13:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x20000000200L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 12;
+                  break;
+               case 10:
+                  if ((0x7fffffe87fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAdd(21);
+                  }
+                  if ((0x7fffffe07fffffeL & l) != 0L)
+                  {
+                     if (kind > 97)
+                        kind = 97;
+                     jjCheckNAddTwoStates(20, 21);
+                  }
+                  if ((0x20000000200L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 9;
+                  break;
+               case 7:
+                  if ((0x10000000100000L & l) != 0L && kind > 19)
+                     kind = 19;
+                  break;
+               case 8:
+                  if ((0x800000008L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 7;
+                  break;
+               case 9:
+                  if ((0x400000004000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 8;
+                  break;
+               case 14:
+                  if ((0x1000000010L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 13;
+                  break;
+               case 15:
+                  if ((0x100000001000L & l) != 0L && kind > 19)
+                     kind = 19;
+                  break;
+               case 17:
+                  if ((0x200000002L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 16;
+                  break;
+               case 20:
+                  if ((0x7fffffe07fffffeL & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAddTwoStates(20, 21);
+                  break;
+               case 21:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 97)
+                     kind = 97;
+                  jjCheckNAdd(21);
+                  break;
+               case 24:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(7, 8);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 37 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+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 jjMoveStringLiteralDfa0_2()
+{
+   switch(curChar)
+   {
+      case 39:
+         return jjStartNfaWithStates_2(0, 93, 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);
+}
+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 ((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; }
+   }
+}
+private int jjMoveStringLiteralDfa0_1()
+{
+   return jjMoveNfa_1(0, 0);
+}
+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 ((0x2400L & l) != 0L)
+                  {
+                     if (kind > 89)
+                        kind = 89;
+                  }
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               case 1:
+                  if (curChar == 10 && kind > 89)
+                     kind = 89;
+                  break;
+               case 2:
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 1;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               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 = {
+   29, 30, 31, 24, 33, 34, 36, 25, 26, 
+};
 
-	/** Constructor. */
-	public ADQLParserTokenManager(SimpleCharStream stream, int lexState){
-		this(stream);
-		SwitchTo(lexState);
-	}
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", 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, null, };
 
-	/** Reinitialise parser. */
-	public void ReInit(SimpleCharStream stream){
-		jjmatchedPos = jjnewStateCnt = 0;
-		curLexState = defaultLexState;
-		input_stream = stream;
-		ReInitRounds();
-	}
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+   "DEFAULT",
+   "WithinComment",
+   "WithinString",
+   "WithinDelimitedId",
+};
 
-	private void ReInitRounds(){
-		int i;
-		jjround = 0x80000001;
-		for(i = 37; i-- > 0;)
-			jjrounds[i] = 0x80000000;
-	}
+/** 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, 0, -1, 2, -1, 0, 3, -1, 0, -1, -1, -1, 
+   -1, -1, -1, 
+};
+static final long[] jjtoToken = {
+   0xfffffffffffffffdL, 0x3b20ffffffL, 
+};
+static final long[] jjtoSkip = {
+   0x2L, 0x2000000L, 
+};
+static final long[] jjtoMore = {
+   0x0L, 0xdd000000L, 
+};
+protected SimpleCharStream input_stream;
+private final int[] jjrounds = new int[37];
+private final int[] jjstateSet = new int[74];
+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;
+}
 
-	/** Reinitialise parser. */
-	public void ReInit(SimpleCharStream stream, int lexState){
-		ReInit(stream);
-		SwitchTo(lexState);
-	}
+/** Constructor. */
+public ADQLParserTokenManager(SimpleCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
 
-	/** Switch to specified lex state. */
-	public void SwitchTo(int lexState){
-		if (lexState >= 4 || lexState < 0)
-			throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-		else
-			curLexState = 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 = 37; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
 
-	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);
+/** Reinitialise parser. */
+public void ReInit(SimpleCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
 
-		t.beginLine = beginLine;
-		t.endLine = endLine;
-		t.beginColumn = beginColumn;
-		t.endColumn = endColumn;
+/** Switch to specified lex state. */
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 4 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
 
-		return t;
-	}
+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);
 
-	int curLexState = 0;
-	int defaultLexState = 0;
-	int jjnewStateCnt;
-	int jjround;
-	int jjmatchedPos;
-	int jjmatchedKind;
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
 
-	/** Get the next Token. */
-	public Token getNextToken(){
-		Token matchedToken;
-		int curPos = 0;
+   return t;
+}
 
-		EOFLoop: for(;;){
-			try{
-				curChar = input_stream.BeginToken();
-			}catch(java.io.IOException e){
-				jjmatchedKind = 0;
-				matchedToken = jjFillToken();
-				return matchedToken;
-			}
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
 
-			for(;;){
-				switch(curLexState){
-					case 0:
-						jjmatchedKind = 0x7fffffff;
-						jjmatchedPos = 0;
-						curPos = jjMoveStringLiteralDfa0_0();
-						break;
-					case 1:
-						jjmatchedKind = 0x7fffffff;
-						jjmatchedPos = 0;
-						curPos = jjMoveStringLiteralDfa0_1();
-						if (jjmatchedPos == 0 && jjmatchedKind > 90){
-							jjmatchedKind = 90;
-						}
-						break;
-					case 2:
-						jjmatchedKind = 0x7fffffff;
-						jjmatchedPos = 0;
-						curPos = jjMoveStringLiteralDfa0_2();
-						break;
-					case 3:
-						jjmatchedKind = 0x7fffffff;
-						jjmatchedPos = 0;
-						curPos = jjMoveStringLiteralDfa0_3();
-						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);
-			}
-		}
-	}
+/** Get the next Token. */
+public Token getNextToken() 
+{
+  Token matchedToken;
+  int curPos = 0;
 
-	private void jjCheckNAdd(int state){
-		if (jjrounds[state] != jjround){
-			jjstateSet[jjnewStateCnt++] = state;
-			jjrounds[state] = jjround;
-		}
-	}
+  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.BeginToken();
+   }
+   catch(java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      return matchedToken;
+   }
 
-	private void jjAddStates(int start, int end){
-		do{
-			jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-		}while(start++ != end);
-	}
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         if (jjmatchedPos == 0 && jjmatchedKind > 90)
+         {
+            jjmatchedKind = 90;
+         }
+         break;
+       case 2:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_2();
+         break;
+       case 3:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_3();
+         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 jjCheckNAddTwoStates(int state1, int state2){
-		jjCheckNAdd(state1);
-		jjCheckNAdd(state2);
-	}
+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);
-	}
+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 daef3dc..12887f4 100644
--- a/src/adql/parser/ADQLQueryFactory.java
+++ b/src/adql/parser/ADQLQueryFactory.java
@@ -16,7 +16,8 @@ package adql.parser;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.Collection;
@@ -30,26 +31,24 @@ import adql.query.ColumnReference;
 import adql.query.IdentifierField;
 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.ADQLConstraint;
-import adql.query.constraint.ConstraintsGroup;
 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.ADQLTable;
-import adql.query.from.FromContent;
 import adql.query.from.CrossJoin;
+import adql.query.from.FromContent;
 import adql.query.from.InnerJoin;
 import adql.query.from.OuterJoin;
 import adql.query.from.OuterJoin.OuterType;
-
-import adql.query.operand.ADQLOperand;
 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;
@@ -57,14 +56,12 @@ 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.DefaultUDF;
 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.GeometryValue;
 import adql.query.operand.function.geometry.AreaFunction;
 import adql.query.operand.function.geometry.BoxFunction;
 import adql.query.operand.function.geometry.CentroidFunction;
@@ -74,6 +71,7 @@ import adql.query.operand.function.geometry.DistanceFunction;
 import adql.query.operand.function.geometry.ExtractCoord;
 import adql.query.operand.function.geometry.ExtractCoordSys;
 import adql.query.operand.function.geometry.GeometryFunction;
+import adql.query.operand.function.geometry.GeometryFunction.GeometryValue;
 import adql.query.operand.function.geometry.IntersectsFunction;
 import adql.query.operand.function.geometry.PointFunction;
 import adql.query.operand.function.geometry.PolygonFunction;
@@ -84,8 +82,8 @@ import adql.query.operand.function.geometry.RegionFunction;
  * 
  * <p>To customize the object representation you merely have to extends the appropriate functions of this class.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 08/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  * 
  * @see ADQLParser
  */
@@ -122,9 +120,6 @@ public class ADQLQueryFactory {
 			caseSensitivity = IdentifierField.ALIAS.setCaseSensitive(caseSensitivity, alias.caseSensitivity);
 		t.setCaseSensitive(caseSensitivity);
 
-		// Set the position in the query:
-		t.setPosition(idItems.getPosition());
-
 		return t;
 	}
 
@@ -378,6 +373,18 @@ public class ADQLQueryFactory {
 		return new IntersectsFunction(left, right);
 	}
 
+	/**
+	 * Replace {@link #createOrder(int, boolean, TextPosition)}.
+	 * @since 1.3
+	 */
+	public ADQLOrder createOrder(final int ind, final boolean desc) throws Exception{
+		return new ADQLOrder(ind, desc);
+	}
+
+	/**
+	 * @deprecated since 1.3 ; Replaced by {@link #createOrder(int, boolean)}
+	 */
+	@Deprecated
 	public ADQLOrder createOrder(final int ind, final boolean desc, final TextPosition position) throws Exception{
 		ADQLOrder order = new ADQLOrder(ind, desc);
 		if (order != null)
@@ -387,10 +394,8 @@ public class ADQLQueryFactory {
 
 	public ADQLOrder createOrder(final IdentifierItems idItems, final boolean desc) throws Exception{
 		ADQLOrder order = new ADQLOrder(idItems.join("."), desc);
-		if (order != null){
-			order.setPosition(idItems.getPosition());
+		if (order != null)
 			order.setCaseSensitive(idItems.getColumnCaseSensitivity());
-		}
 		return order;
 	}
 
diff --git a/src/adql/parser/adqlGrammar.jj b/src/adql/parser/adqlGrammar.jj
index bfac21d..cc2d75e 100644
--- a/src/adql/parser/adqlGrammar.jj
+++ b/src/adql/parser/adqlGrammar.jj
@@ -721,7 +721,7 @@ ADQLQuery Query(): {ADQLQuery q = null;}{
 	}
 }
 
-ADQLQuery QueryExpression(): {} {
+ADQLQuery QueryExpression(): {TextPosition endPos = null;} {
 	{
 		try{
 			// create the query:
@@ -732,12 +732,15 @@ ADQLQuery QueryExpression(): {} {
 		}
 	}
 	Select()
-	From()
-	[Where()]
-	[GroupBy()]
-	[Having()]
-	[OrderBy()]
+	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())
@@ -749,13 +752,16 @@ ADQLQuery QueryExpression(): {} {
 	}
 }
 
-ADQLQuery SubQueryExpression(): {ADQLQuery q = null;} {
-	<LEFT_PAR> q=QueryExpression() <RIGHT_PAR>
-	{return q;}
+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 t = null;} {
-	<SELECT>
+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>
 	 {
@@ -769,11 +775,20 @@ void Select(): {ClauseSelect select = query.getSelect(); SelectItem item=null; T
 	
 	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 SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true); IdentifierItem id = null, label = null; ADQLOperand op = null; SelectItem item; Token starToken;} {
 	(
-		( <ASTERISK> {return new SelectAllColumns(query);} )
+		( starToken=<ASTERISK>
+		  {
+		    item = new SelectAllColumns(query);
+		    item.setPosition(new TextPosition(starToken));
+		    return item;
+		  }
+		)
 	|LOOKAHEAD(7)
 		(
 			id=Identifier() <DOT> { identifiers.append(id); }
@@ -783,10 +798,13 @@ SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true
 					id=Identifier() <DOT> { identifiers.append(id); }
 				)?
 			)?
-			<ASTERISK>
+			starToken=<ASTERISK>
 			{
-				try{;
-					return new SelectAllColumns( queryFactory.createTable(identifiers, null) );
+				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);
 				}
@@ -799,9 +817,11 @@ SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true
 	
 	{
 		try{
-			SelectItem item = queryFactory.createSelectItem(op, (label==null)?null:label.identifier);
-			if (label != null)
+			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);
@@ -812,29 +832,45 @@ SelectItem SelectItem(): {IdentifierItems identifiers = new IdentifierItems(true
 void From():{FromContent content = null, content2 = null;}{
 	try{
 		<FROM> content=TableRef()
-		(<COMMA> content2=TableRef() { content = queryFactory.createJoin(JoinType.CROSS, content, content2); } )*
+		(<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;} {
-	<WHERE> ConditionsList(where)
+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<ColumnReference> groupBy = query.getGroupBy(); ColumnReference colRef = null;} {
-	<GROUP_BY> colRef=ColumnRef() { groupBy.add(colRef); }
+void GroupBy(): {ClauseADQL<ColumnReference> groupBy = query.getGroupBy(); ColumnReference colRef = null; Token start;} {
+	start=<GROUP_BY> colRef=ColumnRef() { groupBy.add(colRef); }
 	( <COMMA> colRef=ColumnRef() { groupBy.add(colRef); } )*
+	{ groupBy.setPosition(new TextPosition(start.beginLine, start.beginColumn, colRef.getPosition().endLine, colRef.getPosition().endColumn)); }
 }
 
-void Having(): {ClauseConstraints having = query.getHaving();} {
-	<HAVING> ConditionsList(having)
+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;} {
-	<ORDER_BY> order=OrderItem() {orderBy.add(order);}
+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.beginLine, start.beginColumn, order.getPosition().endLine, order.getPosition().endColumn)); }
 }
 
 /* *************************** */
@@ -913,10 +949,13 @@ ADQLOrder OrderItem(): {IdentifierItems identifiers = null; Token ind = null, de
 	{
 		try{
 			ADQLOrder order = null;
-			if (identifiers != null)
+			if (identifiers != null){
 				order = queryFactory.createOrder(identifiers, desc!=null);
-			else
-				order = queryFactory.createOrder(Integer.parseInt(ind.image), desc!=null, new TextPosition(ind));
+				order.setPosition(identifiers.getPosition());
+			}else{
+				order = queryFactory.createOrder(Integer.parseInt(ind.image), desc!=null);
+				order.setPosition(new TextPosition(ind));
+			}
 			return order;
 		}catch(Exception ex){
 			throw generateParseException(ex);
@@ -924,17 +963,34 @@ ADQLOrder OrderItem(): {IdentifierItems identifiers = null; Token ind = null, de
 	}
 }
 
-FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null;} {
+FromContent SimpleTableRef(): {IdentifierItem alias = null; IdentifierItems identifiers = null; ADQLQuery subQuery = null; FromContent content = null; Token start,end;} {
 	try{
 		(
 			identifiers=TableName() [[<AS>] alias=Identifier()]
-			{ return queryFactory.createTable(identifiers, alias); }
+			{
+			  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()
-			{ return queryFactory.createTable(subQuery, alias); }
+			{
+			  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;
+			}
 		|
-			<LEFT_PAR> content=JoinedTable() <RIGHT_PAR>
-			{ return content; }
+			start=<LEFT_PAR> content=JoinedTable() end=<RIGHT_PAR>
+			{
+			  content.setPosition(new TextPosition(start, end));
+			  return content;
+			}
 		)
 	}catch(Exception ex){
 		throw generateParseException(ex);
@@ -954,24 +1010,36 @@ FromContent JoinedTable(): { FromContent 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 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=TableRef()
-			{ return queryFactory.createJoin(type, leftTable, rightTable); }
+			{
+			  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=TableRef()
 			(
 				<ON> ConditionsList(condition)
-				{ return queryFactory.createJoin(type, leftTable, rightTable, 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) ); }
-						)* <RIGHT_PAR>
-				{ return queryFactory.createJoin(type, leftTable, rightTable, lstColumns); }
+						)* 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){
@@ -982,49 +1050,83 @@ ADQLJoin JoinSpecification(FromContent leftTable): { boolean natural = false; Jo
 /* ****** */
 /* STRING */
 /* ****** */
-String String(): {Token t; String str="";} {
+StringConstant String(): {Token t; String str=""; StringConstant cst;} {
 	(t=<STRING_LITERAL> {str += t.image;})+
-	{return (str!=null)?str.substring(1,str.length()-1):str;}
+	{
+		try{
+		  str = (str!=null)?str.substring(1,str.length()-1):str;
+		  cst = queryFactory.createStringConstant(str);
+		  cst.setPosition(new TextPosition(t));
+		  return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
 }
 
 /* ************* */
 /* NUMERIC TYPES */
 /* ************* */
-String UnsignedNumeric(): {Token t;} {
+NumericConstant UnsignedNumeric(): {Token t; NumericConstant cst;} {
 	(t=<SCIENTIFIC_NUMBER>
 	| t=<UNSIGNED_FLOAT>
 	| t=<UNSIGNED_INTEGER>)
-	{return t.image;}
+	{
		try{
+		  cst = queryFactory.createNumericConstant(t.image);
+		  cst.setPosition(new TextPosition(t));
+		  return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
 }
 
-String UnsignedFloat(): {Token t;} {
+NumericConstant UnsignedFloat(): {Token t; NumericConstant cst;} {
 	(t=<UNSIGNED_INTEGER>
 	| t=<UNSIGNED_FLOAT>)
-	{return t.image;}
+	{
+		try{
+			cst = queryFactory.createNumericConstant(t.image);
+		  	cst.setPosition(new TextPosition(t));
+			return cst;
+		}catch(Exception ex){
+			throw generateParseException(ex);
+		}
+	}
 }
 
-String SignedInteger(): {Token sign=null, number;} {
+NumericConstant SignedInteger(): {Token sign=null, number; NumericConstant cst;} {
 	((sign=<PLUS>|sign=<MINUS>)? number=<UNSIGNED_INTEGER>)
-	{return ((sign==null)?"":sign.image)+number.image;}
+	{
+		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 ValueExpressionPrimary(): {String expr; ADQLColumn column; ADQLOperand op;} {
-	try{
+ADQLOperand ValueExpressionPrimary(): {ADQLColumn column; ADQLOperand op; Token left,right;} {
+  	try{
 		(// unsigned_value_specification
-		  expr=UnsignedNumeric() {return queryFactory.createNumericConstant(expr);}
+		  op=UnsignedNumeric() {return op;}
 		// string
-		| expr=String() {return queryFactory.createStringConstant(expr);}
+		| op=String() {return op;}
 		// column_reference
 		| column=Column() {return column;}
 		// set_function_specification
 		| op=SqlFunction() {return op;}
 		// LEFT_PAR value_expression RIGHT_PAR
-		| (<LEFT_PAR> op=ValueExpression() <RIGHT_PAR>) {return queryFactory.createWrappedOperand(op);})
-	}catch(Exception ex){
-		throw generateParseException(ex);
+		| (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);
 	}
 }
 
@@ -1044,7 +1146,9 @@ ADQLOperand NumericExpression(): {Token sign=null; ADQLOperand leftOp, rightOp=n
 		return leftOp;
 	else{
 		try{
-			return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+			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);
 		}
@@ -1059,7 +1163,9 @@ ADQLOperand NumericTerm(): {Token sign=null; ADQLOperand leftOp, rightOp=null;}
 		return leftOp;
 	else{
 		try{
-			return queryFactory.createOperation(leftOp, OperationType.getOperator(sign.image), rightOp);
+			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);
 		}
@@ -1067,9 +1173,9 @@ ADQLOperand NumericTerm(): {Token sign=null; ADQLOperand leftOp, rightOp=null;}
 	}
 }
 
-ADQLOperand Factor(): {boolean negative = false;; ADQLOperand op;} {
+ADQLOperand Factor(): {boolean negative = false; Token minusSign = null; ADQLOperand op;} {
 	(
-		(<PLUS> | (<MINUS> {negative = true;}))?
+		(<PLUS> | (minusSign=<MINUS> {negative = true;}))?
 		(LOOKAHEAD(2) op=NumericFunction() | op=ValueExpressionPrimary())
 	)
 	
@@ -1077,6 +1183,8 @@ ADQLOperand Factor(): {boolean negative = false;; ADQLOperand op;} {
 		if (negative){
 			try{
 				op = queryFactory.createNegativeOperand(op);
+				NegativeOperand negativeOp = (NegativeOperand)op;
+				negativeOp.setPosition(new TextPosition(minusSign.beginLine, minusSign.beginColumn, negativeOp.getPosition().endLine, negativeOp.getPosition().endColumn));
 			}catch(Exception ex){
 				throw generateParseException(ex);
 			}
@@ -1104,7 +1212,12 @@ ADQLOperand StringExpression(): {ADQLOperand leftOp; ADQLOperand rightOp = null;
 			((Concatenation)leftOp).add(rightOp);
 		}
 	)*
-	{ return leftOp; }
+	{
+		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;} {
@@ -1129,11 +1242,15 @@ GeometryValue<GeometryFunction> GeometryExpression(): {ADQLColumn col = null; Ge
 /* ********************************** */
 ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint constraint = null; Token op = null; boolean notOp = false;} {
 	try{
-		[<NOT> {notOp = true;}]
+		[op=<NOT> {notOp = true;}]
 		constraint=Constraint()
 		{
-			if (notOp) constraint = queryFactory.createNot(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
@@ -1144,8 +1261,13 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons
 			[<NOT> {notOp = true;}]
 			constraint=Constraint()
 			{
-				if (notOp) constraint = queryFactory.createNot(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
@@ -1155,13 +1277,19 @@ ClauseConstraints ConditionsList(ClauseConstraints clause): {ADQLConstraint cons
 	}catch(Exception ex){
 		throw generateParseException(ex);
 	}
-	{return clause;}
+	{
+	  	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;} {
+ADQLConstraint Constraint(): {ADQLConstraint constraint =  null; Token start, end;} {
 	(LOOKAHEAD(Predicate()) constraint=Predicate()
 	| (
-		<LEFT_PAR>
+		start=<LEFT_PAR>
 		{
 			try{
 				constraint = queryFactory.createGroupOfConstraints();
@@ -1170,19 +1298,37 @@ ADQLConstraint Constraint(): {ADQLConstraint constraint =  null;} {
 			}
 		}
 		ConditionsList((ConstraintsGroup)constraint)
-		<RIGHT_PAR>
+		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 notToken = null; ADQLConstraint constraint = null;} {
+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
-		((<EXISTS> q=SubQueryExpression()) {return queryFactory.createExists(q);}
+		((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>] <NULL> {return queryFactory.createIsNull((notToken!=null), column);})
+		| 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() {return queryFactory.createComparison(strExpr1, (notToken==null)?ComparisonOperator.LIKE:ComparisonOperator.NOTLIKE, strExpr2);})
+		| 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))
@@ -1202,39 +1348,49 @@ 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{
-			return queryFactory.createComparison(leftOp, ComparisonOperator.getOperator(comp.image), rightOp);
+		  	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 notToken=null; ADQLOperand min, max;} {
-	[notToken=<NOT>] <BETWEEN> min=ValueExpression() <AND> max=ValueExpression()
+Between BetweenEnd(ADQLOperand leftOp): {Token start,notToken=null; ADQLOperand min, max;} {
+	[notToken=<NOT>] start=<BETWEEN> min=ValueExpression() <AND> max=ValueExpression()
 	{
 		try{
-			return queryFactory.createBetween((notToken!=null), leftOp, min, max);
+		  	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; ADQLQuery q = null; ADQLOperand item; Vector<ADQLOperand> items = new Vector<ADQLOperand>();} {
-	[not=<NOT>] <IN>
+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{
-			if (q != null)
-				return queryFactory.createIn(leftOp, q, not!=null);
-			else{
+		  	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;
-				return queryFactory.createIn(leftOp, list, not!=null);
+				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);
 		}
@@ -1245,14 +1401,20 @@ In InEnd(ADQLOperand leftOp): {Token not=null; ADQLQuery q = null; ADQLOperand i
 /* ************* */
 /* SQL FUNCTIONS */
 /* ************* */
-SQLFunction SqlFunction(): {Token fct, all=null, distinct=null; ADQLOperand op=null; SQLFunction funct = null;}{
+SQLFunction SqlFunction(): {Token fct, all=null, distinct=null, end; ADQLOperand op=null; SQLFunction funct = null;}{
 	try{
 		(
-			(<COUNT> <LEFT_PAR> [distinct=<QUANTIFIER>] (all=<ASTERISK> | op=ValueExpression()) <RIGHT_PAR>
-			{ funct = queryFactory.createSQLFunction((all!=null)?SQLFunctionType.COUNT_ALL:SQLFunctionType.COUNT, op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); })
+			(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() <RIGHT_PAR> 
-			{ funct = queryFactory.createSQLFunction(SQLFunctionType.valueOf(fct.image.toUpperCase()), op, distinct != null && distinct.image.equalsIgnoreCase("distinct")); })
+			((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);
@@ -1269,22 +1431,22 @@ ADQLOperand[] Coordinates(): {ADQLOperand[] ops = new ADQLOperand[2];} {
 	{return ops;}
 }
 
-GeometryFunction GeometryFunction(): {Token t=null; GeometryValue<GeometryFunction> gvf1, gvf2; GeometryValue<PointFunction> gvp1, gvp2; GeometryFunction gf = null; PointFunction p1=null, p2=null; ADQLColumn col1 = null, col2 = null;} {
+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
 		(
-			((t=<CONTAINS> | t=<INTERSECTS>) <LEFT_PAR> gvf1=GeometryExpression() <COMMA> gvf2=GeometryExpression() <RIGHT_PAR>
+			((fct=<CONTAINS> | fct=<INTERSECTS>) <LEFT_PAR> gvf1=GeometryExpression() <COMMA> gvf2=GeometryExpression() end=<RIGHT_PAR>
 			{
-				if (t.image.equalsIgnoreCase("contains"))
+				if (fct.image.equalsIgnoreCase("contains"))
 					gf = queryFactory.createContains(gvf1, gvf2);
 				else
 					gf = queryFactory.createIntersects(gvf1, gvf2);
 			})
 		// non_predicate_geometry_function
-		|	(<AREA> <LEFT_PAR> gvf1=GeometryExpression() <RIGHT_PAR>) {gf = queryFactory.createArea(gvf1);}
-		|	(<COORD1> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord1(p1);} | col1=Column() {gf = queryFactory.createCoord1(col1);}) <RIGHT_PAR>)
-		|	(<COORD2> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {gf = queryFactory.createCoord2(col1);}) <RIGHT_PAR>)
-		|	(<DISTANCE>
+		|	(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() {gf = queryFactory.createCoord1(col1);}) end=<RIGHT_PAR>)
+		|	(fct=<COORD2> <LEFT_PAR> (p1=Point() {gf = queryFactory.createCoord2(p1);} | col1=Column() {gf = queryFactory.createCoord2(col1);}) end=<RIGHT_PAR>)
+		|	(fct=<DISTANCE>
 				<LEFT_PAR>
 				(p1=Point()|col1=Column()) 
 				{
@@ -1301,7 +1463,7 @@ GeometryFunction GeometryFunction(): {Token t=null; GeometryValue<GeometryFuncti
 					else
 						gvp2 = new GeometryValue<PointFunction>(col2);
 				} 
-				<RIGHT_PAR>
+				end=<RIGHT_PAR>
 				{gf = queryFactory.createDistance(gvp1, gvp2);}
 			)
 		)
@@ -1309,7 +1471,10 @@ GeometryFunction GeometryFunction(): {Token t=null; GeometryValue<GeometryFuncti
 		throw generateParseException(ex);
 	}
 	
-	{ return gf; }
+	{
+	  gf.setPosition(new TextPosition(fct, end));
+	  return gf;
+	}
 }
 
 ADQLOperand CoordinateSystem(): { Token oldToken = token; ADQLOperand coordSys=null;}{
@@ -1327,62 +1492,70 @@ ADQLOperand CoordinateSystem(): { Token oldToken = token; ADQLOperand coordSys=n
 	}
 }
 
-GeometryFunction GeometryValueFunction(): {ADQLOperand coordSys; ADQLOperand width, height; ADQLOperand[] coords, tmp; Vector<ADQLOperand> vCoords; ADQLOperand op=null; GeometryValue<GeometryFunction> gvf = null; GeometryFunction gf = null;} {
+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:
-		((<BOX> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+		((fct=<BOX> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
 				<COMMA> coords=Coordinates() // coordinates
-				<COMMA> width=NumericExpression() <COMMA> height=NumericExpression() <RIGHT_PAR>)
+				<COMMA> width=NumericExpression() <COMMA> height=NumericExpression() end=<RIGHT_PAR>)
 		 {gf = queryFactory.createBox(coordSys, coords[0], coords[1], width, height);}
 		 
 		// CENTROID:
-		| (<CENTROID> <LEFT_PAR> gvf=GeometryExpression() <RIGHT_PAR>) {gf = queryFactory.createCentroid(gvf);}
+		| (fct=<CENTROID> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>) {gf = queryFactory.createCentroid(gvf);}
 		
 		// CIRCLE:
-		| (<CIRCLE> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+		| (fct=<CIRCLE> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
 				<COMMA> coords=Coordinates() // coordinates
-				<COMMA> width=NumericExpression() <RIGHT_PAR>) // radius
+				<COMMA> width=NumericExpression() end=<RIGHT_PAR>) // radius
 		 {gf = queryFactory.createCircle(coordSys, coords[0], coords[1], width);}
 		
 		// POINT: 
 		| gf=Point()
 		
 		// POLYGON:
-		| (<POLYGON> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
+		| (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]);})*
-				<RIGHT_PAR>)
+				end=<RIGHT_PAR>)
 		  { gf = queryFactory.createPolygon(coordSys, vCoords); }
 		  
 		// REGION:
-		| (<REGION> <LEFT_PAR> op=StringExpression() <RIGHT_PAR>) {gf = queryFactory.createRegion(op);})
+		| (fct=<REGION> <LEFT_PAR> op=StringExpression() end=<RIGHT_PAR>) {gf = queryFactory.createRegion(op);})
 	}catch(Exception ex){
 		throw generateParseException(ex);
 	}
 	
-	{return gf;}
+	{
+	  if (fct != null && end != null) // = !(gf instanceof Point)
+	  	gf.setPosition(new TextPosition(fct, end));
+	  return gf;
+	}
 }
 
-PointFunction Point(): {ADQLOperand coordSys; ADQLOperand[] coords;} {
-	<POINT> <LEFT_PAR> coordSys=CoordinateSystem() // coord_sys
-			<COMMA> coords=Coordinates() <RIGHT_PAR> // coordinates
+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{
-			return queryFactory.createPoint(coordSys, coords[0], coords[1]);
+			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(): {GeometryValue<GeometryFunction> gvf;} {
-	<COORDSYS> <LEFT_PAR> gvf=GeometryExpression() <RIGHT_PAR>
+GeometryFunction ExtractCoordSys(): {Token start, end; GeometryValue<GeometryFunction> gvf;} {
+	start=<COORDSYS> <LEFT_PAR> gvf=GeometryExpression() end=<RIGHT_PAR>
 	{
 		try{
-			return queryFactory.createExtractCoordSys(gvf);
+			GeometryFunction gf = queryFactory.createExtractCoordSys(gvf);
+			gf.setPosition(new TextPosition(start, end));
+			return gf;
 		}catch(Exception ex){
 			throw generateParseException(ex);
 		}
@@ -1400,27 +1573,28 @@ ADQLFunction NumericFunction(): {ADQLFunction fct;} {
 	{return fct;}
 }
 
-MathFunction MathFunction(): {Token fct=null; ADQLOperand param1=null, param2=null; String integerValue = null;} {
+MathFunction MathFunction(): {Token fct=null, end; ADQLOperand param1=null, param2=null; NumericConstant integerValue = null;} {
 	try{
-		((fct=<ABS> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<CEILING> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<DEGREES> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<EXP> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<FLOOR> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<LOG> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<LOG10> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<MOD> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() <RIGHT_PAR>)
-		| (fct=<PI> <LEFT_PAR><RIGHT_PAR>)
-		| (fct=<POWER> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() <RIGHT_PAR>)
-		| (fct=<RADIANS> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<RAND> <LEFT_PAR> (param1=NumericExpression())? <RIGHT_PAR>)
-		| (fct=<ROUND> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? <RIGHT_PAR>)
-		| (fct=<SQRT> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-		| (fct=<TRUNCATE> <LEFT_PAR> param1=NumericExpression() (<COMMA> integerValue=SignedInteger() {param2 = queryFactory.createNumericConstant(integerValue);})? <RIGHT_PAR>))
+		((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>))
 		{
-			if (param1 != null)
-				return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
-			else
+			if (param1 != null){
			  	MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+			  	mf.setPosition(new TextPosition(fct, end));
+				return mf;
+			}else
 				return null;
 		}
 	}catch(Exception ex){
@@ -1428,20 +1602,21 @@ MathFunction MathFunction(): {Token fct=null; ADQLOperand param1=null, param2=nu
 	}
 }
 
-MathFunction TrigFunction(): {Token fct=null; ADQLOperand param1=null, param2=null;} {
-	((fct=<ACOS> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<ASIN> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<ATAN> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<ATAN2> <LEFT_PAR> param1=NumericExpression() <COMMA> param2=NumericExpression() <RIGHT_PAR>)
-	| (fct=<COS> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<COT> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<SIN> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>)
-	| (fct=<TAN> <LEFT_PAR> param1=NumericExpression() <RIGHT_PAR>))
+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{
-			if (param1 != null)
-				return queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
-			else
+			if (param1 != null){
			  	MathFunction mf = queryFactory.createMathFunction(MathFunctionType.valueOf(fct.image.toUpperCase()), param1, param2);
+			  	mf.setPosition(new TextPosition(fct, end));
+			  	return mf;
+			}else
 				return null;
 		}catch(Exception ex){
 			throw generateParseException(ex);
@@ -1450,15 +1625,17 @@ MathFunction TrigFunction(): {Token fct=null; ADQLOperand param1=null, param2=nu
 }
 
 /* /!\ WARNING: The function name may be prefixed by "udf_" but there is no way to check it here ! */
-UserDefinedFunction UserDefinedFunction(): {Token fct; Vector<ADQLOperand> params = new Vector<ADQLOperand>(); ADQLOperand op;} {
-	fct=<REGULAR_IDENTIFIER> <LEFT_PAR> (op=ValueExpression() {params.add(op);} (<COMMA> op=ValueExpression() {params.add(op);})*)? <RIGHT_PAR>
+UserDefinedFunction UserDefinedFunction(): {Token fct, end; Vector<ADQLOperand> params = new Vector<ADQLOperand>(); ADQLOperand op;} {
+	fct=<REGULAR_IDENTIFIER> <LEFT_PAR> (op=ValueExpression() {params.add(op);} (<COMMA> op=ValueExpression() {params.add(op);})*)? end=<RIGHT_PAR>
 	{
 		//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{
 			ADQLOperand[] parameters = new ADQLOperand[params.size()];
 			for(int i=0; i<params.size(); i++)
 				parameters[i] = params.get(i);
-			return queryFactory.createUserDefinedFunction(fct.image, parameters);
+			UserDefinedFunction udf = queryFactory.createUserDefinedFunction(fct.image, parameters);
+			udf.setPosition(new TextPosition(fct, end));
+			return udf;
 		}catch(UnsupportedOperationException uoe){
 			throw new ParseException(uoe.getMessage(), new TextPosition(fct, token));
 		}catch(Exception ex){
diff --git a/src/adql/query/ADQLList.java b/src/adql/query/ADQLList.java
index 25d5933..5c6371f 100644
--- a/src/adql/query/ADQLList.java
+++ b/src/adql/query/ADQLList.java
@@ -43,6 +43,10 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	/** List of ADQL items. */
 	private final Vector<T> list = new Vector<T>();
 
+	/** Position inside an ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds an ADQLList with only its name. This name will always prefix the list.
 	 * 
@@ -70,6 +74,7 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 		this(toCopy.getName());
 		for(T obj : toCopy)
 			add((T)obj.getCopy());
+		position = (toCopy.position != null) ? new TextPosition(toCopy.position) : null;
 	}
 
 	/**
@@ -82,8 +87,13 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	public boolean add(T item) throws NullPointerException{
 		if (item == null)
 			throw new NullPointerException("It is impossible to add NULL items to an ADQL clause !");
-		else
-			return list.add(item);
+		else{
+			if (list.add(item)){
+				position = null;
+				return true;
+			}else
+				return false;
+		}
 	}
 
 	/**
@@ -95,9 +105,10 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	 * @throws ArrayIndexOutOfBoundsException	If the index is out of range (index < 0 || index > size()).
 	 */
 	public void add(int index, T item) throws NullPointerException, ArrayIndexOutOfBoundsException{
-		if (item != null)
+		if (item != null){
 			list.add(index, item);
-		else
+			position = null;
+		}else
 			throw new NullPointerException("It is impossible to add NULL items to an ADQL clause !");
 	}
 
@@ -111,9 +122,11 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	 * @throws ArrayIndexOutOfBoundsException	If the index is out of range (index < 0 || index > size()).
 	 */
 	public T set(int index, T item) throws NullPointerException, ArrayIndexOutOfBoundsException{
-		if (item != null)
-			return list.set(index, item);
-		else
+		if (item != null){
+			T removed = list.set(index, item);
+			position = null;
+			return removed;
+		}else
 			throw new NullPointerException("It is impossible to replace an ADQL item by a NULL item into an ADQL clause !");
 	}
 
@@ -136,7 +149,10 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	 * @throws ArrayIndexOutOfBoundsException	If the index is out of range (index < 0 || index > size()).
 	 */
 	public T remove(int index) throws ArrayIndexOutOfBoundsException{
-		return list.remove(index);
+		T removed = list.remove(index);
+		if (removed != null)
+			position = null;
+		return removed;
 	}
 
 	/**
@@ -144,6 +160,7 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	 */
 	public void clear(){
 		list.clear();
+		position = null;
 	}
 
 	/**
@@ -164,10 +181,27 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 		return list.isEmpty();
 	}
 
+	@Override
 	public String getName(){
 		return name;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Sets the position at which this {@link ADQLList} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link ADQLList}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public String toADQL(){
 		String adql = (getName() == null) ? "" : (getName() + " ");
 
@@ -177,10 +211,12 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 		return adql;
 	}
 
+	@Override
 	public Iterator<T> iterator(){
 		return list.iterator();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLListIterator(this);
 	}
@@ -201,6 +237,7 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 	 */
 	public abstract String getSeparator(int index) throws ArrayIndexOutOfBoundsException;
 
+	@Override
 	public abstract ADQLObject getCopy() throws Exception;
 
 	/**
@@ -219,15 +256,18 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 			list = (ADQLList<ADQLObject>)lst;
 		}
 
+		@Override
 		public boolean hasNext(){
 			return index + 1 < list.size();
 		}
 
+		@Override
 		public ADQLObject next(){
 			removed = false;
 			return list.get(++index);
 		}
 
+		@Override
 		public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 			if (index <= -1)
 				throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -241,6 +281,7 @@ public abstract class ADQLList< T extends ADQLObject > implements ADQLObject, It
 				list.set(index, replacer);
 		}
 
+		@Override
 		public void remove(){
 			if (index <= -1)
 				throw new IllegalStateException("remove() impossible: next() has not yet been called !");
diff --git a/src/adql/query/ADQLObject.java b/src/adql/query/ADQLObject.java
index 40776cf..85ebaa0 100644
--- a/src/adql/query/ADQLObject.java
+++ b/src/adql/query/ADQLObject.java
@@ -18,7 +18,8 @@ import adql.search.ISearchHandler;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 /**
@@ -26,12 +27,13 @@ import adql.search.ISearchHandler;
  * <ul>
  * 	<li>to have a name in ADQL</i>
  * 	<li>to be written in ADQL</li>
- * 	<li>to offer a way to search any ADQL item <i>(included itself)</i>.</li>
+ * 	<li>to offer a way to search any ADQL item <i>(included itself)</i></li>
+ * 	<li>to get its position in the original ADQL query.</li>
  * </ul>
  * </p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 01/2012
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public interface ADQLObject {
 
@@ -42,6 +44,17 @@ public interface ADQLObject {
 	 */
 	public String getName();
 
+	/**
+	 * <p>Gets the position of this object/token in the ADQL query.</p>
+	 * <p><i>By default, no position should be set.</i></p>
+	 * 
+	 * @return	Position of this ADQL item in the ADQL query,
+	 *          or NULL if not written originally in the query (for example, if added afterwards.
+	 * 
+	 * @since 1.3
+	 */
+	public TextPosition getPosition();
+
 	/**
 	 * Gets the ADQL expression of this object.
 	 * 
diff --git a/src/adql/query/ADQLQuery.java b/src/adql/query/ADQLQuery.java
index ffbc997..3f47294 100644
--- a/src/adql/query/ADQLQuery.java
+++ b/src/adql/query/ADQLQuery.java
@@ -38,7 +38,7 @@ import adql.search.ISearchHandler;
  * <p>The resulting object of the {@link ADQLParser} is an object of this class.</p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (11/2013)
+ * @version 1.3 (05/2014)
  */
 public class ADQLQuery implements ADQLObject {
 
@@ -60,6 +60,10 @@ public class ADQLQuery implements ADQLObject {
 	/** The ADQL clause ORDER BY. */
 	private ClauseADQL<ADQLOrder> orderBy;
 
+	/** Position of this Query (or sub-query) inside the whole given ADQL query string.
+	 * @since 1.3*/
+	private TextPosition position = null;
+
 	/**
 	 * Builds an empty ADQL query.
 	 */
@@ -86,6 +90,7 @@ public class ADQLQuery implements ADQLObject {
 		groupBy = (ClauseADQL<ColumnReference>)toCopy.groupBy.getCopy();
 		having = (ClauseConstraints)toCopy.having.getCopy();
 		orderBy = (ClauseADQL<ADQLOrder>)toCopy.orderBy.getCopy();
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -101,6 +106,7 @@ public class ADQLQuery implements ADQLObject {
 		groupBy.clear();
 		having.clear();
 		orderBy.clear();
+		position = null;
 	}
 
 	/**
@@ -113,7 +119,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its SELECT clause by the given one.
+	 * <p>Replaces its SELECT clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newSelect					The new SELECT clause.
 	 * 
@@ -124,6 +132,7 @@ public class ADQLQuery implements ADQLObject {
 			throw new NullPointerException("Impossible to replace the SELECT clause of a query by NULL !");
 		else
 			select = newSelect;
+		position = null;
 	}
 
 	/**
@@ -136,7 +145,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its FROM clause by the given one.
+	 * <p>Replaces its FROM clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newFrom					The new FROM clause.
 	 * 
@@ -147,6 +158,7 @@ public class ADQLQuery implements ADQLObject {
 			throw new NullPointerException("Impossible to replace the FROM clause of a query by NULL !");
 		else
 			from = newFrom;
+		position = null;
 	}
 
 	/**
@@ -159,7 +171,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its WHERE clause by the given one.
+	 * <p>Replaces its WHERE clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newWhere					The new WHERE clause.
 	 * 
@@ -170,6 +184,7 @@ public class ADQLQuery implements ADQLObject {
 			where.clear();
 		else
 			where = newWhere;
+		position = null;
 	}
 
 	/**
@@ -182,7 +197,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its GROUP BY clause by the given one.
+	 * <p>Replaces its GROUP BY clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newGroupBy				The new GROUP BY clause.
 	 * @throws NullPointerException		If the given GROUP BY clause is <i>null</i>.
@@ -192,6 +209,7 @@ public class ADQLQuery implements ADQLObject {
 			groupBy.clear();
 		else
 			groupBy = newGroupBy;
+		position = null;
 	}
 
 	/**
@@ -204,7 +222,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its HAVING clause by the given one.
+	 * <p>Replaces its HAVING clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newHaving					The new HAVING clause.
 	 * @throws NullPointerException		If the given HAVING clause is <i>null</i>.
@@ -214,6 +234,7 @@ public class ADQLQuery implements ADQLObject {
 			having.clear();
 		else
 			having = newHaving;
+		position = null;
 	}
 
 	/**
@@ -226,7 +247,9 @@ public class ADQLQuery implements ADQLObject {
 	}
 
 	/**
-	 * Replaces its ORDER BY clause by the given one.
+	 * <p>Replaces its ORDER BY clause by the given one.</p>
+	 * 
+	 * <p><i>note: the position of the query is erased.</i></p>
 	 * 
 	 * @param newOrderBy				The new ORDER BY clause.
 	 * @throws NullPointerException		If the given ORDER BY clause is <i>null</i>.
@@ -236,6 +259,22 @@ public class ADQLQuery implements ADQLObject {
 			orderBy.clear();
 		else
 			orderBy = newOrderBy;
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link ADQLQuery} (or sub-query) inside the whole given ADQL query string.
+	 * 
+	 * @param position New position of this {@link ADQLQuery}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
 	}
 
 	@Override
@@ -387,6 +426,7 @@ public class ADQLQuery implements ADQLObject {
 								throw new UnsupportedOperationException("Impossible to replace a ClauseADQL (" + orderBy.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 							break;
 					}
+					position = null;
 				}
 			}
 
@@ -397,8 +437,10 @@ public class ADQLQuery implements ADQLObject {
 
 				if (index == 0 || index == 1)
 					throw new UnsupportedOperationException("Impossible to remove a " + ((index == 0) ? "SELECT" : "FROM") + " clause from a query !");
-				else
+				else{
 					currentClause.clear();
+					position = null;
+				}
 			}
 		};
 	}
diff --git a/src/adql/query/SelectAllColumns.java b/src/adql/query/SelectAllColumns.java
index b94159f..0096fb0 100644
--- a/src/adql/query/SelectAllColumns.java
+++ b/src/adql/query/SelectAllColumns.java
@@ -20,15 +20,16 @@ import adql.query.from.ADQLTable;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 /**
  * In ADQL it corresponds to the '*' and '{tableName}.*' items in the SELECT clause.
  * It means: 'select all columns'.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 01/2012
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public final class SelectAllColumns extends SelectItem {
 
@@ -87,6 +88,7 @@ public final class SelectAllColumns extends SelectItem {
 		if (query != null){
 			this.query = query;
 			adqlTable = null;
+			setPosition(null);
 		}
 	}
 
@@ -109,6 +111,7 @@ public final class SelectAllColumns extends SelectItem {
 		if (table == null){
 			adqlTable = table;
 			query = null;
+			setPosition(null);
 		}
 	}
 
@@ -128,6 +131,7 @@ public final class SelectAllColumns extends SelectItem {
 
 			private boolean tableGot = (adqlTable == null);
 
+			@Override
 			public ADQLObject next() throws NoSuchElementException{
 				if (tableGot)
 					throw new NoSuchElementException();
@@ -135,10 +139,12 @@ public final class SelectAllColumns extends SelectItem {
 				return adqlTable;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !tableGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (replacer == null)
 					remove();
@@ -146,10 +152,13 @@ public final class SelectAllColumns extends SelectItem {
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 				else if (!(replacer instanceof ADQLTable))
 					throw new IllegalStateException("Impossible to replace an ADQLTable by a " + replacer.getClass().getName() + " !");
-				else
+				else{
 					adqlTable = (ADQLTable)replacer;
+					setPosition(null);
+				}
 			}
 
+			@Override
 			public void remove(){
 				if (!tableGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
diff --git a/src/adql/query/SelectItem.java b/src/adql/query/SelectItem.java
index 595e762..41795cc 100644
--- a/src/adql/query/SelectItem.java
+++ b/src/adql/query/SelectItem.java
@@ -16,7 +16,8 @@ package adql.query;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
@@ -28,8 +29,8 @@ import adql.query.operand.ADQLOperand;
  * 
  * <p>It merely encapsulates an operand and allows to associate to it an alias (according to the following syntax: "SELECT operand AS alias").</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 01/2012
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  * 
  * @see ClauseSelect
  */
@@ -44,6 +45,10 @@ public class SelectItem implements ADQLObject {
 	/** Indicates whether the alias is case sensitive (if yes, the alias is written between double-quotes). */
 	private boolean caseSensitive = false;
 
+	/** Position of this Select item in the ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds a SELECT item just with an operand.
 	 * 
@@ -77,6 +82,7 @@ public class SelectItem implements ADQLObject {
 			operand = null;
 		alias = toCopy.getAlias();
 		caseSensitive = toCopy.caseSensitive;
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -112,6 +118,8 @@ public class SelectItem implements ADQLObject {
 	 * @param newAlias	The new alias of the operand.
 	 */
 	public final void setAlias(String newAlias){
+		if (alias == null && newAlias != null || alias != null && newAlias == null || alias != null && !alias.equals(newAlias))
+			position = null;
 		alias = newAlias;
 		caseSensitive = false;
 
@@ -120,6 +128,7 @@ public class SelectItem implements ADQLObject {
 			a.trimToSize();
 			if (a.length() == 0){
 				alias = null;
+				position = null;
 				return;
 			}else if (a.length() > 1 && a.charAt(0) == '\"' && a.charAt(a.length() - 1) == '\"'){
 				a.deleteCharAt(0);
@@ -127,6 +136,7 @@ public class SelectItem implements ADQLObject {
 				a.trimToSize();
 				if (a.length() == 0){
 					alias = null;
+					position = null;
 					return;
 				}
 				caseSensitive = true;
@@ -153,19 +163,38 @@ public class SelectItem implements ADQLObject {
 		caseSensitive = sensitive;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link SelectItem} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link SelectItem}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new SelectItem(this);
 	}
 
+	@Override
 	public String getName(){
 		return hasAlias() ? alias : operand.getName();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean operandGot = (operand == null);
 
+			@Override
 			public ADQLObject next() throws NoSuchElementException{
 				if (operandGot)
 					throw new NoSuchElementException();
@@ -173,10 +202,12 @@ public class SelectItem implements ADQLObject {
 				return operand;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !operandGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (replacer == null)
 					remove();
@@ -184,10 +215,13 @@ public class SelectItem implements ADQLObject {
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 				else if (!(replacer instanceof ADQLOperand))
 					throw new IllegalStateException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " !");
-				else
+				else{
 					operand = (ADQLOperand)replacer;
+					position = null;
+				}
 			}
 
+			@Override
 			public void remove(){
 				if (!operandGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -197,6 +231,7 @@ public class SelectItem implements ADQLObject {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		StringBuffer adql = new StringBuffer(operand.toADQL());
 		if (hasAlias()){
diff --git a/src/adql/query/TextPosition.java b/src/adql/query/TextPosition.java
index e7d086a..5bda46a 100644
--- a/src/adql/query/TextPosition.java
+++ b/src/adql/query/TextPosition.java
@@ -16,7 +16,8 @@ package adql.query;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.parser.Token;
@@ -25,8 +26,8 @@ import adql.parser.Token;
  * Indicates a simple position or a token/string position in a text.
  * It is particularly used to localize columns and tables in the original ADQL query.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 01/2012
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  */
 public class TextPosition {
 
@@ -71,7 +72,7 @@ public class TextPosition {
 	}
 
 	/**
-	 * Builds a position whose the end line and column are unknown => a simple position.
+	 * Builds a position defining the region delimited by the given token.
 	 * 
 	 * @param token	The position will be the one of this token.
 	 */
@@ -89,6 +90,27 @@ public class TextPosition {
 		this(beginToken.beginLine, beginToken.beginColumn, endToken.endLine, (endToken.endColumn < 0) ? -1 : (endToken.endColumn + 1));
 	}
 
+	/**
+	 * Builds a copy of the given position.
+	 * 
+	 * @param positionToCopy	Position to copy.
+	 * @since 1.3
+	 */
+	public TextPosition(final TextPosition positionToCopy){
+		this(positionToCopy.beginLine, positionToCopy.beginColumn, positionToCopy.endLine, positionToCopy.endColumn);
+	}
+
+	/**
+	 * Builds a position whose the start is the start position of the first parameter and the end is the end position of the second parameter.
+	 * 
+	 * @param startPos	Start position (only beginLine and beginColumn will be used).
+	 * @param endPos	End position (only endLine and endColumn will be used).
+	 * @since 1.3
+	 */
+	public TextPosition(final TextPosition startPos, final TextPosition endPos){
+		this(startPos.beginLine, startPos.beginColumn, endPos.endLine, endPos.endColumn);
+	}
+
 	@Override
 	public String toString(){
 		if (beginLine == -1 && beginColumn == -1)
diff --git a/src/adql/query/constraint/Between.java b/src/adql/query/constraint/Between.java
index 28cecbd..430fec1 100644
--- a/src/adql/query/constraint/Between.java
+++ b/src/adql/query/constraint/Between.java
@@ -16,14 +16,15 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
-
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -32,8 +33,8 @@ import adql.query.operand.ADQLOperand;
  * <p>This predicate returns <i>true</i> if the value of the left operand is
  * between the value of the two other operands, else it returns <i>false</i>.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class Between implements ADQLConstraint {
 
@@ -49,6 +50,10 @@ public class Between implements ADQLConstraint {
 	/** Indicates which predicate must be used: BETWEEN (<i>false</i>) or NOT BETWEEN (<i>true</i>). */
 	private boolean notBetween = false;
 
+	/** Position of this {@link Between} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds a BETWEEN constraints.
 	 * 
@@ -87,6 +92,7 @@ public class Between implements ADQLConstraint {
 		setLeftOperand((ADQLOperand)toCopy.leftOperand.getCopy());
 		setMinOperand((ADQLOperand)toCopy.minOperand.getCopy());
 		setMaxOperand((ADQLOperand)toCopy.maxOperand.getCopy());
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -106,6 +112,7 @@ public class Between implements ADQLConstraint {
 	 */
 	public void setLeftOperand(ADQLOperand leftOperand) throws NullPointerException{
 		this.leftOperand = leftOperand;
+		position = null;
 	}
 
 	/**
@@ -125,6 +132,7 @@ public class Between implements ADQLConstraint {
 	 */
 	public void setMinOperand(ADQLOperand minOperand) throws NullPointerException{
 		this.minOperand = minOperand;
+		position = null;
 	}
 
 	/**
@@ -144,6 +152,7 @@ public class Between implements ADQLConstraint {
 	 */
 	public void setMaxOperand(ADQLOperand maxOperand) throws NullPointerException{
 		this.maxOperand = maxOperand;
+		position = null;
 	}
 
 	/**
@@ -162,21 +171,41 @@ public class Between implements ADQLConstraint {
 	 */
 	public void setNotBetween(boolean notBetween){
 		this.notBetween = notBetween;
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link Between} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link Between}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new Between(this);
 	}
 
+	@Override
 	public String getName(){
 		return (isNotBetween() ? "NOT " : "") + "BETWEEN";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private int index = -1;
 
+			@Override
 			public ADQLObject next(){
 				switch(++index){
 					case 0:
@@ -190,10 +219,12 @@ public class Between implements ADQLConstraint {
 				}
 			}
 
+			@Override
 			public boolean hasNext(){
 				return index + 1 < 3;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (index <= -1)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -212,10 +243,12 @@ public class Between implements ADQLConstraint {
 							maxOperand = (ADQLOperand)replacer;
 							break;
 					}
+					position = null;
 				}else
 					throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 			}
 
+			@Override
 			public void remove(){
 				if (index <= -1)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -225,6 +258,7 @@ public class Between implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return leftOperand.toADQL() + " " + getName() + " " + minOperand.toADQL() + " AND " + maxOperand.toADQL();
 	}
diff --git a/src/adql/query/constraint/Comparison.java b/src/adql/query/constraint/Comparison.java
index 8aeab2e..14b2d1b 100644
--- a/src/adql/query/constraint/Comparison.java
+++ b/src/adql/query/constraint/Comparison.java
@@ -16,20 +16,22 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
  * Represents a comparison (numeric or not) between two operands.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  * 
  * @see ComparisonOperator
  */
@@ -44,6 +46,10 @@ public class Comparison implements ADQLConstraint {
 	/** The right part of the comparison. */
 	private ADQLOperand rightOperand;
 
+	/** Position of this {@link Comparison} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Creates a comparison between two operands.
 	 * 
@@ -73,6 +79,7 @@ public class Comparison implements ADQLConstraint {
 		leftOperand = (ADQLOperand)toCopy.leftOperand.getCopy();
 		compOperator = toCopy.compOperator;
 		rightOperand = (ADQLOperand)toCopy.rightOperand.getCopy();
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -100,6 +107,7 @@ public class Comparison implements ADQLConstraint {
 			throw new UnsupportedOperationException("Impossible to update the left operand of the comparison (" + toADQL() + ") with \"" + newLeftOperand.toADQL() + "\" because the comparison operator " + compOperator.toADQL() + " is not applicable on numeric operands !");
 
 		leftOperand = newLeftOperand;
+		position = null;
 	}
 
 	/**
@@ -125,6 +133,7 @@ public class Comparison implements ADQLConstraint {
 			throw new UnsupportedOperationException("Impossible to update the comparison operator" + ((compOperator != null) ? (" (" + compOperator.toADQL() + ")") : "") + " by " + newOperation.toADQL() + " because the two operands (\"" + leftOperand.toADQL() + "\" & \"" + rightOperand.toADQL() + "\") are not all Strings !");
 
 		compOperator = newOperation;
+		position = null;
 	}
 
 	/**
@@ -152,21 +161,41 @@ public class Comparison implements ADQLConstraint {
 			throw new UnsupportedOperationException("Impossible to update the right operand of the comparison (" + toADQL() + ") with \"" + newRightOperand.toADQL() + "\" because the comparison operator " + compOperator.toADQL() + " is not applicable on numeric operands !");
 
 		rightOperand = newRightOperand;
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link Comparison} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link Comparison}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new Comparison(this);
 	}
 
+	@Override
 	public String getName(){
 		return compOperator.toADQL();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private int index = -1;
 
+			@Override
 			public ADQLObject next(){
 				index++;
 				if (index == 0)
@@ -177,10 +206,12 @@ public class Comparison implements ADQLConstraint {
 					throw new NoSuchElementException();
 			}
 
+			@Override
 			public boolean hasNext(){
 				return index + 1 < 2;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (index <= -1)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -188,14 +219,18 @@ public class Comparison implements ADQLConstraint {
 				if (replacer == null)
 					remove();
 				else if (replacer instanceof ADQLOperand){
-					if (index == 0)
+					if (index == 0){
 						leftOperand = (ADQLOperand)replacer;
-					else if (index == 1)
+						position = null;
+					}else if (index == 1){
 						rightOperand = (ADQLOperand)replacer;
+						position = null;
+					}
 				}else
 					throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " in a comparison !");
 			}
 
+			@Override
 			public void remove(){
 				if (index <= -1)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -205,6 +240,7 @@ public class Comparison implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return ((leftOperand == null) ? "NULL" : leftOperand.toADQL()) + " " + ((compOperator == null) ? "NULL" : compOperator.toADQL()) + " " + ((rightOperand == null) ? "NULL" : rightOperand.toADQL());
 	}
diff --git a/src/adql/query/constraint/Exists.java b/src/adql/query/constraint/Exists.java
index 363588f..92c1197 100644
--- a/src/adql/query/constraint/Exists.java
+++ b/src/adql/query/constraint/Exists.java
@@ -16,7 +16,8 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
@@ -24,20 +25,25 @@ import java.util.NoSuchElementException;
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
 import adql.query.ADQLQuery;
+import adql.query.TextPosition;
 
 /**
  * <p>Represents the predicate EXISTS of SQL and ADQL.</p>
  * 
  * <p>This function returns <i>true</i> if the sub-query given in parameter returns at least one result, else it returns <i>false</i>.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class Exists implements ADQLConstraint {
 
 	/** The sub-query. */
 	private ADQLQuery subQuery;
 
+	/** Position of this {@link Exists} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds an Exists constraint instance.
 	 * 
@@ -55,6 +61,7 @@ public class Exists implements ADQLConstraint {
 	 */
 	public Exists(Exists toCopy) throws Exception{
 		subQuery = (ADQLQuery)toCopy.subQuery.getCopy();
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -75,23 +82,44 @@ public class Exists implements ADQLConstraint {
 	public void setSubQuery(ADQLQuery query) throws NullPointerException{
 		if (query == null)
 			throw new NullPointerException("Impossible to build an EXISTS constraint with a sub-query NULL !");
-		else
+		else{
 			subQuery = query;
+			position = null;
+		}
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
 	}
 
+	/**
+	 * Set the position of this {@link Exists} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link Exists}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new Exists(this);
 	}
 
+	@Override
 	public String getName(){
 		return "EXISTS";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean subQueryGot = (subQuery == null);
 
+			@Override
 			public ADQLObject next(){
 				if (subQueryGot)
 					throw new NoSuchElementException();
@@ -99,22 +127,26 @@ public class Exists implements ADQLConstraint {
 				return subQuery;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !subQueryGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (!subQueryGot)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 
 				if (replacer == null)
 					remove();
-				else if (replacer instanceof ADQLQuery)
+				else if (replacer instanceof ADQLQuery){
 					subQuery = (ADQLQuery)replacer;
-				else
+					position = null;
+				}else
 					throw new UnsupportedOperationException("Impossible to replace an ADQLQuery by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 			}
 
+			@Override
 			public void remove(){
 				if (!subQueryGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -124,6 +156,7 @@ public class Exists implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return getName() + "(" + subQuery.toADQL() + ")";
 	}
diff --git a/src/adql/query/constraint/In.java b/src/adql/query/constraint/In.java
index 2ea7ffa..a507984 100644
--- a/src/adql/query/constraint/In.java
+++ b/src/adql/query/constraint/In.java
@@ -16,7 +16,8 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
@@ -26,7 +27,7 @@ import adql.query.ADQLList;
 import adql.query.ADQLObject;
 import adql.query.ADQLQuery;
 import adql.query.ClauseADQL;
-
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -35,8 +36,8 @@ import adql.query.operand.ADQLOperand;
  * <p>This predicate returns <i>true</i> if the value of the given operand is
  * either in the given values list or in the results of the given sub-query, else it returns <i>false</i>.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class In implements ADQLConstraint {
 
@@ -52,6 +53,10 @@ public class In implements ADQLConstraint {
 	/** IN or NOT IN ? */
 	private boolean notIn = false;
 
+	/** Position of this {@link In} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds an IN constraint with a sub-query.
 	 * 
@@ -141,6 +146,7 @@ public class In implements ADQLConstraint {
 		else
 			setValuesList((ADQLList<ADQLOperand>)toCopy.list.getCopy());
 		notIn = toCopy.notIn;
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -161,8 +167,10 @@ public class In implements ADQLConstraint {
 	public void setOperand(ADQLOperand newLeftOp) throws NullPointerException{
 		if (newLeftOp == null)
 			throw new NullPointerException("Impossible to set a left operand NULL in an IN constraint !");
-		else
+		else{
 			leftOp = newLeftOp;
+			position = null;
+		}
 	}
 
 	/**
@@ -195,6 +203,7 @@ public class In implements ADQLConstraint {
 		else{
 			list = null;
 			subQuery = newSubQuery;
+			position = null;
 		}
 	}
 
@@ -221,6 +230,7 @@ public class In implements ADQLConstraint {
 			list = new ClauseADQL<ADQLOperand>();
 			for(int i = 0; i < valuesList.length; i++)
 				list.add(valuesList[i]);
+			position = null;
 		}
 	}
 
@@ -236,6 +246,7 @@ public class In implements ADQLConstraint {
 		else{
 			subQuery = null;
 			list = valuesList;
+			position = null;
 		}
 	}
 
@@ -255,21 +266,41 @@ public class In implements ADQLConstraint {
 	 */
 	public void setNotIn(boolean notIn){
 		this.notIn = notIn;
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link In} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link In}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new In(this);
 	}
 
+	@Override
 	public String getName(){
 		return notIn ? "NOT IN" : "IN";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private int index = -1;
 
+			@Override
 			public ADQLObject next(){
 				index++;
 				if (index == 0)
@@ -280,10 +311,12 @@ public class In implements ADQLConstraint {
 					throw new NoSuchElementException();
 			}
 
+			@Override
 			public boolean hasNext(){
 				return index + 1 < 2;
 			}
 
+			@Override
 			@SuppressWarnings("unchecked")
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (index <= -1)
@@ -293,20 +326,24 @@ public class In implements ADQLConstraint {
 					remove();
 
 				if (index == 0){
-					if (replacer instanceof ADQLOperand)
+					if (replacer instanceof ADQLOperand){
 						leftOp = (ADQLOperand)replacer;
-					else
+						position = null;
+					}else
 						throw new UnsupportedOperationException("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 				}else if (index == 1){
-					if (hasSubQuery() && replacer instanceof ADQLQuery)
+					if (hasSubQuery() && replacer instanceof ADQLQuery){
 						subQuery = (ADQLQuery)replacer;
-					else if (!hasSubQuery() && replacer instanceof ADQLList)
+						position = null;
+					}else if (!hasSubQuery() && replacer instanceof ADQLList){
 						list = (ADQLList<ADQLOperand>)replacer;
-					else
+						position = null;
+					}else
 						throw new UnsupportedOperationException("Impossible to replace an " + (hasSubQuery() ? "ADQLQuery" : "ADQLList<ADQLOperand>") + " by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 				}
 			}
 
+			@Override
 			public void remove(){
 				if (index <= -1)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -319,6 +356,7 @@ public class In implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return leftOp.toADQL() + " " + getName() + " (" + (hasSubQuery() ? subQuery.toADQL() : list.toADQL()) + ")";
 	}
diff --git a/src/adql/query/constraint/IsNull.java b/src/adql/query/constraint/IsNull.java
index 666654d..529a140 100644
--- a/src/adql/query/constraint/IsNull.java
+++ b/src/adql/query/constraint/IsNull.java
@@ -16,20 +16,22 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLColumn;
 
 /**
  * Represents a comparison between a column to the NULL value.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class IsNull implements ADQLConstraint {
 
@@ -39,6 +41,10 @@ public class IsNull implements ADQLConstraint {
 	/** Indicates whether the predicate IS NOT NULL must be used rather than IS NULL. */
 	private boolean isNotNull = false;
 
+	/** Position of this {@link IsNull} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds a comparison between the given column and NULL.
 	 * 
@@ -70,6 +76,7 @@ public class IsNull implements ADQLConstraint {
 	public IsNull(IsNull toCopy) throws Exception{
 		column = (ADQLColumn)toCopy.column.getCopy();
 		isNotNull = toCopy.isNotNull;
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -90,8 +97,10 @@ public class IsNull implements ADQLConstraint {
 	public final void setColumn(ADQLColumn column) throws NullPointerException{
 		if (column == null)
 			throw new NullPointerException("Impossible to compare nothing to NULL: no column has been given to build a IsNull constraint !");
-		else
+		else{
 			this.column = column;
+			position = null;
+		}
 	}
 
 	/**
@@ -110,21 +119,41 @@ public class IsNull implements ADQLConstraint {
 	 */
 	public final void setNotNull(boolean notNull){
 		isNotNull = notNull;
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
 	}
 
+	/**
+	 * Set the position of this {@link IsNull} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link IsNull}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new IsNull(this);
 	}
 
+	@Override
 	public String getName(){
 		return "IS" + (isNotNull ? " NOT " : " ") + "NULL";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean columnGot = (column == null);
 
+			@Override
 			public ADQLObject next(){
 				if (columnGot)
 					throw new NoSuchElementException();
@@ -132,22 +161,26 @@ public class IsNull implements ADQLConstraint {
 				return column;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !columnGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (!columnGot)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 
 				if (replacer == null)
 					remove();
-				else if (replacer instanceof ADQLColumn)
+				else if (replacer instanceof ADQLColumn){
 					column = (ADQLColumn)replacer;
-				else
+					position = null;
+				}else
 					throw new UnsupportedOperationException("Impossible to replace a column (" + column.toADQL() + ") by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") in a IsNull constraint (" + toADQL() + ") !");
 			}
 
+			@Override
 			public void remove(){
 				if (!columnGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -157,6 +190,7 @@ public class IsNull implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return column.toADQL() + " " + getName();
 	}
diff --git a/src/adql/query/constraint/NotConstraint.java b/src/adql/query/constraint/NotConstraint.java
index 77caae1..8d6f400 100644
--- a/src/adql/query/constraint/NotConstraint.java
+++ b/src/adql/query/constraint/NotConstraint.java
@@ -16,24 +16,30 @@ package adql.query.constraint;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 
 /**
  * Lets apply the logical operator NOT on any constraint.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class NotConstraint implements ADQLConstraint {
 
 	private ADQLConstraint constraint;
 
+	/** Position of this {@link NotConstraint} in the ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/**
 	 * Builds a NotConstraint just with the constraint on which the logical operator NOT must be applied.
 	 * 
@@ -56,19 +62,38 @@ public class NotConstraint implements ADQLConstraint {
 		return constraint;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link NotConstraint} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link NotConstraint}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new NotConstraint((ADQLConstraint)constraint.getCopy());
 	}
 
+	@Override
 	public String getName(){
 		return "NOT " + constraint.getName();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean constraintGot = (constraint == null);
 
+			@Override
 			public ADQLObject next(){
 				if (constraintGot)
 					throw new NoSuchElementException();
@@ -76,22 +101,26 @@ public class NotConstraint implements ADQLConstraint {
 				return constraint;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !constraintGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (!constraintGot)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 
 				if (replacer == null)
 					remove();
-				else if (replacer instanceof ADQLConstraint)
+				else if (replacer instanceof ADQLConstraint){
 					constraint = (ADQLConstraint)replacer;
-				else
+					position = null;
+				}else
 					throw new UnsupportedOperationException("Impossible to replace an ADQLConstraint by a " + replacer.getClass().getName() + " !");
 			}
 
+			@Override
 			public void remove(){
 				if (!constraintGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -101,6 +130,7 @@ public class NotConstraint implements ADQLConstraint {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return "NOT " + constraint.toADQL();
 	}
diff --git a/src/adql/query/from/ADQLJoin.java b/src/adql/query/from/ADQLJoin.java
index 9c9cb14..6cbc8c5 100644
--- a/src/adql/query/from/ADQLJoin.java
+++ b/src/adql/query/from/ADQLJoin.java
@@ -35,13 +35,14 @@ import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
 import adql.query.ClauseConstraints;
 import adql.query.IdentifierField;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLColumn;
 
 /**
  * Defines a join between two "tables".
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (11/2013)
+ * @version 1.3 (05/2014)
  */
 public abstract class ADQLJoin implements ADQLObject, FromContent {
 
@@ -60,6 +61,10 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 	/** List of columns on which the join must be done. */
 	protected ArrayList<ADQLColumn> lstColumns = null;
 
+	/** Position of this {@link ADQLJoin} in the given ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
 	/* ************ */
 	/* CONSTRUCTORS */
 	/* ************ */
@@ -92,6 +97,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 			for(ADQLColumn col : toCopy.lstColumns)
 				lstColumns.add((ADQLColumn)col.getCopy());
 		}
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/* ***************** */
@@ -117,6 +123,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 			condition = null;
 			lstColumns = null;
 		}
+		position = null;
 	}
 
 	/**
@@ -135,6 +142,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 	 */
 	public void setLeftTable(FromContent table){
 		leftTable = table;
+		position = null;
 	}
 
 	/**
@@ -153,6 +161,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 	 */
 	public void setRightTable(FromContent table){
 		rightTable = table;
+		position = null;
 	}
 
 	/**
@@ -175,6 +184,17 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 			natural = false;
 			lstColumns = null;
 		}
+		position = null;
+	}
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	@Override
+	public final void setPosition(final TextPosition position){
+		this.position = position;
 	}
 
 	/**
@@ -228,6 +248,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 
 			natural = false;
 			condition = null;
+			position = null;
 		}
 	}
 
@@ -299,6 +320,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 					else
 						throw new UnsupportedOperationException("Impossible to replace an ADQLColumn by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
 				}
+				position = null;
 
 			}
 
@@ -315,6 +337,7 @@ public abstract class ADQLJoin implements ADQLObject, FromContent {
 				else if (itCol != null){
 					itCol.remove();
 					index--;
+					position = null;
 				}
 			}
 		};
diff --git a/src/adql/query/from/FromContent.java b/src/adql/query/from/FromContent.java
index e9157f8..e7ad5c2 100644
--- a/src/adql/query/from/FromContent.java
+++ b/src/adql/query/from/FromContent.java
@@ -26,13 +26,14 @@ import adql.db.DBColumn;
 import adql.db.SearchColumnList;
 import adql.db.exception.UnresolvedJoin;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 
 /**
  * Represents the content of the whole or a part of the clause FROM.
  * It could be either a table ({@link ADQLTable}) or a join ({@link ADQLJoin}).
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (11/2013)
+ * @version 1.3 (05/2014)
  */
 public interface FromContent extends ADQLObject {
 
@@ -67,4 +68,12 @@ public interface FromContent extends ADQLObject {
 	 */
 	public ArrayList<ADQLTable> getTablesByAlias(final String alias, final boolean caseSensitive);
 
+	/**
+	 * Set the position of this {@link FromContent} in the given ADQL query string.
+	 * 
+	 * @param position	New position of this {@link FromContent}.
+	 * @since 1.3
+	 */
+	public void setPosition(final TextPosition position);
+
 }
diff --git a/src/adql/query/operand/ADQLColumn.java b/src/adql/query/operand/ADQLColumn.java
index d148bd7..590f8b5 100644
--- a/src/adql/query/operand/ADQLColumn.java
+++ b/src/adql/query/operand/ADQLColumn.java
@@ -20,7 +20,6 @@ package adql.query.operand;
  */
 
 import adql.db.DBColumn;
-
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
 import adql.query.IdentifierField;
@@ -163,11 +162,7 @@ public class ADQLColumn implements ADQLOperand {
 	/* ***************** */
 	/* GETTERS & SETTERS */
 	/* ***************** */
-	/**
-	 * Gets the position in the original ADQL query string.
-	 * 
-	 * @return	The position of this {@link ADQLTable}.
-	 */
+	@Override
 	public final TextPosition getPosition(){
 		return position;
 	}
@@ -457,26 +452,32 @@ public class ADQLColumn implements ADQLOperand {
 	/* ***************** */
 	/* INHERITED METHODS */
 	/* ***************** */
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new ADQLColumn(this);
 	}
 
+	@Override
 	public String getName(){
 		return getColumnName();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new NullADQLIterator();
 	}
 
+	@Override
 	public String toADQL(){
 		return getFullColumnName();
 	}
diff --git a/src/adql/query/operand/NegativeOperand.java b/src/adql/query/operand/NegativeOperand.java
index 82fad6b..39bb608 100644
--- a/src/adql/query/operand/NegativeOperand.java
+++ b/src/adql/query/operand/NegativeOperand.java
@@ -16,23 +16,28 @@ package adql.query.operand;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 
 /**
  * Lets putting a minus sign in front of any numeric operand.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  */
 public final class NegativeOperand implements ADQLOperand {
 
+	/** The negativated operand. */
 	private ADQLOperand operand;
+	/** Position of this operand. */
+	private TextPosition position = null;
 
 	/**
 	 * <p>Builds an operand which will negativate the given operand.</p>
@@ -66,6 +71,7 @@ public final class NegativeOperand implements ADQLOperand {
 	/** Always returns <i>true</i>.
 	 * @see adql.query.operand.ADQLOperand#isNumeric()
 	 */
+	@Override
 	public final boolean isNumeric(){
 		return true;
 	}
@@ -73,24 +79,44 @@ public final class NegativeOperand implements ADQLOperand {
 	/** Always returns <i>false</i>.
 	 * @see adql.query.operand.ADQLOperand#isString()
 	 */
+	@Override
 	public final boolean isString(){
 		return false;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return this.position;
+	}
+
+	/**
+	 * Sets the position at which this {@link NegativeOperand} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link NegativeOperand}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		NegativeOperand copy = new NegativeOperand((ADQLOperand)operand.getCopy());
 		return copy;
 	}
 
+	@Override
 	public String getName(){
 		return "-" + operand.getName();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean operandGot = (operand == null);
 
+			@Override
 			public ADQLObject next(){
 				if (operandGot)
 					throw new NoSuchElementException();
@@ -98,10 +124,12 @@ public final class NegativeOperand implements ADQLOperand {
 				return operand;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !operandGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (!operandGot)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -114,6 +142,7 @@ public final class NegativeOperand implements ADQLOperand {
 					throw new UnsupportedOperationException("Impossible to replace the operand \"" + operand.toADQL() + "\" by \"" + replacer.toADQL() + "\" in the NegativeOperand \"" + toADQL() + "\" because the replacer is not an ADQLOperand or is not numeric !");
 			}
 
+			@Override
 			public void remove(){
 				if (!operandGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -123,6 +152,7 @@ public final class NegativeOperand implements ADQLOperand {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return "-" + operand.toADQL();
 	}
diff --git a/src/adql/query/operand/NumericConstant.java b/src/adql/query/operand/NumericConstant.java
index 2baa6d2..a0c93fd 100644
--- a/src/adql/query/operand/NumericConstant.java
+++ b/src/adql/query/operand/NumericConstant.java
@@ -16,22 +16,26 @@ package adql.query.operand;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
 import adql.query.NullADQLIterator;
+import adql.query.TextPosition;
 
 /**
  * A numeric (integer, double, ...) constant.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  */
 public final class NumericConstant implements ADQLOperand {
 
 	private String value;
+	/** Position of this operand. */
+	private TextPosition position = null;
 
 	/**
 	 * The numeric value is saved as a string so that the exact user format can be saved.
@@ -149,6 +153,7 @@ public final class NumericConstant implements ADQLOperand {
 	/** Always returns <i>true</i>.
 	 * @see adql.query.operand.ADQLOperand#isNumeric()
 	 */
+	@Override
 	public final boolean isNumeric(){
 		return true;
 	}
@@ -156,22 +161,42 @@ public final class NumericConstant implements ADQLOperand {
 	/** Always returns <i>false</i>.
 	 * @see adql.query.operand.ADQLOperand#isString()
 	 */
+	@Override
 	public final boolean isString(){
 		return false;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return this.position;
+	}
+
+	/**
+	 * Sets the position at which this {@link NumericConstant} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link NumericConstant}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy(){
 		return new NumericConstant(this);
 	}
 
+	@Override
 	public String getName(){
 		return value;
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new NullADQLIterator();
 	}
 
+	@Override
 	public String toADQL(){
 		return value;
 	}
diff --git a/src/adql/query/operand/Operation.java b/src/adql/query/operand/Operation.java
index b5398ff..09daee2 100644
--- a/src/adql/query/operand/Operation.java
+++ b/src/adql/query/operand/Operation.java
@@ -16,19 +16,21 @@ package adql.query.operand;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 
 /**
  * It represents a simple numeric operation (sum, difference, multiplication and division).
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  * 
  * @see OperationType
  */
@@ -46,6 +48,9 @@ public class Operation implements ADQLOperand {
 	/** Part of the operation at the right of the operator. */
 	private ADQLOperand rightOperand;
 
+	/** Position of the operation in the ADQL query string. */
+	private TextPosition position = null;
+
 	/**
 	 * Builds an operation.
 	 * 
@@ -68,6 +73,8 @@ public class Operation implements ADQLOperand {
 			operation = op;
 
 		setRightOperand(rightOp);
+
+		position = null;
 	}
 
 	/**
@@ -81,6 +88,7 @@ public class Operation implements ADQLOperand {
 		leftOperand = (ADQLOperand)toCopy.leftOperand.getCopy();
 		operation = toCopy.operation;
 		rightOperand = (ADQLOperand)toCopy.rightOperand.getCopy();
+		position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 	}
 
 	/**
@@ -107,6 +115,8 @@ public class Operation implements ADQLOperand {
 			throw new UnsupportedOperationException("Impossible to update an Operation because the left operand is not numeric (" + newLeftOperand.toADQL() + ") !");
 
 		leftOperand = newLeftOperand;
+
+		position = null;
 	}
 
 	/**
@@ -155,11 +165,14 @@ public class Operation implements ADQLOperand {
 			throw new UnsupportedOperationException("Impossible to update an Operation because the right operand is not numeric (" + newRightOperand.toADQL() + ") !");
 
 		rightOperand = newRightOperand;
+
+		position = null;
 	}
 
 	/** Always returns <i>true</i>.
 	 * @see adql.query.operand.ADQLOperand#isNumeric()
 	 */
+	@Override
 	public final boolean isNumeric(){
 		return true;
 	}
@@ -167,24 +180,44 @@ public class Operation implements ADQLOperand {
 	/** Always returns <i>false</i>.
 	 * @see adql.query.operand.ADQLOperand#isString()
 	 */
+	@Override
 	public final boolean isString(){
 		return false;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return this.position;
+	}
+
+	/**
+	 * Sets the position at which this {@link WrappedOperand} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link WrappedOperand}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new Operation(this);
 	}
 
+	@Override
 	public String getName(){
 		return operation.toString();
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private int index = -1;
 			private ADQLOperand operand = null;
 
+			@Override
 			public ADQLObject next(){
 				index++;
 
@@ -197,10 +230,12 @@ public class Operation implements ADQLOperand {
 				return operand;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return index + 1 < 2;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (index <= -1)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -213,11 +248,13 @@ public class Operation implements ADQLOperand {
 							leftOperand = (ADQLOperand)replacer;
 						else if (index == 1)
 							rightOperand = (ADQLOperand)replacer;
+						position = null;
 					}else
 						throw new UnsupportedOperationException("Impossible to replace the operand \"" + operand.toADQL() + "\" by \"" + replacer.toADQL() + "\" in the operation \"" + toADQL() + "\" because the replacer is not an ADQLOperand or is not numeric !");
 				}
 			}
 
+			@Override
 			public void remove(){
 				if (index <= -1)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -227,6 +264,7 @@ public class Operation implements ADQLOperand {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return leftOperand.toADQL() + operation.toADQL() + rightOperand.toADQL();
 	}
diff --git a/src/adql/query/operand/StringConstant.java b/src/adql/query/operand/StringConstant.java
index 2e2b0d4..1551912 100644
--- a/src/adql/query/operand/StringConstant.java
+++ b/src/adql/query/operand/StringConstant.java
@@ -16,22 +16,26 @@ package adql.query.operand;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
 import adql.query.NullADQLIterator;
+import adql.query.TextPosition;
 
 /**
  * A string constant.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  */
 public final class StringConstant implements ADQLOperand {
 
 	private String value;
+	/** Position of this operand. */
+	private TextPosition position = null;
 
 	public StringConstant(String value){
 		this.value = value;
@@ -49,26 +53,47 @@ public final class StringConstant implements ADQLOperand {
 		this.value = value;
 	}
 
+	@Override
 	public final boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public final boolean isString(){
 		return true;
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return this.position;
+	}
+
+	/**
+	 * Sets the position at which this {@link StringConstant} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link StringConstant}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy(){
 		return new StringConstant(this);
 	}
 
+	@Override
 	public String getName(){
 		return "'" + value + "'";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new NullADQLIterator();
 	}
 
+	@Override
 	public String toADQL(){
 		return "'" + value + "'";
 	}
diff --git a/src/adql/query/operand/WrappedOperand.java b/src/adql/query/operand/WrappedOperand.java
index 2ffae9b..92ab7bf 100644
--- a/src/adql/query/operand/WrappedOperand.java
+++ b/src/adql/query/operand/WrappedOperand.java
@@ -16,24 +16,28 @@ package adql.query.operand;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 
 /**
  * Lets wrapping an operand by parenthesis.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 05/2014
  */
 public class WrappedOperand implements ADQLOperand {
 
 	/** The wrapped operand. */
 	private ADQLOperand operand;
+	/** Position of this operand. */
+	private TextPosition position = null;
 
 	/**
 	 * Wraps the given operand.
@@ -57,27 +61,48 @@ public class WrappedOperand implements ADQLOperand {
 		return operand;
 	}
 
+	@Override
 	public final boolean isNumeric(){
 		return operand.isNumeric();
 	}
 
+	@Override
 	public final boolean isString(){
 		return operand.isString();
 	}
 
+	@Override
+	public final TextPosition getPosition(){
+		return this.position;
+	}
+
+	/**
+	 * Sets the position at which this {@link WrappedOperand} has been found in the original ADQL query string.
+	 * 
+	 * @param pos	Position of this {@link WrappedOperand}.
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new WrappedOperand((ADQLOperand)operand.getCopy());
 	}
 
+	@Override
 	public String getName(){
 		return "(" + operand.getName() + ")";
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private boolean operandGot = (operand == null);
 
+			@Override
 			public ADQLObject next(){
 				if (operandGot)
 					throw new NoSuchElementException();
@@ -85,22 +110,26 @@ public class WrappedOperand implements ADQLOperand {
 				return operand;
 			}
 
+			@Override
 			public boolean hasNext(){
 				return !operandGot;
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (!operandGot)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
 
 				if (replacer == null)
 					remove();
-				else if (replacer instanceof ADQLOperand)
+				else if (replacer instanceof ADQLOperand){
 					operand = (ADQLOperand)replacer;
-				else
+					position = null;
+				}else
 					throw new UnsupportedOperationException("Impossible to replace an ADQLOperand (\"" + operand + "\") by a " + replacer.getClass().getName() + " (\"" + replacer.toADQL() + "\") !");
 			}
 
+			@Override
 			public void remove(){
 				if (!operandGot)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -110,6 +139,7 @@ public class WrappedOperand implements ADQLOperand {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		return "(" + operand.toADQL() + ")";
 	}
diff --git a/src/adql/query/operand/function/ADQLFunction.java b/src/adql/query/operand/function/ADQLFunction.java
index 97a22b7..ed9dac7 100644
--- a/src/adql/query/operand/function/ADQLFunction.java
+++ b/src/adql/query/operand/function/ADQLFunction.java
@@ -16,7 +16,8 @@ package adql.query.operand.function;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012-2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.Iterator;
@@ -24,17 +25,36 @@ import java.util.NoSuchElementException;
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
-
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
  * Represents any kind of function.
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public abstract class ADQLFunction implements ADQLOperand {
 
+	/** Position of this {@link ADQLFunction} in the ADQL query string.
+	 * @since 1.3 */
+	private TextPosition position = null;
+
+	@Override
+	public final TextPosition getPosition(){
+		return position;
+	}
+
+	/**
+	 * Set the position of this {@link ADQLFunction} in the ADQL query string.
+	 * 
+	 * @param position	New position of this {@link ADQLFunction}
+	 * @since 1.3
+	 */
+	public final void setPosition(final TextPosition position){
+		this.position = position;
+	}
+
 	/**
 	 * Gets the number of parameters this function has.
 	 * 
@@ -82,11 +102,13 @@ public abstract class ADQLFunction implements ADQLOperand {
 		return new ParameterIterator(this);
 	}
 
+	@Override
 	public ADQLIterator adqlIterator(){
 		return new ADQLIterator(){
 
 			private int index = -1;
 
+			@Override
 			public ADQLObject next(){
 				try{
 					return getParameter(++index);
@@ -95,10 +117,12 @@ public abstract class ADQLFunction implements ADQLOperand {
 				}
 			}
 
+			@Override
 			public boolean hasNext(){
 				return index + 1 < getNbParameters();
 			}
 
+			@Override
 			public void replace(ADQLObject replacer) throws UnsupportedOperationException, IllegalStateException{
 				if (index <= -1)
 					throw new IllegalStateException("replace(ADQLObject) impossible: next() has not yet been called !");
@@ -116,6 +140,7 @@ public abstract class ADQLFunction implements ADQLOperand {
 					throw new UnsupportedOperationException("Impossible to replace the " + index + "-th parameter of \"" + toADQL() + "\" by an object whose the class (" + replacer.getClass().getName() + ") is not ADQLOperand !");
 			}
 
+			@Override
 			public void remove(){
 				if (index <= -1)
 					throw new IllegalStateException("remove() impossible: next() has not yet been called !");
@@ -125,6 +150,7 @@ public abstract class ADQLFunction implements ADQLOperand {
 		};
 	}
 
+	@Override
 	public String toADQL(){
 		String adql = getName() + "(";
 
@@ -152,15 +178,18 @@ public abstract class ADQLFunction implements ADQLOperand {
 				function = fct;
 		}
 
+		@Override
 		public boolean hasNext(){
 			return (index + 1) < function.getNbParameters();
 		}
 
+		@Override
 		public ADQLOperand next(){
 			index++;
 			return function.getParameter(index);
 		}
 
+		@Override
 		public void remove() throws UnsupportedOperationException{
 			try{
 				function.setParameter(index, null);
diff --git a/src/adql/query/operand/function/DefaultUDF.java b/src/adql/query/operand/function/DefaultUDF.java
index 55cafc3..2ab08bd 100644
--- a/src/adql/query/operand/function/DefaultUDF.java
+++ b/src/adql/query/operand/function/DefaultUDF.java
@@ -22,13 +22,14 @@ package adql.query.operand.function;
 import adql.query.ADQLList;
 import adql.query.ADQLObject;
 import adql.query.ClauseADQL;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
  * It represents any function which is not managed by ADQL.
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (04/2014)
+ * @version 1.3 (05/2014)
  */
 public final class DefaultUDF extends UserDefinedFunction {
 
@@ -60,6 +61,7 @@ public final class DefaultUDF extends UserDefinedFunction {
 	public DefaultUDF(DefaultUDF toCopy) throws Exception{
 		functionName = toCopy.functionName;
 		parameters = (ADQLList<ADQLOperand>)(toCopy.parameters.getCopy());
+		setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));;
 	}
 
 	@Override
@@ -108,7 +110,9 @@ public final class DefaultUDF extends UserDefinedFunction {
 	 */
 	@Override
 	public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{
-		return parameters.set(index, replacer);
+		ADQLOperand oldParam = parameters.set(index, replacer);
+		setPosition(null);
+		return oldParam;
 	}
 
 }
diff --git a/src/adql/query/operand/function/MathFunction.java b/src/adql/query/operand/function/MathFunction.java
index 0e89163..88e06e0 100644
--- a/src/adql/query/operand/function/MathFunction.java
+++ b/src/adql/query/operand/function/MathFunction.java
@@ -21,13 +21,14 @@ package adql.query.operand.function;
  */
 
 import adql.query.ADQLObject;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
  * It represents any basic mathematical function.
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (03/2014)
+ * @version 1.3 (05/2014)
  * 
  * @see MathFunctionType
  */
@@ -116,6 +117,7 @@ public class MathFunction extends ADQLFunction {
 		type = toCopy.type;
 		param1 = (ADQLOperand)toCopy.param1.getCopy();
 		param2 = (ADQLOperand)toCopy.param2.getCopy();
+		setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));
 	}
 
 	/**
@@ -193,10 +195,12 @@ public class MathFunction extends ADQLFunction {
 				case 0:
 					replaced = param1;
 					param1 = replacer;
+					setPosition(null);
 					break;
 				case 1:
 					replaced = param2;
 					param2 = replacer;
+					setPosition(null);
 					break;
 			}
 			return replaced;
diff --git a/src/adql/query/operand/function/SQLFunction.java b/src/adql/query/operand/function/SQLFunction.java
index 3442aea..588eba8 100644
--- a/src/adql/query/operand/function/SQLFunction.java
+++ b/src/adql/query/operand/function/SQLFunction.java
@@ -16,18 +16,19 @@ package adql.query.operand.function;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2011,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
+import adql.query.TextPosition;
 import adql.query.operand.ADQLOperand;
 
 /**
  * It represents any SQL function (COUNT, MAX, MIN, AVG, SUM, etc...).
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  * 
  * @see SQLFunctionType
  */
@@ -87,6 +88,7 @@ public class SQLFunction extends ADQLFunction {
 		type = toCopy.type;
 		param = (ADQLOperand)toCopy.param.getCopy();
 		distinct = toCopy.distinct;
+		setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));;
 	}
 
 	/**
@@ -105,6 +107,7 @@ public class SQLFunction extends ADQLFunction {
 	 */
 	public void setDistinct(boolean distinctValues){
 		distinct = distinctValues;
+		setPosition(null);
 	}
 
 	/**
@@ -116,18 +119,22 @@ public class SQLFunction extends ADQLFunction {
 		return type;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new SQLFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return type.name();
 	}
 
+	@Override
 	public final boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public final boolean isString(){
 		return false;
 	}
@@ -163,6 +170,7 @@ public class SQLFunction extends ADQLFunction {
 
 		ADQLOperand replaced = param;
 		param = replacer;
+		setPosition(null);
 
 		return replaced;
 	}
diff --git a/src/adql/query/operand/function/geometry/AreaFunction.java b/src/adql/query/operand/function/geometry/AreaFunction.java
index 42906c9..aa59e83 100644
--- a/src/adql/query/operand/function/geometry/AreaFunction.java
+++ b/src/adql/query/operand/function/geometry/AreaFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the AREA function of ADQL.</p>
@@ -33,8 +33,8 @@ import adql.query.operand.ADQLColumn;
  * 
  * <p>Inappropriate geometries for this construct (e.g. POINT) SHOULD either return zero or throw an error message. <b>This choice must be done in an extended class of {@link AreaFunction}</b>.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class AreaFunction extends GeometryFunction {
 
@@ -47,7 +47,6 @@ public class AreaFunction extends GeometryFunction {
 	 * @param param					Parameter of AREA.
 	 * @throws NullPointerException	If the given operand is <i>null</i> or if it's not a {@link GeometryFunction}.
 	 */
-	@SuppressWarnings("unchecked")
 	public AreaFunction(GeometryValue<GeometryFunction> param) throws NullPointerException{
 		super();
 		if (param == null)
@@ -86,20 +85,25 @@ public class AreaFunction extends GeometryFunction {
 	 */
 	public final void setParameter(GeometryValue<GeometryFunction> parameter){
 		this.parameter = parameter;
+		setPosition(null);
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new AreaFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "AREA";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -137,6 +141,7 @@ public class AreaFunction extends GeometryFunction {
 				parameter.setGeometry((GeometryFunction)replacer);
 			else
 				throw new Exception("Impossible to replace a GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
+			setPosition(null);
 			return replaced;
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
diff --git a/src/adql/query/operand/function/geometry/BoxFunction.java b/src/adql/query/operand/function/geometry/BoxFunction.java
index e907133..485c098 100644
--- a/src/adql/query/operand/function/geometry/BoxFunction.java
+++ b/src/adql/query/operand/function/geometry/BoxFunction.java
@@ -16,11 +16,11 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -39,8 +39,8 @@ import adql.query.operand.ADQLOperand;
  * </i></p>
  * 
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class BoxFunction extends GeometryFunction {
 
@@ -93,18 +93,22 @@ public class BoxFunction extends GeometryFunction {
 		height = (ADQLOperand)(toCopy.height.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new BoxFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "BOX";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
@@ -125,6 +129,7 @@ public class BoxFunction extends GeometryFunction {
 	 */
 	public final void setCoord1(ADQLOperand coord1){
 		this.coord1 = coord1;
+		setPosition(null);
 	}
 
 	/**
@@ -143,6 +148,7 @@ public class BoxFunction extends GeometryFunction {
 	 */
 	public final void setCoord2(ADQLOperand coord2){
 		this.coord2 = coord2;
+		setPosition(null);
 	}
 
 	/**
@@ -161,6 +167,7 @@ public class BoxFunction extends GeometryFunction {
 	 */
 	public final void setWidth(ADQLOperand width){
 		this.width = width;
+		setPosition(null);
 	}
 
 	/**
@@ -179,6 +186,7 @@ public class BoxFunction extends GeometryFunction {
 	 */
 	public final void setHeight(ADQLOperand height){
 		this.height = height;
+		setPosition(null);
 	}
 
 	@Override
@@ -241,6 +249,7 @@ public class BoxFunction extends GeometryFunction {
 			default:
 				throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
 		}
+		setPosition(null);
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/CentroidFunction.java b/src/adql/query/operand/function/geometry/CentroidFunction.java
index 88f80e3..8ef5af3 100644
--- a/src/adql/query/operand/function/geometry/CentroidFunction.java
+++ b/src/adql/query/operand/function/geometry/CentroidFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the CENTROID function of the ADQL language.</p>
@@ -35,8 +35,8 @@ import adql.query.operand.ADQLColumn;
  * in a position of (25.4,-20.0) degrees and defined according to the ICRS coordinate system with GEOCENTER reference position.
  * </i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class CentroidFunction extends GeometryFunction {
 
@@ -68,18 +68,22 @@ public class CentroidFunction extends GeometryFunction {
 		parameter = (GeometryValue<GeometryFunction>)(toCopy.parameter.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new CentroidFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "CENTROID";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -117,6 +121,7 @@ public class CentroidFunction extends GeometryFunction {
 				parameter.setGeometry((GeometryFunction)replacer);
 			else
 				throw new Exception("Impossible to replace a GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
+			setPosition(null);
 			return replaced;
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
diff --git a/src/adql/query/operand/function/geometry/CircleFunction.java b/src/adql/query/operand/function/geometry/CircleFunction.java
index aff59d8..aa0efdb 100644
--- a/src/adql/query/operand/function/geometry/CircleFunction.java
+++ b/src/adql/query/operand/function/geometry/CircleFunction.java
@@ -16,11 +16,11 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -35,8 +35,8 @@ import adql.query.operand.ADQLOperand;
  * according to the ICRS coordinate system with GEOCENTER reference position.
  * </i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class CircleFunction extends GeometryFunction {
 
@@ -83,18 +83,22 @@ public class CircleFunction extends GeometryFunction {
 		radius = (ADQLOperand)(toCopy.radius.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new CircleFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "CIRCLE";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
@@ -115,6 +119,7 @@ public class CircleFunction extends GeometryFunction {
 	 */
 	public final void setCoord1(ADQLOperand coord1){
 		this.coord1 = coord1;
+		setPosition(null);
 	}
 
 	/**
@@ -133,6 +138,7 @@ public class CircleFunction extends GeometryFunction {
 	 */
 	public final void setCoord2(ADQLOperand coord2){
 		this.coord2 = coord2;
+		setPosition(null);
 	}
 
 	/**
@@ -151,6 +157,7 @@ public class CircleFunction extends GeometryFunction {
 	 */
 	public final void setRadius(ADQLOperand radius){
 		this.radius = radius;
+		setPosition(null);
 	}
 
 	@Override
@@ -205,6 +212,7 @@ public class CircleFunction extends GeometryFunction {
 			default:
 				throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
 		}
+		setPosition(null);
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/ContainsFunction.java b/src/adql/query/operand/function/geometry/ContainsFunction.java
index f97a9c7..0a99325 100644
--- a/src/adql/query/operand/function/geometry/ContainsFunction.java
+++ b/src/adql/query/operand/function/geometry/ContainsFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the CONTAINS function of the ADQL language.</p>
@@ -41,8 +41,8 @@ import adql.query.operand.ADQLColumn;
  * If it can not do so, it SHOULD throw an error message, to be defined by the service making use of ADQL.</li></ul>
  * </b></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class ContainsFunction extends GeometryFunction {
 
@@ -81,18 +81,22 @@ public class ContainsFunction extends GeometryFunction {
 		rightParam = (GeometryValue<GeometryFunction>)(toCopy.rightParam.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new ContainsFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "CONTAINS";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -108,8 +112,10 @@ public class ContainsFunction extends GeometryFunction {
 	 * @param leftParam The leftParam to set.
 	 */
 	public final void setLeftParam(GeometryValue<GeometryFunction> leftParam){
-		if (leftParam != null)
+		if (leftParam != null){
 			this.leftParam = leftParam;
+			setPosition(null);
+		}
 	}
 
 	/**
@@ -123,8 +129,10 @@ public class ContainsFunction extends GeometryFunction {
 	 * @param rightParam The rightParam to set.
 	 */
 	public final void setRightParam(GeometryValue<GeometryFunction> rightParam){
-		if (rightParam != null)
+		if (rightParam != null){
 			this.rightParam = rightParam;
+			setPosition(null);
+		}
 	}
 
 	@Override
@@ -174,6 +182,7 @@ public class ContainsFunction extends GeometryFunction {
 				rightParam.setGeometry((GeometryFunction)replacer);
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
+		setPosition(null);
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/DistanceFunction.java b/src/adql/query/operand/function/geometry/DistanceFunction.java
index d942967..f7aa889 100644
--- a/src/adql/query/operand/function/geometry/DistanceFunction.java
+++ b/src/adql/query/operand/function/geometry/DistanceFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the DISTANCE function of the ADQL language.</p>
@@ -34,8 +34,8 @@ import adql.query.operand.ADQLColumn;
  * In this example the function computes the distance between two points of coordinates (25, -19.5) and (25.4, -20) both expressed according to the ICRS
  * coordinate system with GEOCENTER reference position.</i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class DistanceFunction extends GeometryFunction {
 
@@ -79,18 +79,22 @@ public class DistanceFunction extends GeometryFunction {
 		throw new UnsupportedOperationException("A DISTANCE function is not associated to a coordinate system !");
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new DistanceFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "DISTANCE";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -111,6 +115,7 @@ public class DistanceFunction extends GeometryFunction {
 	 */
 	public final void setP1(GeometryValue<PointFunction> p1){
 		this.p1 = p1;
+		setPosition(null);
 	}
 
 	/**
@@ -129,6 +134,7 @@ public class DistanceFunction extends GeometryFunction {
 	 */
 	public final void setP2(GeometryValue<PointFunction> p2){
 		this.p2 = p2;
+		setPosition(null);
 	}
 
 	@Override
@@ -189,6 +195,8 @@ public class DistanceFunction extends GeometryFunction {
 				toUpdate.setGeometry((PointFunction)replacer);
 		}
 
+		setPosition(null);
+
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/ExtractCoord.java b/src/adql/query/operand/function/geometry/ExtractCoord.java
index 6f016c9..570b79a 100644
--- a/src/adql/query/operand/function/geometry/ExtractCoord.java
+++ b/src/adql/query/operand/function/geometry/ExtractCoord.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the COORD1 and the COORD2 functions of the ADQL language.</p>
@@ -35,8 +35,8 @@ import adql.query.operand.ADQLColumn;
  * system with GEOCENTER reference position.
  * </i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class ExtractCoord extends GeometryFunction {
 
@@ -78,18 +78,22 @@ public class ExtractCoord extends GeometryFunction {
 		point = (GeometryValue<PointFunction>)(toCopy.point.getCopy());
 	}
 
+	@Override
 	public String getName(){
 		return "COORD" + indCoord;
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new ExtractCoord(this);
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -127,6 +131,7 @@ public class ExtractCoord extends GeometryFunction {
 				point.setGeometry((PointFunction)replacer);
 			else
 				throw new Exception("Impossible to replace GeometryValue/Column/PointFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
+			setPosition(null);
 			return replaced;
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
diff --git a/src/adql/query/operand/function/geometry/ExtractCoordSys.java b/src/adql/query/operand/function/geometry/ExtractCoordSys.java
index 5337f49..15cfa30 100644
--- a/src/adql/query/operand/function/geometry/ExtractCoordSys.java
+++ b/src/adql/query/operand/function/geometry/ExtractCoordSys.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the COORDSYS function the ADQL language.</p>
@@ -35,8 +35,8 @@ import adql.query.operand.ADQLColumn;
  * system with GEOCENTER reference position.
  * </i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class ExtractCoordSys extends GeometryFunction {
 
@@ -65,18 +65,22 @@ public class ExtractCoordSys extends GeometryFunction {
 		geomExpr = (GeometryValue<GeometryFunction>)(toCopy.geomExpr.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new ExtractCoordSys(this);
 	}
 
+	@Override
 	public String getName(){
 		return "COORDSYS";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
@@ -114,6 +118,7 @@ public class ExtractCoordSys extends GeometryFunction {
 				geomExpr.setGeometry((GeometryFunction)replacer);
 			else
 				throw new Exception("Impossible to replace GeometryValue/Column/GeometryFunction by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
+			setPosition(null);
 			return replaced;
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function " + getName() + " !");
diff --git a/src/adql/query/operand/function/geometry/GeometryFunction.java b/src/adql/query/operand/function/geometry/GeometryFunction.java
index 4270eb1..7eb29e0 100644
--- a/src/adql/query/operand/function/geometry/GeometryFunction.java
+++ b/src/adql/query/operand/function/geometry/GeometryFunction.java
@@ -16,20 +16,22 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLIterator;
 import adql.query.ADQLObject;
-import adql.query.operand.ADQLOperand;
+import adql.query.TextPosition;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 import adql.query.operand.function.ADQLFunction;
 
 /**
  * <p>It represents any geometric function of ADQL.</p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public abstract class GeometryFunction extends ADQLFunction {
 
@@ -63,6 +65,7 @@ public abstract class GeometryFunction extends ADQLFunction {
 	 */
 	protected GeometryFunction(GeometryFunction toCopy) throws Exception{
 		coordSys = (ADQLOperand)(toCopy.coordSys.getCopy());
+		setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));
 	}
 
 	/**
@@ -87,43 +90,54 @@ public abstract class GeometryFunction extends ADQLFunction {
 			throw new NullPointerException("");
 		else if (!coordSys.isString())
 			throw new Exception("A coordinate system must be a string literal: \"" + coordSys.toADQL() + "\" is not a string operand !");
-		else
+		else{
 			this.coordSys = coordSys;
+			setPosition(null);
+		}
 	}
 
 	/**
 	 * This class represents a parameter of a geometry function
 	 * which, in general, is either a GeometryFunction or a Column.
 	 * 
-	 * @author Gr&eacute;gory Mantelet (CDS)
-	 * @version 06/2011
+	 * @author Gr&eacute;gory Mantelet (CDS;ARI)
+	 * @version 05/2014
 	 */
 	public static final class GeometryValue< F extends GeometryFunction > implements ADQLOperand {
 		private ADQLColumn column;
 		private F geomFunct;
+		/** Position of this {@link GeometryValue} in the ADQL query string.
+		 * @since 1.3 */
+		private TextPosition position = null;
 
 		public GeometryValue(ADQLColumn col) throws NullPointerException{
 			if (col == null)
 				throw new NullPointerException("Impossible to build a GeometryValue without a column or a geometry function !");
 			setColumn(col);
+			if (col.getPosition() != null)
+				position = col.getPosition();
 		}
 
 		public GeometryValue(F geometry) throws NullPointerException{
 			if (geometry == null)
 				throw new NullPointerException("Impossible to build a GeometryValue without a column or a geometry function !");
 			setGeometry(geometry);
+			if (geometry.getPosition() != null)
+				position = geometry.getPosition();
 		}
 
 		@SuppressWarnings("unchecked")
 		public GeometryValue(GeometryValue<F> toCopy) throws Exception{
 			column = (toCopy.column == null) ? null : ((ADQLColumn)(toCopy.column.getCopy()));
 			geomFunct = (toCopy.geomFunct == null) ? null : ((F)(toCopy.geomFunct.getCopy()));
+			position = (toCopy.position == null) ? null : new TextPosition(toCopy.position);
 		}
 
 		public void setColumn(ADQLColumn col){
 			if (col != null){
 				geomFunct = null;
 				column = col;
+				position = (column.getPosition() != null) ? column.getPosition() : null;
 			}
 		}
 
@@ -131,6 +145,7 @@ public abstract class GeometryFunction extends ADQLFunction {
 			if (geometry != null){
 				column = null;
 				geomFunct = geometry;
+				position = (geomFunct.getPosition() != null) ? geomFunct.getPosition() : null;
 			}
 		}
 
@@ -142,26 +157,37 @@ public abstract class GeometryFunction extends ADQLFunction {
 			return column != null;
 		}
 
+		@Override
 		public boolean isNumeric(){
 			return getValue().isNumeric();
 		}
 
+		@Override
 		public boolean isString(){
 			return getValue().isString();
 		}
 
+		@Override
+		public TextPosition getPosition(){
+			return position;
+		}
+
+		@Override
 		public ADQLObject getCopy() throws Exception{
 			return new GeometryValue<F>(this);
 		}
 
+		@Override
 		public String getName(){
 			return getValue().getName();
 		}
 
+		@Override
 		public ADQLIterator adqlIterator(){
 			return getValue().adqlIterator();
 		}
 
+		@Override
 		public String toADQL(){
 			return getValue().toADQL();
 		}
diff --git a/src/adql/query/operand/function/geometry/IntersectsFunction.java b/src/adql/query/operand/function/geometry/IntersectsFunction.java
index 0a37597..046f5e4 100644
--- a/src/adql/query/operand/function/geometry/IntersectsFunction.java
+++ b/src/adql/query/operand/function/geometry/IntersectsFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
-import adql.query.operand.ADQLOperand;
 import adql.query.operand.ADQLColumn;
+import adql.query.operand.ADQLOperand;
 
 /**
  * <p>It represents the INTERSECTS function of the ADQL language.</p>
@@ -42,8 +42,8 @@ import adql.query.operand.ADQLColumn;
  * If it can not do so, it SHOULD throw an error message, to be defined by the service making use of ADQL.</li></ul>
  * </b></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class IntersectsFunction extends GeometryFunction {
 
@@ -82,18 +82,22 @@ public class IntersectsFunction extends GeometryFunction {
 		rightParam = (GeometryValue<GeometryFunction>)(toCopy.rightParam.getCopy());
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new IntersectsFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "INTERSECTS";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return true;
 	}
 
+	@Override
 	public boolean isString(){
 		return false;
 	}
@@ -109,8 +113,10 @@ public class IntersectsFunction extends GeometryFunction {
 	 * @param leftParam The leftParam to set.
 	 */
 	public final void setLeftParam(GeometryValue<GeometryFunction> leftParam){
-		if (leftParam != null)
+		if (leftParam != null){
 			this.leftParam = leftParam;
+			setPosition(null);
+		}
 	}
 
 	/**
@@ -124,8 +130,10 @@ public class IntersectsFunction extends GeometryFunction {
 	 * @param rightParam The rightParam to set.
 	 */
 	public final void setRightParam(GeometryValue<GeometryFunction> rightParam){
-		if (rightParam != null)
+		if (rightParam != null){
 			this.rightParam = rightParam;
+			setPosition(null);
+		}
 	}
 
 	@Override
@@ -175,6 +183,7 @@ public class IntersectsFunction extends GeometryFunction {
 				rightParam.setGeometry((GeometryFunction)replacer);
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
+		setPosition(null);
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/PointFunction.java b/src/adql/query/operand/function/geometry/PointFunction.java
index 626e34f..38a6b45 100644
--- a/src/adql/query/operand/function/geometry/PointFunction.java
+++ b/src/adql/query/operand/function/geometry/PointFunction.java
@@ -16,11 +16,11 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import adql.query.ADQLObject;
-
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -34,8 +34,8 @@ import adql.query.operand.ADQLOperand;
  * In this example the function expresses a point with right ascension of 25 degrees and declination of  -19.5 degrees according
  * to the ICRS coordinate system with GEOCENTER reference position.</i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class PointFunction extends GeometryFunction {
 
@@ -98,8 +98,10 @@ public class PointFunction extends GeometryFunction {
 			throw new NullPointerException("The first coordinate of a POINT function must be different from NULL !");
 		else if (!coord1.isNumeric())
 			throw new Exception("Coordinates of a POINT function must be numeric !");
-		else
+		else{
 			this.coord1 = coord1;
+			setPosition(null);
+		}
 	}
 
 	/**
@@ -123,22 +125,28 @@ public class PointFunction extends GeometryFunction {
 			throw new NullPointerException("The second coordinate of a POINT function must be different from NULL !");
 		else if (!coord2.isNumeric())
 			throw new Exception("Coordinates of a POINT function must be numeric !");
-		else
+		else{
 			this.coord2 = coord2;
+			setPosition(null);
+		}
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new PointFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "POINT";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
@@ -190,6 +198,8 @@ public class PointFunction extends GeometryFunction {
 				throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" !");
 		}
 
+		setPosition(null);
+
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/PolygonFunction.java b/src/adql/query/operand/function/geometry/PolygonFunction.java
index 07e47ba..3dfede4 100644
--- a/src/adql/query/operand/function/geometry/PolygonFunction.java
+++ b/src/adql/query/operand/function/geometry/PolygonFunction.java
@@ -16,13 +16,13 @@ package adql.query.operand.function.geometry;
  * 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 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
+ * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS),
+ *                       Astronomishes Rechen Institute (ARI)
  */
 
 import java.util.Vector;
 
 import adql.query.ADQLObject;
-
 import adql.query.operand.ADQLOperand;
 
 /**
@@ -40,8 +40,8 @@ import adql.query.operand.ADQLOperand;
  * In this example the function expresses a triangle, whose vertices are (10.0, -10.5), (20.0, 20.5) and (30.0, 30.5) in degrees
  * according to the STC coordinate system with GEOCENTER reference position.</i></p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 06/2011
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 1.3 (05/2014)
  */
 public class PolygonFunction extends GeometryFunction {
 
@@ -102,18 +102,22 @@ public class PolygonFunction extends GeometryFunction {
 			coordinates.add((ADQLOperand)(item.getCopy()));
 	}
 
+	@Override
 	public ADQLObject getCopy() throws Exception{
 		return new PolygonFunction(this);
 	}
 
+	@Override
 	public String getName(){
 		return "POLYGON";
 	}
 
+	@Override
 	public boolean isNumeric(){
 		return false;
 	}
 
+	@Override
 	public boolean isString(){
 		return true;
 	}
@@ -158,6 +162,9 @@ public class PolygonFunction extends GeometryFunction {
 			coordinates.set(index - 1, replacer);
 		}else
 			throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + getName() + "\" (" + toADQL() + ") !");
+
+		setPosition(null);
+
 		return replaced;
 	}
 
diff --git a/src/adql/query/operand/function/geometry/RegionFunction.java b/src/adql/query/operand/function/geometry/RegionFunction.java
index 05ccf5e..404423d 100644
--- a/src/adql/query/operand/function/geometry/RegionFunction.java
+++ b/src/adql/query/operand/function/geometry/RegionFunction.java
@@ -38,7 +38,7 @@ import adql.query.operand.ADQLOperand;
  * Inappropriate geometries for this construct SHOULD throw an error message, to be defined by the service making use of ADQL.</b></p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 1.2 (02/2014)
+ * @version 1.3 (05/2014)
  */
 public class RegionFunction extends GeometryFunction {
 
@@ -117,6 +117,7 @@ public class RegionFunction extends GeometryFunction {
 			else if (replacer instanceof ADQLOperand){
 				ADQLOperand replaced = parameter;
 				parameter = replacer;
+				setPosition(null);
 				return replaced;
 			}else
 				throw new Exception("Impossible to replace an ADQLOperand by a " + replacer.getClass().getName() + " (" + replacer.toADQL() + ") !");
diff --git a/test/adql/TestGetPositionInAllADQLObject.java b/test/adql/TestGetPositionInAllADQLObject.java
new file mode 100644
index 0000000..19744e9
--- /dev/null
+++ b/test/adql/TestGetPositionInAllADQLObject.java
@@ -0,0 +1,27 @@
+package adql;
+
+import java.util.Iterator;
+
+import adql.parser.ADQLParser;
+import adql.query.ADQLObject;
+import adql.query.ADQLQuery;
+import adql.search.SimpleSearchHandler;
+
+public class TestGetPositionInAllADQLObject {
+
+	public static void main(String[] args) throws Throwable{
+		ADQLParser parser = new ADQLParser();
+		ADQLQuery query = parser.parseQuery("SELECT truc, bidule.machin FROM foo JOIN bidule USING(id) WHERE truc > 12.5 AND bidule.machin < 5");
+
+		System.out.println("\nOBJECT WITH NO DEFINED POSITION:");
+		Iterator<ADQLObject> results = query.search(new SimpleSearchHandler(true){
+			@Override
+			protected boolean match(ADQLObject obj){
+				return obj.getPosition() == null;
+			}
+		});
+		while(results.hasNext())
+			System.out.println("    * " + results.next().toADQL());
+	}
+
+}
-- 
GitLab