diff --git a/src/tap/config/ConfigurableServiceConnection.java b/src/tap/config/ConfigurableServiceConnection.java
index f7e7c48955b2b2e6033f33c1d54743482d16f24f..1e178ed1945f8d920d1c1c734d0480a11961fced 100644
--- a/src/tap/config/ConfigurableServiceConnection.java
+++ b/src/tap/config/ConfigurableServiceConnection.java
@@ -49,6 +49,7 @@ import static tap.config.TAPConfiguration.VALUE_XML;
 import static tap.config.TAPConfiguration.fetchClass;
 import static tap.config.TAPConfiguration.getProperty;
 import static tap.config.TAPConfiguration.isClassPath;
+import static tap.config.TAPConfiguration.newInstance;
 import static tap.config.TAPConfiguration.parseLimit;
 
 import java.io.File;
@@ -123,6 +124,9 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 	private Collection<FunctionDef> udfs = new ArrayList<FunctionDef>(0);
 
 	public ConfigurableServiceConnection(final Properties tapConfig) throws NullPointerException, TAPException, UWSException{
+		if (tapConfig == null)
+			throw new NullPointerException("Missing TAP properties! ");
+
 		// 1. INITIALIZE THE FILE MANAGER:
 		initFileManager(tapConfig);
 
@@ -198,20 +202,8 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 			}
 		}
 		// CUSTOM file manager:
-		else{
-			Class<? extends UWSFileManager> classObj = fetchClass(fileManagerType, KEY_FILE_MANAGER, UWSFileManager.class);
-			if (classObj == null)
-				throw new TAPException("Unknown value for the property \"" + KEY_FILE_MANAGER + "\": \"" + fileManagerType + "\". Only two possible values: " + VALUE_LOCAL + " or a class path between {...}.");
-
-			try{
-				fileManager = classObj.getConstructor(Properties.class).newInstance(tapConfig);
-			}catch(Exception e){
-				if (e instanceof TAPException)
-					throw (TAPException)e;
-				else
-					throw new TAPException("Impossible to create a TAPFileManager instance with the constructor (java.util.Properties tapConfig) of \"" + classObj.getName() + "\" for the following reason: " + e.getMessage());
-			}
-		}
+		else
+			fileManager = newInstance(fileManagerType, KEY_FILE_MANAGER, UWSFileManager.class, new Class<?>[]{Properties.class}, new Object[]{tapConfig});
 	}
 
 	private void initLogger(final Properties tapConfig){
@@ -458,18 +450,8 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 					hasVotableFormat = true;
 			}
 			// custom OutputFormat
-			else if (isClassPath(f)){
-				Class<? extends OutputFormat> userOutputFormatClass = fetchClass(f, KEY_OUTPUT_FORMATS, OutputFormat.class);
-				try{
-					OutputFormat userOutputFormat = userOutputFormatClass.getConstructor(ServiceConnection.class).newInstance(this);
-					outputFormats.add(userOutputFormat);
-				}catch(Exception e){
-					if (e instanceof TAPException)
-						throw (TAPException)e;
-					else
-						throw new TAPException("Impossible to create an OutputFormat instance with the constructor (ServiceConnection) of \"" + userOutputFormatClass.getName() + "\" (see the property output_add_format) for the following reason: " + e.getMessage());
-				}
-			}
+			else if (isClassPath(f))
+				outputFormats.add(TAPConfiguration.newInstance(f, KEY_OUTPUT_FORMATS, OutputFormat.class, new Class<?>[]{ServiceConnection.class}, new Object[]{this}));
 			// unknown format
 			else
 				throw new TAPException("Unknown output format: " + f);
