diff --git a/src/adql/parser/ADQLParser.java b/src/adql/parser/ADQLParser.java
index b1649f8a3a5e508e0ee2b99ab910b198977687c1..f5f1e54d1a949ad4d2061bc700674a78216de4b6 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 cf75565a791da7dda1c52e7a91f37ac6498c5a89..e69af55581bc59a5c723daf82e5f639616ced299 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 4e4d9ccacac9e6978b879eca02d022d91348d0e9..15441617d4a598b379a86b537a7081e68d30579b 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 daef3dc567acbd9ee71e4b6b6729220e0349fb4e..12887f4d69e8e34afc5b2f98767cb04834636282 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 bfac21d80477977153f30f41f3df1e0a7554b4fd..cc2d75e2291a7d9086615c150f19960e947bf4ea 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 25d5933bdc4692b6e6297090ab6c902315fead9c..5c6371fb280d3d3b9ffed4f26e837e2c03358e62 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 40776cf1f72171205e5835b031dab3a3a1f0d166..85ebaa043519a3a2158b033eb517f6f9fc34c0f5 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 ffbc9971fe6504237e797d8bb6937d873b9af731..3f4729476923b3f3652035ae0c6ac5b8f8b3d96d 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 b94159f7cbab1ec762e944c221661cc3aafcffe3..0096fb012c4532ca8d14dc0002b86c1592654415 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 595e762482a24502ce2db1bd7eb89d86e120b6eb..41795cc9de3730b6c8d8be2a5354e16bd04f02c8 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 e7d086aa64e47dc19cf36207904307e7f0debcaa..5bda46a1d2326edf8bf0c3f5eff91de8c023f98c 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 28cecbd4ba60221013da2eefd92c275cd4cd3da1..430fec1a3de2e00443fec0f544d1e2f4142205dc 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 8aeab2e2e1e1444d31003bcb9e2339307cf22907..14b2d1bd72f368dc53c0e36d72e1620b000ace8a 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 363588ff01bd554ab862411ce7abb0c4e0129a20..92c119789b5d31031fb4c02206b3dfe86244ce8e 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 2ea7ffa10727f19d2530130f0cda0a0a442415b2..a5079849a12b210a40004d0dddd848766259a538 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 666654df3b61b0afa29ec7e1417fe246866aa525..529a140a3eca41c99e6fd314650109b179041d67 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 77caae147ec5d6b278eede5f4f7d34b9d7f1ed31..8d6f400867be91dd0637508bd02b78768157c388 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 9c9cb1420c09b01f41dad9e9491abc763772f7a8..6cbc8c57914d310213215fc38c04f72ac5e26779 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 e9157f8f273b04a4e0111e6c32aa9b229ef7b7f8..e7ad5c20f1b64e0b3dec064e7ed029dec1b76cdf 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 d148bd70b061976d74f32df28891bed940bd9e11..590f8b5048e1b2e4fc187093d7526767cb1eeb8a 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 82fad6bb3691b3dbaa474902526b68a8c3fdbc4c..39bb608d70aafebdedc5fa6c6e64a57373ad244d 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 2baa6d260079d0f290cab19b9f1983f1a1d3881f..a0c93fd6a4d9a97f1280c2b7b982f9adede7f7b2 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 b5398ffeabc4864e09e40bf369402850cefd1c6e..09daee20eb2381e060c21e13ac0424497b6a8fa1 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 2e2b0d4ff1e5cc5e942f9c16120909ff5d687a0c..1551912c630a075667c760dea6c36ab3b948d143 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 2ffae9bfd13bb85ed39029eef00bea7b5f9760dc..92ab7bfaae0ca5b6c2d354c2f2a6e7cf74710657 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 97a22b7f30340c0fcd5d74be2febc83ff9e0675b..ed9dac72ba6c33844257dc0c834b5596388e4c80 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 55cafc3057db3058532fffffdbfb22d74762f486..2ab08bdcdfbb9aece9ffbee4c3888914a3c97f3f 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 0e89163424abaf080b407b71e5750ca5cba3f87d..88e06e06d171d19ef2ff0bea28cc38f50ef6c484 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 3442aea581efa2e092d1eb65a78bdab9f62db74c..588eba8ceef3f3154697c76cb8ac754d0f2e53e6 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 42906c9811341c3c2929f26b3befe67f801fddef..aa59e83a0d08dcf4fe51f30bf7e1776726822c42 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 e9071330227d2d550e05cebba42a20ae8faca7fa..485c0982b8f483ceaf31a56574eb7261eb1e591d 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 88f80e3fe0a3d97d516f0b73b79ec35c71fcc0af..8ef5af3e2021a1a4243b2b6d35b2488547d4d015 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 aff59d89e1832212617fff22d4a6a8f2b27ad34a..aa0efdb8fa7d4d1cb34e11fda2ec9f4140218ac8 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 f97a9c7614240b3703aa1c75c97c9bcef54bbc2d..0a99325409a80733f87cfcccc34fa2ca76714305 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 d9429675837a943e30a23ad807ef5611ba98964c..f7aa8896733821b8037d15def7a5c9d1617304da 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 6f016c9c0ca356d495587262df438eb758ba4116..570b79a96be8573cb02e2ced79dc536ae7ba1698 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 5337f494b43151115804d82f0139fa3c1bd4083c..15cfa30ac9e49584e288ba61c522d868422823dc 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 4270eb183e469f6c6f144d7202a57766b9e64b19..7eb29e0a19711fe00856b9cda1013605753538bd 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 0a37597eadac5b751740c327abb68402f33be157..046f5e4a01304570eeb7755cb665108cc8ab0392 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 626e34f22a0cbd7ed93ec71ea5f228cc87643f6a..38a6b458e0d19e333a806538b22345dc5638fb26 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 07e47ba629e47d979dae71d4db2c36f33819f866..3dfede4d3bf90e7e977bc4ab74913b0ba03ff055 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 05ccf5e43200b9e238b64c25cfcd42b15289ef11..404423d3e82d32d85ca83bf7fde8ec8f2830580b 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 0000000000000000000000000000000000000000..19744e9b7aa31411ab1d7e5596a9755c6ebdd5a3
--- /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());
+	}
+
+}