diff --git a/src/tap/ADQLExecutor.java b/src/tap/ADQLExecutor.java
index a0ffd3e2767da702839e40aeb05bbb0aa97b6dfc..f46701388fb786300ca15795df593fe5475a9ca2 100644
--- a/src/tap/ADQLExecutor.java
+++ b/src/tap/ADQLExecutor.java
@@ -44,7 +44,6 @@ import uws.service.log.UWSLog.LogLevel;
 import adql.parser.ADQLParser;
 import adql.parser.ADQLQueryFactory;
 import adql.parser.ParseException;
-import adql.parser.QueryChecker;
 import adql.query.ADQLQuery;
 
 /**
@@ -508,18 +507,22 @@ public class ADQLExecutor {
 		// Log the start of the parsing:
 		logger.logTAP(LogLevel.INFO, report, "PARSING", "Parsing ADQL: " + tapParams.getQuery().replaceAll("(\t|\r?\n)+", " "), null);
 
-		// Get the ADQL factory:
-		ADQLQueryFactory queryFactory = service.getFactory().createQueryFactory();
+		// Create the ADQL parser:
+		ADQLParser parser = service.getFactory().createADQLParser();
+		if (parser == null){
+			logger.logTAP(LogLevel.WARNING, null, "PARSING", "No ADQL parser returned by the TAPFactory! The default implementation is used instead.", null);
+			parser = new ADQLParser();
+		}
+
+		// Set the ADQL factory:
+		if (parser.getQueryFactory() == null || parser.getQueryFactory().getClass() == ADQLQueryFactory.class)
+			parser.setQueryFactory(service.getFactory().createQueryFactory());
 
-		// Get the query checker:
-		QueryChecker queryChecker = service.getFactory().createQueryChecker(uploadSchema);
+		// Set the query checker:
+		if (parser.getQueryChecker() == null)
+			parser.setQueryChecker(service.getFactory().createQueryChecker(uploadSchema));
 
 		// Parse the ADQL query:
-		ADQLParser parser;
-		if (queryFactory == null)
-			parser = new ADQLParser(queryChecker);
-		else
-			parser = new ADQLParser(queryChecker, queryFactory);
 		ADQLQuery query = parser.parseQuery(tapParams.getQuery());
 
 		// Set or check the row limit:
diff --git a/src/tap/AbstractTAPFactory.java b/src/tap/AbstractTAPFactory.java
index 7642a5240554c3af5f54a19b3a2d5532a46fe4a4..74ac6014dad1d355576d4e9b2834a9608f4eca1c 100644
--- a/src/tap/AbstractTAPFactory.java
+++ b/src/tap/AbstractTAPFactory.java
@@ -43,6 +43,7 @@ import uws.service.UWSService;
 import uws.service.backup.UWSBackupManager;
 import uws.service.error.ServiceErrorWriter;
 import adql.db.DBChecker;
+import adql.parser.ADQLParser;
 import adql.parser.ADQLQueryFactory;
 import adql.parser.ParseException;
 import adql.parser.QueryChecker;
@@ -53,7 +54,7 @@ import adql.query.ADQLQuery;
  * Only the functions related with the database connection stay abstract.
  * 
  * @author Grégory Mantelet (CDS;ARI)
- * @version 2.0 (02/2015)
+ * @version 2.0 (04/2015)
  */
 public abstract class AbstractTAPFactory extends TAPFactory {
 
@@ -112,6 +113,16 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 		return new ADQLExecutor(service);
 	}
 