diff --git a/src/tap/config/ConfigurableTAPFactory.java b/src/tap/config/ConfigurableTAPFactory.java
index 6fd9c669767c89f556ea4728fb313048ff0b1b12..40edfab4f8d661a852b78f5e45a3141c60924080 100644
--- a/src/tap/config/ConfigurableTAPFactory.java
+++ b/src/tap/config/ConfigurableTAPFactory.java
@@ -60,6 +60,9 @@ public final class ConfigurableTAPFactory extends AbstractTAPFactory {
 	public ConfigurableTAPFactory(ServiceConnection service, final Properties tapConfig) throws NullPointerException, TAPException{
 		super(service);
 
+		if (tapConfig == null)
+			throw new NullPointerException("Missing TAP properties! ");
+
 		/* 1. Configure the database access */
 		final String dbAccessMethod = getProperty(tapConfig, KEY_DATABASE_ACCESS);
 
diff --git a/src/tap/config/ConfigurableTAPServlet.java b/src/tap/config/ConfigurableTAPServlet.java
index 8260eb382b9701a6b0fe7ca6bf0ff7f7a9bc897f..69aa12fcb7c5f03b0d360c8b922e7cd8f4a8ffc4 100644
--- a/src/tap/config/ConfigurableTAPServlet.java
+++ b/src/tap/config/ConfigurableTAPServlet.java
@@ -20,18 +20,18 @@ package tap.config;
  */
 
 import static tap.config.TAPConfiguration.DEFAULT_TAP_CONF_FILE;
+import static tap.config.TAPConfiguration.KEY_ADD_TAP_RESOURCES;
 import static tap.config.TAPConfiguration.KEY_HOME_PAGE;
 import static tap.config.TAPConfiguration.KEY_HOME_PAGE_MIME_TYPE;
 import static tap.config.TAPConfiguration.TAP_CONF_PARAMETER;
-import static tap.config.TAPConfiguration.fetchClass;
 import static tap.config.TAPConfiguration.getProperty;
 import static tap.config.TAPConfiguration.isClassPath;
+import static tap.config.TAPConfiguration.newInstance;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Constructor;
 import java.util.Properties;
 
 import javax.servlet.ServletConfig;
@@ -44,6 +44,7 @@ import tap.ServiceConnection;
 import tap.TAPException;
 import tap.resource.HomePage;
 import tap.resource.TAP;
+import tap.resource.TAPResource;
 
 public class ConfigurableTAPServlet extends HttpServlet {
 	private static final long serialVersionUID = 1L;
@@ -117,21 +118,10 @@ public class ConfigurableTAPServlet extends HttpServlet {
 		if (propValue != null){
 			// If it is a class path, replace the current home page by an instance of this class:
 			if (isClassPath(propValue)){
-				Class<? extends HomePage> newHomePage = null;
 				try{
-					// ...fetch the class:
-					newHomePage = fetchClass(propValue, KEY_HOME_PAGE, HomePage.class);
-					// ...get its constructor with TAP object:
-					Constructor<? extends HomePage> constructor = newHomePage.getConstructor(TAP.class);
-					// ...create a new instance and set it as new home page:
-					tap.setHomePage(constructor.newInstance(tap));
-				}catch(NoSuchMethodException e){
-					throw new ServletException("Missing constructor " + (newHomePage == null ? "HomePage" : newHomePage.getName()) + "(TAP)! This constructor is required to set a new home page to your TAP service.");
-				}catch(Exception ex){
-					if (ex instanceof TAPException)
-						throw new ServletException(ex.getMessage(), (ex.getCause() == null ? ex : ex.getCause()));
-					else
-						throw new ServletException("Impossible to set the specified home page: \"" + propValue + "\"!", ex);
+					tap.setHomePage(newInstance(propValue, KEY_HOME_PAGE, HomePage.class, new Class<?>[]{TAP.class}, new Object[]{tap}));
+				}catch(TAPException te){
+					throw new ServletException(te.getMessage(), te.getCause());
 				}
 			}
 			// If it is a file URI (null, file inside WebContent, file://..., http://..., etc...):
@@ -145,10 +135,33 @@ public class ConfigurableTAPServlet extends HttpServlet {
 			}
 		}
 
-		/* 5. DEFAULT SERVLET INITIALIZATION */
+		/* 5. SET ADDITIONAL TAP RESOURCES */
+		propValue = getProperty(tapConf, KEY_ADD_TAP_RESOURCES);
+		if (propValue != null){
+			// split all list items:
+			String[] lstResources = propValue.split(",");
+			for(String addRes : lstResources){
+				addRes = addRes.trim();
+				// ignore empty items:
+				if (addRes.length() > 0){
+					try{
+						// create an instance of the resource:
+						TAPResource newRes = newInstance(addRes, KEY_ADD_TAP_RESOURCES, TAPResource.class, new Class<?>[]{TAP.class}, new Object[]{tap});
+						if (newRes.getName() == null || newRes.getName().trim().length() == 0)
+							throw new TAPException("TAP resource name missing for the new resource \"" + addRes + "\"! The function getName() of the new TAPResource must return a non-empty and not NULL name. See the property \"" + KEY_ADD_TAP_RESOURCES + "\".");
+						// add it into TAP:
+						tap.addResource(newRes);
+					}catch(TAPException te){
+						throw new ServletException(te.getMessage(), te.getCause());
+					}
+				}
+			}
+		}
+
+		/* 6. DEFAULT SERVLET INITIALIZATION */
 		super.init(config);
 
-		/* 6. FINALLY MAKE THE SERVICE AVAILABLE */
+		/* 7. FINALLY MAKE THE SERVICE AVAILABLE */
 		serviceConn.setAvailable(true, "TAP service available.");
 	}
 
diff --git a/src/tap/config/TAPConfiguration.java b/src/tap/config/TAPConfiguration.java
index 3a6976218926e5438857dd9e07c8511497f7e4b4..f1e5d9fcddbaf800d828753133a7bf3695d91e7e 100644
--- a/src/tap/config/TAPConfiguration.java
+++ b/src/tap/config/TAPConfiguration.java
@@ -2,6 +2,8 @@ package tap.config;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Properties;
@@ -113,6 +115,9 @@ public final class TAPConfiguration {
 	public final static String KEY_UDFS = "udfs";
 	public final static String VALUE_ANY = "ANY";
 
+	/* ADDITIONAL TAP RESOURCES */
+	public final static String KEY_ADD_TAP_RESOURCES = "additional_resources";
+
 	/**
 	 * <p>Read the asked property from the given Properties object.</p>
 	 * <ul>
@@ -187,6 +192,99 @@ public final class TAPConfiguration {
 		}
 	}
 
+	/**
+	 * <p>Create an instance of the specified class. The class name is expected to be surrounded by {} in the given value.</p>
+	 * 
+	 * <p>The instance is created using the empty constructor of the specified class.</p>
+	 * 
+	 * @param value			Value which is supposed to contain the classpath between brackets (see {@link #isClassPath(String)} for more details)
+	 * @param propertyName	Name of the property associated with the parameter "value".
+	 * @param expectedType	Type of the class expected to be returned ; it is also the type which parameterizes this function: C.
+	 * 
+	 * @return	The corresponding instance.
+	 * 
+	 * @throws TAPException	If the class name is incorrect
+	 *                     	or if its type is not compatible with the parameterized type C (represented by the parameter "expectedType")
+	 *                     	or if the specified class has no empty constructor
+	 *                     	or if an error occurred while calling this constructor.
+	 * 
+	 * @see {@link #isClassPath(String)}
+	 * @see #fetchClass(String, String, Class)
+	 */
+	public final static < C > C newInstance(final String propValue, final String propName, final Class<C> expectedType) throws TAPException{
+		return newInstance(propValue, propName, expectedType, null, null);
+	}
+
+	/**
+	 * <p>Create an instance of the specified class. The class name is expected to be surrounded by {} in the given value.</p>
+	 * 
+	 * <p><b>IMPORTANT:</b>
+	 * 	The instance is created using the constructor whose the declaration matches exactly with the given list of parameter types.
+	 * 	The number and types of given parameters MUST match exactly to the list of parameter types.
+	 * </p>
+	 * 
+	 * @param value			Value which is supposed to contain the classpath between brackets (see {@link #isClassPath(String)} for more details)
+	 * @param propertyName	Name of the property associated with the parameter "value".
+	 * @param expectedType	Type of the class expected to be returned ; it is also the type which parameterizes this function: C.
+	 * @param pTypes		List of each constructor parameter type. Each type MUST be exactly the type declared in the class constructor to select. <i>NULL or empty array if no parameter.</i>
+	 * @param parameters	List of all constructor parameters. The number of object MUST match exactly the number of classes provided in the parameter pTypes. <i>NULL or empty array if no parameter.</i>
+	 * 
+	 * @return	The corresponding instance.
+	 * 
+	 * @throws TAPException	If the class name is incorrect
+	 *                     	or if its type is not compatible with the parameterized type C (represented by the parameter "expectedType")
+	 *                     	or if the constructor with the specified parameters can not be found
+	 *                     	or if an error occurred while calling this constructor.
+	 * 
+	 * @see {@link #isClassPath(String)}
+	 * @see #fetchClass(String, String, Class)
+	 */
+	public final static < C > C newInstance(final String propValue, final String propName, final Class<C> expectedType, final Class<?>[] pTypes, final Object[] parameters) throws TAPException{
+		// Ensure the given name is a class name specification:
+		if (!isClassPath(propValue))
+			throw new TAPException("Class name expected for the property \"" + propName + "\" instead of: \"" + propValue + "\"! The specified class must extend/implement " + expectedType.getName() + ".");
+
+		Class<? extends C> classObj = null;
+		try{
+
+			// Fetch the class object:
+			classObj = fetchClass(propValue, propName, expectedType);
+
+			// Get a constructor matching the given parameters list:
+			Constructor<? extends C> constructor = classObj.getConstructor((pTypes == null) ? new Class<?>[0] : pTypes);
+
+			// Finally create a new instance:
+			return constructor.newInstance((parameters == null) ? new Object[0] : parameters);
+
+		}catch(NoSuchMethodException e){
+			// List parameters' type:
+			StringBuffer pTypesStr = new StringBuffer();
+			for(int i = 0; i < pTypes.length; i++){
+				if (pTypesStr.length() > 0)
+					pTypesStr.append(", ");
+				if (pTypes[i] == null)
+					pTypesStr.append("NULL");
+				pTypesStr.append(pTypes[i].getName());
+			}
+			// Throw the error:
+			throw new TAPException("Missing constructor " + classObj.getName() + "(" + pTypesStr.toString() + ")! See the value \"" + propValue + "\" of the property \"" + propName + "\".");
+		}catch(InstantiationException ie){
+			throw new TAPException("Impossible to create an instance of an abstract class: \"" + classObj.getName() + "\"! See the value \"" + propValue + "\" of the property \"" + propName + "\".");
+		}catch(InvocationTargetException ite){
+			if (ite.getCause() != null){
+				if (ite.getCause() instanceof TAPException)
+					throw (TAPException)ite.getCause();
+				else
+					throw new TAPException(ite.getCause());
+			}else
+				throw new TAPException(ite);
+		}catch(TAPException te){
+			throw te;
+		}catch(Exception ex){
+			throw new TAPException("Impossible to create an instance of " + expectedType.getName() + " as specified in the property \"" + propName + "\": \"" + propValue + "\"!", ex);
+		}
+	}
+
 	/**
 	 * <p>Lets parsing a limit (for output, upload, ...) with its numeric value and its unit.</p>
 	 * <p>
diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html
index 08879eedd78e683b74111095f484951996d6e181..82e83a9592a29bf0a5b88f718ef13519c3abc4cf 100644
--- a/src/tap/config/tap_configuration_file.html
+++ b/src/tap/config/tap_configuration_file.html
@@ -595,6 +595,31 @@
 				<td><ul><li>ΓΈ <em>(default)</em></li><li>ANY</li><li>[trim(txt String) -&gt; String], [random() -&gt; DOUBLE]</li><li>[newFct(x double)-&gt;double, {apackage.MyNewFunction}]</li></ul></td>
 			</tr>
 			
+			<tr><td colspan="5">Additional TAP Resources</td></tr>
+			<tr class="optional">
+				<td class="done">additional_resources</td>
+				<td></td>
+				<td>text</td>
+				<td>
+					<p>Comma-separated list of additional TAP resources/end-point.</p>
+					<p>
+						By default, the following standard TAP resources are already existing: /sync, /async, /tables, /capabilities and /availability.
+						With this property, you can add a custom resource to your TAP service (e.g. /adqlValidator, /admin).
+					</p>
+					<p>
+						Each item of the list MUST be the name of a class implementing tap.resource.TAPResource. This class MUST have at least one constructor
+						with exactly one parameter of type tap.resource.TAP.
+					</p>
+					<p>
+						The string returned by tap.resource.TAPResource.getName() will be the resource name, following the root TAP service URL (e.g. if getName()
+						returns "foo", then its access URL will "{tapRoot}/foo"). Then, it is possible to replace TAP resources already existing by using the same
+						name (e.g. if getName() returns "sync", the /sync resource won't be anymore the default Sync resource of this library but your new resource).
+					</p>
+					<p><em>By default, this list is empty ; only the standard TAP resources exist.</em></p>
+				</td>
+				<td>{aPackage.QuickADQLValidator}</td>
+			</tr>
+			
 		</table>
 		<script type="text/javascript">
 			var nb = document.getElementsByClassName("mandatory").length;
diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties
index c8e4b14d1e4970b0a734924af0035938e9459a16..0d5ad3803302f10078f3de259678725eced03b55 100644
--- a/src/tap/config/tap_full.properties
+++ b/src/tap/config/tap_full.properties
@@ -442,3 +442,23 @@ geometries =
 # 
 # Default: no unknown function is allowed.
 udfs = 
+
+########################
+# ADDITIONAL RESOURCES #
+########################
+
+# [OPTIONAL]
+# Comma-separated list of additional TAP resources/end-point.
+# 
+# By default, the following standard TAP resources are already existing: /sync, /async, /tables, /capabilities and /availability.
+# With this property, you can add a custom resource to your TAP service (e.g. /adqlValidator, /admin).
+# 
+# Each item of the list MUST be the name of a class implementing tap.resource.TAPResource. This class MUST have at least one constructor with
+# exactly one parameter of type tap.resource.TAP.
+# 
+# The string returned by tap.resource.TAPResource.getName() will be the resource name, following the root TAP service URL (e.g. if getName()
+# returns "foo", then its access URL will "{tapRoot}/foo"). Then, it is possible to replace TAP resources already existing by using the same
+# name (e.g. if getName() returns "sync", the /sync resource won't be anymore the default Sync resource of this library but your new resource).
+# 
+# By default, this list is empty ; only the standard TAP resources exist.
+additional_resources = 
\ No newline at end of file
diff --git a/src/tap/metadata/TAPSchema.java b/src/tap/metadata/TAPSchema.java
index c43b44ec35ddd945ea04675cb64ff9ddbfdbcf3a..a7634434dc1a35812756844a4771186b826b5c2e 100644
--- a/src/tap/metadata/TAPSchema.java
+++ b/src/tap/metadata/TAPSchema.java
@@ -93,7 +93,7 @@ public class TAPSchema implements Iterable<TAPTable> {
 	 */
 	public TAPSchema(String schemaName){
 		if (schemaName == null || schemaName.trim().length() == 0)
-			throw new NullPointerException("Missing schema name !");
+			throw new NullPointerException("Missing schema name!");
 		int indPrefix = schemaName.lastIndexOf('.');
 		adqlName = (indPrefix >= 0) ? schemaName.substring(indPrefix + 1).trim() : schemaName.trim();
 		dbName = adqlName;
diff --git a/test/tap/config/TestConfigurableServiceConnection.java b/test/tap/config/TestConfigurableServiceConnection.java
index a7534843dc44073b244ca77a77e8e93fa3ac1909..0712d9d2a16f3db534562394ca03820ec88c525c 100644
--- a/test/tap/config/TestConfigurableServiceConnection.java
+++ b/test/tap/config/TestConfigurableServiceConnection.java
@@ -392,7 +392,7 @@ public class TestConfigurableServiceConnection {
 			fail("This MUST have failed because an incorrect File Manager value has been provided!");
 		}catch(Exception e){
 			assertEquals(TAPException.class, e.getClass());
-			assertEquals("Unknown value for the property \"" + KEY_FILE_MANAGER + "\": \"foo\". Only two possible values: " + VALUE_LOCAL + " or a class path between {...}.", e.getMessage());
+			assertEquals("Class name expected for the property \"file_manager\" instead of: \"foo\"! The specified class must extend/implement uws.service.file.UWSFileManager.", e.getMessage());
 		}
 
 		// Custom log level and log rotation:
diff --git a/test/tap/config/TestTAPConfiguration.java b/test/tap/config/TestTAPConfiguration.java
index 5cf52c268b1c43b0554e73607fef5b1f36400711..a7d6390fc0a24471ae23bc75d70a20019eca298f 100644
--- a/test/tap/config/TestTAPConfiguration.java
+++ b/test/tap/config/TestTAPConfiguration.java
@@ -11,13 +11,23 @@ import static tap.config.TAPConfiguration.KEY_FILE_MANAGER;
 import static tap.config.TAPConfiguration.KEY_MAX_OUTPUT_LIMIT;
 import static tap.config.TAPConfiguration.fetchClass;
 import static tap.config.TAPConfiguration.isClassPath;
+import static tap.config.TAPConfiguration.newInstance;
 import static tap.config.TAPConfiguration.parseLimit;
 
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
 import org.junit.Before;
 import org.junit.Test;
 
 import tap.ServiceConnection.LimitUnit;
 import tap.TAPException;
+import tap.metadata.TAPMetadata;
+import tap.metadata.TAPSchema;
+import adql.query.ColumnReference;
 
 public class TestTAPConfiguration {
 
@@ -138,6 +148,110 @@ public class TestTAPConfiguration {
 		}
 	}
 
+	@Test
+	public void testNewInstance(){
+		// VALID CONSTRUCTOR with no parameters:
+		try{
+			TAPMetadata metadata = newInstance("{tap.metadata.TAPMetadata}", "metadata", TAPMetadata.class);
+			assertNotNull(metadata);
+			assertEquals("tap.metadata.TAPMetadata", metadata.getClass().getName());
+		}catch(Exception ex){
+			ex.printStackTrace();
+			fail("This test should have succeeded: the parameters of newInstance(...) are all valid.");
+		}
+
+		// VALID CONSTRUCTOR with some parameters:
+		try{
+			final String schemaName = "MySuperSchema", description = "And its less super description.", utype = "UTYPE";
+			TAPSchema schema = newInstance("{tap.metadata.TAPSchema}", "schema", TAPSchema.class, new Class<?>[]{String.class,String.class,String.class}, new String[]{schemaName,description,utype});
+			assertNotNull(schema);
+			assertEquals("tap.metadata.TAPSchema", schema.getClass().getName());
+			assertEquals(schemaName, schema.getADQLName());
+			assertEquals(description, schema.getDescription());
+			assertEquals(utype, schema.getUtype());
+		}catch(Exception ex){
+			ex.printStackTrace();
+			fail("This test should have succeeded: the constructor TAPSchema(String,String,String) exists.");
+		}
+
+		// VALID CONSTRUCTOR with some parameters whose the type is an extension (not the exact type):
+		OutputStream output = null;
+		File tmp = new File("tmp.empty");
+		try{
+			output = newInstance("{java.io.BufferedOutputStream}", "stream", OutputStream.class, new Class<?>[]{OutputStream.class}, new OutputStream[]{new FileOutputStream(tmp)});
+			assertNotNull(output);
+			assertEquals(BufferedOutputStream.class, output.getClass());
+		}catch(Exception ex){
+			ex.printStackTrace();
+			fail("This test should have succeeded: the constructor TAPSchema(String,String,String) exists.");
+		}finally{
+			try{
+				tmp.delete();
+				if (output != null)
+					output.close();
+			}catch(IOException ioe){}
+		}
+
+		// NOT A CLASS NAME:
+		try{
+			TAPMetadata metadata = newInstance("tap.metadata.TAPMetadata", "metadata", TAPMetadata.class);
+			assertNotNull(metadata);
+			assertEquals("tap.metadata.TAPMetadata", metadata.getClass().getName());
+		}catch(Exception ex){
+			assertEquals(TAPException.class, ex.getClass());
+			assertEquals("Class name expected for the property \"metadata\" instead of: \"tap.metadata.TAPMetadata\"! The specified class must extend/implement tap.metadata.TAPMetadata.", ex.getMessage());
+		}
+
+		// NO MATCHING CONSTRUCTOR:
+		try{
+			newInstance("{tap.metadata.TAPSchema}", "schema", TAPSchema.class, new Class<?>[]{Integer.class}, new Object[]{new Integer(123)});
+		}catch(Exception ex){
+			assertEquals(TAPException.class, ex.getClass());
+			assertEquals("Missing constructor tap.metadata.TAPSchema(java.lang.Integer)! See the value \"{tap.metadata.TAPSchema}\" of the property \"schema\".", ex.getMessage());
+		}
+
+		// VALID CONSTRUCTOR with primitive type:
+		try{
+			ColumnReference colRef = newInstance("{adql.query.ColumnReference}", "colRef", ColumnReference.class, new Class<?>[]{int.class}, new Object[]{123});
+			assertNotNull(colRef);
+			assertEquals(ColumnReference.class, colRef.getClass());
+			assertEquals(123, colRef.getColumnIndex());
+			colRef = newInstance("{adql.query.ColumnReference}", "colRef", ColumnReference.class, new Class<?>[]{int.class}, new Object[]{new Integer(123)});
+			assertNotNull(colRef);
+			assertEquals(ColumnReference.class, colRef.getClass());
+			assertEquals(123, colRef.getColumnIndex());
+		}catch(Exception ex){
+			ex.printStackTrace();
+			fail("This test should have succeeded: the constructor ColumnReference(int) exists.");
+		}
+
+		// WRONG CONSTRUCTOR with primitive type:
+		try{
+			newInstance("{adql.query.ColumnReference}", "colRef", ColumnReference.class, new Class<?>[]{Integer.class}, new Object[]{new Integer(123)});
+		}catch(Exception ex){
+			assertEquals(TAPException.class, ex.getClass());
+			assertEquals("Missing constructor adql.query.ColumnReference(java.lang.Integer)! See the value \"{adql.query.ColumnReference}\" of the property \"colRef\".", ex.getMessage());
+		}
+
+		// THE CONSTRUCTOR THROWS AN EXCEPTION:
+		try{
+			newInstance("{tap.metadata.TAPSchema}", "schema", TAPSchema.class, new Class<?>[]{String.class}, new Object[]{null});
+		}catch(Exception ex){
+			assertEquals(TAPException.class, ex.getClass());
+			assertNotNull(ex.getCause());
+			assertEquals(NullPointerException.class, ex.getCause().getClass());
+			assertEquals("Missing schema name!", ex.getCause().getMessage());
+		}
+
+		// THE CONSTRUCTOR THROWS AN EXCEPTION:
+		try{
+			newInstance("{tap.config.TestTAPConfiguration$ClassAlwaysThrowTAPError}", "tapError", ClassAlwaysThrowTAPError.class);
+		}catch(Exception ex){
+			assertEquals(TAPException.class, ex.getClass());
+			assertEquals("This error is always thrown by ClassAlwaysThrowTAPError ^^", ex.getMessage());
+		}
+	}
+
 	/**
 	 * TEST parseLimit(String,String):
 	 * 	- nothing, -123, 0			=> {-1,LimitUnit.rows}
@@ -285,4 +399,11 @@ public class TestTAPConfiguration {
 		return (ex.getCause() == null || ex.getMessage().equals(ex.getCause().getMessage())) ? ex.getMessage() : ex.getCause().getMessage();
 	}
 
+	private static class ClassAlwaysThrowTAPError {
+		@SuppressWarnings("unused")
+		public ClassAlwaysThrowTAPError() throws TAPException{
+			throw new TAPException("This error is always thrown by ClassAlwaysThrowTAPError ^^");
+		}
+	}
+
 }