+	/**
+	 * <p><i>Note:
+	 * 	This function should be extended if you want to customize the ADQL grammar.
+	 * </i></p>
+	 */
+	@Override
+	public ADQLParser createADQLParser() throws TAPException{
+		return new ADQLParser();
+	}
+
 	/**
 	 * <p><i>Note:
 	 * 	This function should be extended if you have customized the creation of any
diff --git a/src/tap/TAPFactory.java b/src/tap/TAPFactory.java
index bea7adeb4ff84270d383f8925c913b8230f6b2e8..19624ff9420107f3b887a5922909bb8e473fb6e5 100644
--- a/src/tap/TAPFactory.java
+++ b/src/tap/TAPFactory.java
@@ -42,6 +42,7 @@ import uws.service.backup.UWSBackupManager;
 import uws.service.error.ServiceErrorWriter;
 import uws.service.file.UWSFileManager;
 import uws.service.request.RequestParser;
+import adql.parser.ADQLParser;
 import adql.parser.ADQLQueryFactory;
 import adql.parser.QueryChecker;
 import adql.query.ADQLQuery;
@@ -56,11 +57,13 @@ import adql.query.ADQLQuery;
  * 	<li>whether and how UWS/asynchronous jobs must be backuped and restored? <i>({@link UWSBackupManager})</i></li>
  * 	<li>how to create asynchronous jobs? <i>({@link TAPJob})</i></li>
  * 	<li>whether and how tables must be updated? <i>({@link Uploader})</i></li>
+ * 	<li>how to execute an ADQL query? <i>({@link ADQLExecutor})</i>
+ * 	<li>how to parser an ADQL query? <i>({@link ADQLParser})</i></li>
  * 	<li>how to check ADQL queries? <i>({@link QueryChecker})</i></li>
  * </ul>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.0 (02/2015)
+ * @version 2.0 (04/2015)
  */
 public abstract class TAPFactory implements UWSFactory {
 
@@ -177,9 +180,37 @@ public abstract class TAPFactory implements UWSFactory {
 	 */
 	public abstract ADQLExecutor createADQLExecutor() throws TAPException;
 
+	/**
+	 * <p>Create a parser of ADQL query.</p>
+	 * 
+	 * <p><i>Warning:
+	 * 	This parser can be created with a query factory and/or a query checker.
+	 * 	{@link #createQueryFactory()} will be used only if the default query factory (or none) is set
+	 * 	in the ADQL parser returned by this function.
+	 * 	Idem for {@link #createQueryChecker(TAPSchema)}: it will used only if no query checker is set
+	 * 	in the returned ADQL parser.
+	 * </i></p>
+	 * 
+	 * <p><i>Note:
+	 * 	A default implementation is provided by {@link AbstractTAPFactory}.
+	 * </i></p>
+	 * 
+	 * @return	An ADQL query parser.
+	 * 
+	 * @throws TAPException	If any error occurs while creating an ADQL parser.
+	 * 
+	 * @since 2.0
+	 */
+	public abstract ADQLParser createADQLParser() throws TAPException;
+
 	/**
 	 * <p>Create a factory able to build every part of an {@link ADQLQuery} object.</p>
 	 * 
+	 * <p><i>Warning:
+	 * 	This function is used only if the default query factory (or none) is set in the ADQL parser
+	 * 	returned by {@link #createADQLParser()}.
+	 * </i></p>
+	 * 
 	 * <p><i>Note:
 	 * 	A default implementation is provided by {@link AbstractTAPFactory}
 	 * </i></p> 
@@ -195,6 +226,11 @@ public abstract class TAPFactory implements UWSFactory {
 	 * That's to say, it checks whether the tables and columns used in the query really exist
 	 * in the database.</p>
 	 * 
+	 * <p><i>Warning:
+	 * 	This function is used only if no query checker is set in the ADQL parser
+	 * 	returned by {@link #createADQLParser()}.
+	 * </i></p>
+	 * 
 	 * <p><i>Note:
 	 * 	A default implementation is provided by {@link AbstractTAPFactory}
 	 * </i></p>
diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html
index 381d84e12057941f78c66c7f64f782fbdbbbcd94..57c6967ed2a63b000697a45b682867db7f7a5251 100644
--- a/src/tap/config/tap_configuration_file.html
+++ b/src/tap/config/tap_configuration_file.html
@@ -695,8 +695,12 @@
 				<td>
 					<p>Class to use in replacement of the default TAPFactory.</p>
 					<p>
-						This property must be a class name (given between {...}). It must reference an extension of the abstract TAPFactory.
-						This extension must have at least one constructor with exactly one parameter of type ServiceConnection.
+						This property must be a class name (given between {...}). It must reference an implementation of TAPFactory.
+						This implementation must have at least one constructor with exactly one parameter of type ServiceConnection.
+					</p>
+					<p>
+						It is recommended to extend an existing implementation such as:
+						tap.AbstractTAPFactory or tap.config.ConfigurableTAPFactory.
 					</p>
 					<p><em>By default, the default TAPFactory (tap.config.ConfigurableTAPFactory) is used and may use all properties related to the backup management,
 					the database access and the ADQL translation.</em></p>
diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties
index 04b67714339a6cba9cd1d455ca6fc4de5a827741..42d614460d592c4cc0bea9187256f2d8558abc0b 100644
--- a/src/tap/config/tap_full.properties
+++ b/src/tap/config/tap_full.properties
@@ -2,7 +2,7 @@
 #             FULL TAP CONFIGURATION FILE                #
 #                                                        #
 # TAP Version: 2.0                                       #
-# Date: 8 April 2015                                     #
+# Date: 9 April 2015                                     #
 # Author: Gregory Mantelet (ARI)                         #
 #                                                        #
 ########################################################## 
@@ -519,8 +519,11 @@ additional_resources =
 # [OPTIONAL]
 # Class to use in replacement of the default TAPFactory.
 # 
-# This property must be a class name (given between {...}). It must reference an extension of the abstract TAPFactory.
-# This extension must have at least one constructor with exactly one parameter of type ServiceConnection.
+# This property must be a class name (given between {...}). It must reference an implementation of TAPFactory.
+# This implementation must have at least one constructor with exactly one parameter of type ServiceConnection.
+# 
+# It is recommended to extend an existing implementation such as:
+# tap.AbstractTAPFactory or tap.config.ConfigurableTAPFactory.
 # 
 # By default, the default TAPFactory (tap.config.ConfigurableTAPFactory) is used and may use all properties related to the backup management,
 # the database access and the ADQL translation.