diff --git a/src/tap/config/ConfigurableServiceConnection.java b/src/tap/config/ConfigurableServiceConnection.java
index 1b78ae27c4c7e9545bfa2d10164638a0c7d45b96..b13d82f4d14787ef6ae33f350f51cf99c4a559c5 100644
--- a/src/tap/config/ConfigurableServiceConnection.java
+++ b/src/tap/config/ConfigurableServiceConnection.java
@@ -151,9 +151,6 @@ public final class ConfigurableServiceConnection implements ServiceConnection {
 		// 9. CONFIGURE ADQL:
 		initADQLGeometries(tapConfig);
 		initUDFs(tapConfig);
-
-		// 10. MAKE THE SERVICE AVAILABLE:
-		setAvailable(true, "TAP service available.");
 	}
 
 	private void initFileManager(final Properties tapConfig) throws TAPException{
diff --git a/src/tap/config/ConfigurableTAPServlet.java b/src/tap/config/ConfigurableTAPServlet.java
index ddb03fcb2a793a420072cd4456dfaab54f96b43a..72150f4ea97f4ef6b7b2a2851a522f147cd2796b 100644
--- a/src/tap/config/ConfigurableTAPServlet.java
+++ b/src/tap/config/ConfigurableTAPServlet.java
@@ -20,12 +20,16 @@ package tap.config;
  */
 
 import static tap.config.TAPConfiguration.DEFAULT_TAP_CONF_FILE;
+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.getProperty;
 
 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;
@@ -35,6 +39,8 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import tap.ServiceConnection;
+import tap.TAPException;
+import tap.resource.HomePage;
 import tap.resource.TAP;
 
 public class ConfigurableTAPServlet extends HttpServlet {
@@ -90,19 +96,58 @@ public class ConfigurableTAPServlet extends HttpServlet {
 		}
 
 		/* 4. CREATE THE TAP SERVICE */
+		ServiceConnection serviceConn = null;
 		try{
 			// Create the service connection:
-			ServiceConnection serviceConn = new ConfigurableServiceConnection(tapConf);
+			serviceConn = new ConfigurableServiceConnection(tapConf);
 			// Create all the TAP resources:
 			tap = new TAP(serviceConn);
 		}catch(Exception ex){
 			tap = null;
-			throw new ServletException("Impossible to initialize the TAP service!", ex);
+			if (ex instanceof TAPException)
+				throw new ServletException(ex.getMessage(), ex.getCause());
+			else
+				throw new ServletException("Impossible to initialize the TAP service!", ex);
 		}
 
-		// TODO Set the home page file, if any:
+		/* 4Bis. SET THE HOME PAGE */
+		String propValue = getProperty(tapConf, KEY_HOME_PAGE);
+		if (propValue != null){
+			// If it is a class path, replace the current home page by an instance of this class:
+			if (TAPConfiguration.isClassPath(propValue)){
+				Class<? extends HomePage> newHomePage = null;
+				try{
+					// ...fetch the class:
+					newHomePage = TAPConfiguration.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);
+				}
+			}
+			// If it is a file URI (null, file inside WebContent, file://..., http://..., etc...):
+			else{
+				// ...set the given URI:
+				tap.setHomePageURI(propValue);
+				// ...and its MIME type (if any):
+				propValue = getProperty(tapConf, KEY_HOME_PAGE_MIME_TYPE);
+				if (propValue != null)
+					tap.setHomePageMimeType(propValue);
+			}
+		}
 
+		/* 5. DEFAULT SERVLET INITIALIZATION */
 		super.init(config);
+
+		/* 6. FINALLY MAKE THE SERVICE AVAILABLE */
+		serviceConn.setAvailable(true, "TAP service available.");
 	}
 
 	protected final InputStream searchFile(final String filePath, final ServletConfig config){
diff --git a/src/tap/config/TAPConfiguration.java b/src/tap/config/TAPConfiguration.java
index 86808adc93dcbd0def2ed6873d511f24bf54d081..35a965815ecdf70aa4551e93bd3e4c78751c73ce 100644
--- a/src/tap/config/TAPConfiguration.java
+++ b/src/tap/config/TAPConfiguration.java
@@ -70,6 +70,10 @@ public final class TAPConfiguration {
 	public final static String VALUE_DB = "db";
 	public final static String KEY_METADATA_FILE = "metadata_file";
 
+	/* HOME PAGE KEY */
+	public final static String KEY_HOME_PAGE = "home_page";
+	public final static String KEY_HOME_PAGE_MIME_TYPE = "home_page_mime_type";
+
 	/* PROVIDER KEYS */
 	public final static String KEY_PROVIDER_NAME = "provider_name";
 	public final static String KEY_SERVICE_DESCRIPTION = "service_description";
diff --git a/src/tap/config/tap_configuration_file.html b/src/tap/config/tap_configuration_file.html
index e1febf196de74b24b9d5a37d7e78c2c610c40ec5..0d02f63ba0508c9b9a50ef3218239ebb72ebd3da 100644
--- a/src/tap/config/tap_configuration_file.html
+++ b/src/tap/config/tap_configuration_file.html
@@ -33,10 +33,14 @@
 				background-color: #CEE3F6;
 			}
 			th:nth-child(2), td:nth-child(2) {
-				font-weight: bold;
 				text-align: center;
 				max-width: 2em;
 			}
+			tr.mandatory td:nth-child(2):after{
+				color: red;
+				font-weight: bold;
+				content: "M";
+			}
 			td:nth-child(5) {
 				font-family: monospace;
 			}
@@ -50,6 +54,17 @@
 			.todo, .mandatory .todo {color: red; }
 			
 		</style>
+		<script type="text/javascript">
+			function toggleOptional(){
+				var button = document.getElementById("toggleOptional");
+				var display = (button.value == "hide") ? 'none' : '';
+				var lines = document.querySelectorAll("tr.optional");
+				for(var i=0 ; i<lines.length ; i++)
+					lines[i].style.display = display;
+				button.value = (display == '') ? 'hide' : 'show';
+				button.textContent = (display == '') ? 'Hide optional' : 'Show optional';
+			}
+		</script>
 	</head>
 	<body>
 		<h1>TAP Configuration File</h1>
@@ -71,8 +86,10 @@
 		<p><b>Important note:</b> Any limit value is an integer and so can be at most: 2<sup>31</sup>-1 bytes/rows = 2147483647B/R (or also for the byte unit: = 2147483kB = 2147MB = 2GB).
 		Otherwise, you should use the null value 0 to raise the limit constraint.</p>
 		
-		<p><i><u>Legend:</u> <b>M</b> means that the property is mandatory. If nothing is written for the second column, the property is optional.</i>
-	
+		<p><i><u>Legend:</u> <b style="color:red">M</b> means that the property is mandatory. If nothing is written for the second column, the property is optional.</i></p>
+		
+		<button id="toggleOptional" value="hide" onClick="toggleOptional();">Hide optional</button> <i><span id="nbMandatory"></span>/<span id="nbTotal"></span> mandatory properties</i>
+		<br /><br/>
 		<table>
 			<tr>
 				<th>Property</th>
@@ -83,26 +100,44 @@
 			</tr>
 			
 			<tr><td colspan="5">General</td></tr>
-			<tr>
-				<td class="later">service_home_page</td>
+			<tr class="optional">
+				<td class="done">home_page</td>
 				<td></td>
 				<td>text</td>
 				<td>
-					<p>Path to the page which will be the index/home page of the TAP Service.</p>
-					<p><i>A default home page - just listing the TAP resources - is set if none is provided.</i></p>
+					<p>This property lets set a custom home page. 4 different kinds of value are accepted:</p>
+					<ul>
+						<li><u>nothing (default)</u>: the default home page provided by the library (just a simple HTML page displaying a list of all available TAP resources).</li>
+						<li><u>name or relative path of a file</u>: this method MUST be chosen if the new home page is a JSP file. This file MUST be inside the directory WebContent of your web application.</li>
+						<li><u>a URI starting with <code>file://</code></u>: in this method the local file pointed by the URI will be merely returned when the home page will be requested.</li>
+						<li><u>a URL</u>: here, a redirection toward this URL will be made at each request on the home page</li>
+						<li><u>a classpath</u>: the classpath of an extension of tap.resource.HomePage which must replace the default home page resource. This class MUST have at least one constructor with exactly one parameter not NULL of type tap.resource.TAP.</li>
+					</ul>
 				</td>
-				<td><ul><li>home.html</li><li>/home/foo/my_tap_homepage.jsp</li></ul></td>
+				<td><ul><li>my_tap_homepage.jsp</li><li>jsp/my_tap_homepage.jsp</li><li>file:///home/foo/customHomePage.html</li><li>http://...</li><li>{aPackage.NewHomePage}</li></ul></td>
+			</tr>
+			<tr class="optional">
+				<td class="done">home_page_mime_type</td>
+				<td></td>
+				<td>text</td>
+				<td>
+					<p>MIME type of the service home page.</p>
+					<p>This property is used only if the specified "home_page" is a local file path (i.e. if "home_page=file://...").</p>
+					<p>If no value is provided "text/html" will be set by default.</p>
+					<p><i>Default: <code>text/html</code></i></p>
+				</td>
+				<td><ul><li>text/html <em>(default)</em></li><li>text/plain</li><li>application/xml</li></ul></td>
 			</tr>
 			
 			<tr><td colspan="5">Provider</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">provider_name</td>
 				<td></td>
 				<td>text</td>
 				<td>Name of the provider of the TAP Service.</td>
-				<td><ul><li>ARI</li><li>Mr. Smith</li></ul></td>
+				<td></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">service_description</td>
 				<td></td>
 				<td>text</td>
@@ -113,7 +148,7 @@
 			<tr><td colspan="5">Database</td></tr>
 			<tr class="mandatory">
 				<td class="done">database_access</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>Method to use in order to create database connections.</p>
@@ -127,7 +162,7 @@
 			</tr>
 			<tr class="mandatory">
 				<td class="done">sql_translator</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>The translator to use in order to translate ADQL to a SQL compatible with the used DBMS and its spatial extension.</p>
@@ -140,16 +175,16 @@
 			<tr><td colspan="5">&#10551; JNDI datasource <i>(only if database_access=jndi)</i></td></tr>
 			<tr class="mandatory">
 				<td class="done">datasource_jndi_name</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>JNDI name of the datasource. It should be defined in the web application (e.g. in the META-INF/context.xml file in tomcat).</p>
 				</td>
-				<td><ul><li>jdbc/postgres</li><li>jdbc/mydatasource</li><li>mydatasource</li><li>...</li></ul></td>
+				<td><ul><li>jdbc/postgres</li><li>jdbc/mydatasource</li><li>mydatasource</li></ul></td>
 			</tr>
 			
 			<tr><td colspan="5">&#10551; JDBC parameters <i>(only if database_access=jdbc)</i></td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">jdbc_driver</td>
 				<td></td>
 				<td>text</td>
@@ -168,7 +203,7 @@
 			</tr>
 			<tr class="mandatory">
 				<td class="done">jdbc_url</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>It must be a JDBC driver URL.</p>
@@ -177,7 +212,7 @@
 				</td>
 				<td><ul><li>jdbc:postgresql:mydb</li><li>jdbc:postgresql://myserver:1234/mydb</li><li>jdbc:sqlite:Database.db</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">db_username</td>
 				<td></td>
 				<td>text</td>
@@ -187,7 +222,7 @@
 				</td>
 				<td></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">db_password</td>
 				<td></td>
 				<td>text</td>
@@ -202,7 +237,7 @@
 			<tr><td colspan="5">Metadata</td></tr>
 			<tr class="mandatory">
 				<td class="done">metadata</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>Define the way the library must get the list of all schemas, tables and columns to publish and all their metadata (e.g. utype, description, type, ...)</p>
@@ -214,7 +249,7 @@
 				</td>
 				<td><ul><li>xml</li><li>db</li></ul>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">metadata_file</td>
 				<td></td>
 				<td>text</td>
@@ -228,7 +263,7 @@
 			<tr><td colspan="5">Files</td></tr>
 			<tr class="mandatory">
 				<td class="done">file_manager</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>
 					<p>Type of the file manager.</p>
@@ -239,12 +274,12 @@
 			</tr>
 			<tr class="mandatory">
 				<td class="done">file_root_path</td>
-				<td>M</td>
+				<td></td>
 				<td>text</td>
 				<td>File path of the directory in which all TAP files (logs, errors, job results, backup, ...) must be.</td>
 				<td></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">directory_per_user</td>
 				<td></td>
 				<td>boolean</td>
@@ -255,7 +290,7 @@
 				</td>
 				<td><ul><li>true <i>(default)</i></li><li>false</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">group_user_directories</td>
 				<td></td>
 				<td>boolean</td>
@@ -265,7 +300,7 @@
 				</td>
 				<td><ul><li>true</li><li>false <i>(default)</i></li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">default_retention_period</td>
 				<td></td>
 				<td>integer</td>
@@ -278,7 +313,7 @@
 					<p><em>By default query results are kept forever: default_retention_period=0.</em></p></td>
 				<td>86400 <em>(1 day)</em></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">max_retention_period</td>
 				<td></td>
 				<td>integer</td>
@@ -292,7 +327,7 @@
 			</tr>
 			
 			<tr><td colspan="5">UWS Backup</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">backup_frequency</td>
 				<td></td>
 				<td>text or integer</td>
@@ -303,7 +338,7 @@
 				</td>
 				<td><ul><li>never <em>(default)</em></li><li>user_action</li><li>3600000 <em>(1 hour)</em></li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">backup_mode</td>
 				<td></td>
 				<td>text</td>
@@ -316,7 +351,7 @@
 			</tr>
 			
 			<tr><td colspan="5">Asynchronous jobs management</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">max_async_jobs</td>
 				<td></td>
 				<td>integer</td>
@@ -329,7 +364,7 @@
 			</tr>
 			
 			<tr><td colspan="5">Query Execution</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">default_execution_duration</td>
 				<td></td>
 				<td>integer</td>
@@ -342,7 +377,7 @@
 				</td>
 				<td>600000 <em>(10 minutes)</em></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">max_execution_duration</td>
 				<td></td>
 				<td>integer</td>
@@ -357,7 +392,7 @@
 			</tr>
 			
 			<tr><td colspan="5">Output</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">output_add_formats</td>
 				<td></td>
 				<td>text</td>
@@ -368,7 +403,7 @@
 				</td>
 				<td><ul><li>json</li><li>csv</li><li>tsv</li><li>sv(|):text/psv:psv</li><li>sv([])</li><li>{apackage.FooOutputFormat}</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">output_default_limit</td>
 				<td></td>
 				<td>text</td>
@@ -381,7 +416,7 @@
 				</td>
 				<td><ul><li>0 <em>(default)</em></li><li>20</li><li>20r</li><li>20R</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">output_max_limit</td>
 				<td></td>
 				<td>text</td>
@@ -396,7 +431,7 @@
 			</tr>
 			
 			<tr><td colspan="5">Upload</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">upload_enabled</td>
 				<td></td>
 				<td>boolean</td>
@@ -407,7 +442,7 @@
 				</td>
 				<td><ul><li>false <em>(default)</em></li><li>true</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">upload_default_db_limit</td>
 				<td></td>
 				<td>text</td>
@@ -423,7 +458,7 @@
 				</td>
 				<td><ul><li>0 <em>(default)</em></li><li>20</li><li>20r</li><li>20R</li><li>200kB</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">upload_max_db_limit</td>
 				<td></td>
 				<td>text</td>
@@ -439,7 +474,7 @@
 				</td>
 				<td><ul><li>0 <em>(default)</em></li><li>10000</li><li>10000r</li><li>10000R</li><li>1MB</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">upload_max_file_size</td>
 				<td></td>
 				<td>text</td>
@@ -455,7 +490,7 @@
 			</tr>
 			
 			<tr><td colspan="5">User identification</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">user_identifier</td>
 				<td></td>
 				<td>text</td>
@@ -471,7 +506,7 @@
 			</tr>
 			
 			<tr><td colspan="5">ADQL restrictions</td></tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">geometries</td>
 				<td></td>
 				<td>text</td>
@@ -485,7 +520,7 @@
 				</td>
 				<td><ul><li>ΓΈ <em>(default)</em></li><li>NONE</li><li>CONTAINS, intersects, Point, Box, CIRCLE</li></ul></td>
 			</tr>
-			<tr>
+			<tr class="optional">
 				<td class="done">udfs</td>
 				<td></td>
 				<td>text</td>
@@ -508,5 +543,11 @@
 			</tr>
 			
 		</table>
+		<script type="text/javascript">
+			var nb = document.getElementsByClassName("mandatory").length;
+			document.getElementById("nbMandatory").textContent = nb;
+			nb += document.getElementsByClassName("optional").length;
+			document.getElementById("nbTotal").textContent = nb;
+		</script>
 	</body>
 </html>
\ No newline at end of file
diff --git a/src/tap/config/tap_full.properties b/src/tap/config/tap_full.properties
index affacdb556851e16a84e5d93224dbb899bdf094d..0d03a50a3ebc145473ffd40001a717488bc391ac 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: 12 Feb. 2015                                     #
+# Date: 17 Feb. 2015                                     #
 # Author: Gregory Mantelet (ARI)                         #
 #                                                        #
 ########################################################## 
@@ -12,8 +12,26 @@
 ###########
 
 # [OPTIONAL]
-# Path to the page which will be the index/home page of the TAP Service.
-service_home_page = 
+# This property lets set a custom home page.
+# 
+# 4 different kinds of value are accepted:
+#     * nothing (default): the default home page provided by the library (just a simple HTML page displaying a list of all available TAP resources).
+#     * name or relative path of a file: this method MUST be chosen if the new home page is a JSP file. This file MUST be inside the directory WebContent of your web application.
+#     * a URI starting with file://: in this method the local file pointed by the URI will be merely returned when the home page will be requested.
+#     * a URL: here, a redirection toward this URL will be made at each request on the home page
+#     * a classpath: the classpath of an extension of tap.resource.HomePage which must replace the default home page resource.
+#                    This class MUST have at least one constructor with exactly one parameter not NULL of type tap.resource.TAP.
+home_page = 
+
+# [OPTIONAL]
+# MIME type of the service home page.
+# 
+# This property is used only if the specified "home_page" is a local file path (i.e. if "home_page=file://...").
+# 
+# If no value is provided "text/html" will be set by default.
+# 
+# Default: text/html
+home_page_mime_type = 
 
 ############
 # PROVIDER #
diff --git a/src/tap/resource/TAP.java b/src/tap/resource/TAP.java
index b30fbb7071d50cd8ce0a780d6d5c91f6cf23f639..775f705659a5401bda357e357af13536f915b315 100644
--- a/src/tap/resource/TAP.java
+++ b/src/tap/resource/TAP.java
@@ -20,13 +20,7 @@ package tap.resource;
  *                       Astronomisches Rechen Institut (ARI)
  */
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -64,6 +58,32 @@ import adql.db.FunctionDef;
  */
 public class TAP implements VOSIResource {
 
+	/** <p>Name of the TAP AVAILABILITY resource.
+	 * This resource tells whether the TAP service is available (i.e. whether it accepts queries or not).</p>
+	 * <p><i>Note: this name is suffixing the root TAP URL in order to access one of its resources.</i></p>
+	 * @since 2.0 */
+	public final static String RESOURCE_AVAILABILITY = "availability";
+	/** <p>Name of the TAP CAPABILITIES resource.
+	 * This resource list all capabilities (e.g. output limits and formats, uploads, ...) of this TAP resource.</p>
+	 * <p><i>Note: this name is suffixing the root TAP URL in order to access one of its resources.</i></p>
+	 * @since 2.0 */
+	public final static String RESOURCE_CAPABILITIES = "capabilities";
+	/** <p>Name of the TAP HOME PAGE resource.
+	 * This resource lists and describes all published and query-able schemas, tables and columns.</p>
+	 * <p><i>Note: this name is suffixing the root TAP URL in order to access one of its resources.</i></p>
+	 * @since 2.0 */
+	public final static String RESOURCE_METADATA = "tables";
+	/** <p>Name of the TAP HOME PAGE resource.
+	 * This resource is used to submit ADQL queries to run asynchronously.</p>
+	 * <p><i>Note: this name is suffixing the root TAP URL in order to access one of its resources.</i></p>
+	 * @since 2.0 */
+	public final static String RESOURCE_ASYNC = "async";
+	/** <p>Name of the TAP HOME PAGE resource.
+	 * This resource is used to submit ADQL queries to run synchronously.</p>
+	 * <p><i>Note: this name is suffixing the root TAP URL in order to access one of its resources.</i></p>
+	 * @since 2.0 */
+	public final static String RESOURCE_SYNC = "sync";
+
 	/** Description of the TAP service owning this resource. */
 	protected final ServiceConnection service;
 
@@ -73,6 +93,17 @@ public class TAP implements VOSIResource {
 	/** Base URL of the TAP service. It is also the URL of this resource (HOME). */
 	protected String tapBaseURL = null;
 
+	/**
+	 * <p>HOME PAGE resource.
+	 * This resource lets write the home page.</p>
+	 * <p><i>Note:
+	 * 	at the URI {@link #homePageURI} or it is a very simple HTML page listing the link of all available
+	 * 	TAP resources.
+	 * </i></p>
+	 * @since 2.0
+	 */
+	protected HomePage homePage = null;
+
 	/** URI of the page or path of the file to display when this resource is requested. */
 	protected String homePageURI = null;
 
@@ -106,6 +137,10 @@ public class TAP implements VOSIResource {
 		if (errorWriter == null)
 			errorWriter = new DefaultTAPErrorWriter(service);
 
+		// Set the default home page:
+		homePage = new HomePage(this);
+
+		// Set all the standard TAP resources:
 		TAPResource res = new Availability(service);
 		resources.put(res.getName(), res);
 
@@ -206,13 +241,24 @@ public class TAP implements VOSIResource {
 	/* RESOURCES MANAGEMENT */
 	/* ******************** */
 
+	/**
+	 * Get the description of this service.
+	 * 
+	 * @return	Description/Configuration of this TAP service.
+	 * 
+	 * @since 2.0
+	 */
+	public final ServiceConnection getServiceConnection(){
+		return service;
+	}
+
 	/**
 	 * Get the /availability resource of this TAP service.
 	 * 
 	 * @return	The /availability resource.
 	 */
 	public final Availability getAvailability(){
-		return (Availability)resources.get(Availability.RESOURCE_NAME);
+		return (Availability)resources.get(RESOURCE_AVAILABILITY);
 	}
 
 	/**
@@ -221,7 +267,7 @@ public class TAP implements VOSIResource {
 	 * @return	The /capabilities resource.
 	 */
 	public final Capabilities getCapabilities(){
-		return (Capabilities)resources.get(Capabilities.RESOURCE_NAME);
+		return (Capabilities)resources.get(RESOURCE_CAPABILITIES);
 	}
 
 	/**
@@ -230,7 +276,7 @@ public class TAP implements VOSIResource {
 	 * @return	The /sync resource.
 	 */
 	public final Sync getSync(){
-		return (Sync)resources.get(Sync.RESOURCE_NAME);
+		return (Sync)resources.get(RESOURCE_SYNC);
 	}
 
 	/**
@@ -239,7 +285,7 @@ public class TAP implements VOSIResource {
 	 * @return	The /async resource.
 	 */
 	public final ASync getASync(){
-		return (ASync)resources.get(ASync.RESOURCE_NAME);
+		return (ASync)resources.get(RESOURCE_ASYNC);
 	}
 
 	/**
@@ -349,10 +395,22 @@ public class TAP implements VOSIResource {
 	 * 
 	 * @return	Iterator over the available TAP resources.
 	 */
-	public final Iterator<TAPResource> getTAPResources(){
+	public final Iterator<TAPResource> getResources(){
 		return resources.values().iterator();
 	}
 
+	/**
+	 * Let iterate over the full list of the TAP resources managed by this TAP service.
+	 * 
+	 * @return	Iterator over the available TAP resources.
+	 * @deprecated	The name of this function has been normalized. So now, you should use {@link #getResources()}
+	 *            	which is doing exactly the same thing.
+	 */
+	@Deprecated
+	public final Iterator<TAPResource> getTAPResources(){
+		return getResources();
+	}
+
 	/**
 	 * <p>Tell whether a resource is already associated with the given ID/URI.</p>
 	 * 
@@ -570,11 +628,46 @@ public class TAP implements VOSIResource {
 	/* MANAGEMENT OF THIS RESOURCE'S CONTENT */
 	/* ************************************* */
 
+	/**
+	 * Get the HOME PAGE resource of this TAP service.
+	 * 
+	 * @return	The HOME PAGE resource.
+	 * 
+	 * @since 2.0
+	 */
+	public final HomePage getHomePage(){
+		return homePage;
+	}
+
+	/**
+	 * <p>Change the whole behavior of the TAP home page.</p>
+	 * 
+	 * <p><i>Note:
+	 * 	If the given resource is NULL, the default home page (i.e. {@link HomePage}) is set.
+	 * </i></p>
+	 * 
+	 * @param newHomePageResource	The new HOME PAGE resource for this TAP service.
+	 * 
+	 * @since 2.0
+	 */
+	public final void setHomePage(final HomePage newHomePageResource){
+		if (newHomePageResource == null){
+			if (homePage == null || !(homePage instanceof HomePage))
+				homePage = new HomePage(this);
+		}else
+			homePage = newHomePageResource;
+	}
+
 	/**
 	 * <p>Get the URL or the file path of a custom home page.</p>
 	 * 
 	 * <p>The home page will be displayed when this resource is directly requested.</p>
 	 * 
+	 * <p><i>Note:
+	 * 	This function has a sense only if the HOME PAGE resource of this TAP service
+	 * 	is still the default home page (i.e. {@link HomePage}).
+	 * </i></p>
+	 * 
 	 * @return	URL or file path of the file to display as home page,
 	 *        	or NULL if no custom home page has been specified.
 	 */
@@ -587,6 +680,11 @@ public class TAP implements VOSIResource {
 	 * 
 	 * <p>The home page will be displayed when this resource is directly requested.</p>
 	 * 
+	 * <p><i>Note:
+	 * 	This function has a sense only if the HOME PAGE resource of this TAP service
+	 * 	is still the default home page (i.e. {@link HomePage}).
+	 * </i></p>
+	 * 
 	 * @param uri	URL or file path of the file to display as home page, or NULL to display the default home page.
 	 */
 	public final void setHomePageURI(final String uri){
@@ -598,9 +696,12 @@ public class TAP implements VOSIResource {
 	/**
 	 * <p>Get the MIME type of the custom home page.</p>
 	 * 
-	 * <p>
-	 * 	By default, it is the same as the default home page: "text/html".
-	 * </p>
+	 * <p>By default, it is the same as the default home page: "text/html".</p>
+	 * 
+	 * <p><i>Note:
+	 * 	This function has a sense only if the HOME PAGE resource of this TAP service
+	 * 	is still the default home page (i.e. {@link HomePage}).
+	 * </i></p>
 	 * 
 	 * @return	MIME type of the custom home page.
 	 */
@@ -613,6 +714,11 @@ public class TAP implements VOSIResource {
 	 * 
 	 * <p>A NULL value will be considered as "text/html".</p>
 	 * 
+	 * <p><i>Note:
+	 * 	This function has a sense only if the HOME PAGE resource of this TAP service
+	 * 	is still the default home page (i.e. {@link HomePage}).
+	 * </i></p>
+	 * 
 	 * @param mime	MIME type of the custom home page.
 	 */
 	public final void setHomePageMimeType(final String mime){
@@ -696,7 +802,7 @@ public class TAP implements VOSIResource {
 
 		// Retrieve the resource path parts:
 		String[] resourcePath = (request.getPathInfo() == null) ? null : request.getPathInfo().split("/");
-		final String resourceName = (resourcePath == null || resourcePath.length < 1) ? "homePage" : resourcePath[1].trim().toLowerCase();
+		String resourceName = (resourcePath == null || resourcePath.length < 1) ? "" : resourcePath[1].trim();
 
 		// Log the reception of the request, only if the asked resource is not UWS (because UWS is already logging the received request):
 		if (!resourceName.equalsIgnoreCase(ASync.RESOURCE_NAME))
@@ -707,7 +813,7 @@ public class TAP implements VOSIResource {
 			// initialize the base URL:
 			setTAPBaseURL(request);
 			// log the successful initialization:
-			getLogger().logUWS(LogLevel.INFO, this, "INIT", "TAP successfully initialized.", null);
+			getLogger().logUWS(LogLevel.INFO, this, "INIT", "TAP successfully initialized (" + tapBaseURL + ").", null);
 		}
 
 		JobOwner user = null;
@@ -719,9 +825,11 @@ public class TAP implements VOSIResource {
 				throw new TAPException(ue);
 			}
 
-			// Display the TAP Main Page:
-			if (resourceName.equals("homePage"))
-				writeHomePage(response, user);
+			// Display the TAP Home Page:
+			if (resourceName.length() == 0){
+				resourceName = homePage.getName();
+				homePage.executeResource(request, response);
+			}
 			// or Display/Execute the selected TAP Resource:
 			else{
 				// search for the corresponding resource:
@@ -762,60 +870,4 @@ public class TAP implements VOSIResource {
 		}
 	}
 
-	/**
-	 * <p>Write the content of the home page in the given writer.</p>
-	 * 
-	 * <p>This content can be:</p>
-	 * <ul>
-	 * 	<li><b>a distance document</b> if a URL has been provided to this class using {@link #setHomePageURI(String)}.
-	 * 	                               In this case, the content of the distant document is copied in the given writer.
-	 * 	                               No redirection is done.</li>
-	 * 	<li><b>a local file</b> if a file path has been provided to this class using {@link #setHomePageURI(String)}.
-	 * 	                        In this case, the content of the local file is copied in the given writer.</li>
-	 * 	<li><b>a default content</b> if no custom home page has been specified using {@link #setHomePageURI(String)}.
-	 * 	                             This default home page is hard-coded in this function and displays just an HTML list of
-	 * 	                             links. There is one link for each resources of this TAP service.</li>
-	 * </ul>
-	 * 
-	 * @param response	{@link HttpServletResponse} in which the home page must be written.
-	 * @param owner		The identified user who asked this home page.
-	 * 
-	 * @throws IOException	If any error occurs while writing the home page in the given HTTP response.
-	 */
-	public void writeHomePage(final HttpServletResponse response, final JobOwner owner) throws IOException{
-		PrintWriter writer = response.getWriter();
-
-		// By default, list all available resources:
-		if (homePageURI == null){
-			// Set the content type: HTML document
-			response.setContentType("text/html");
-
-			// Write the home page:
-			writer.println("<html><head><title>TAP HOME PAGE</title></head><body><h1 style=\"text-align: center\">TAP HOME PAGE</h1><h2>Available resources:</h2><ul>");
-			for(TAPResource res : resources.values())
-				writer.println("<li><a href=\"" + tapBaseURL + "/" + res.getName() + "\">" + res.getName() + "</a></li>");
-			writer.println("</ul></body></html>");
-		}
-		// or Display the specified home page:
-		else{
-			response.setContentType(homePageMimeType);
-
-			// Get an input toward the custom home page:
-			BufferedInputStream input = null;
-			try{
-				// CASE: URL => distant document
-				input = new BufferedInputStream((new URL(homePageURI)).openStream());
-			}catch(MalformedURLException mue){
-				// CASE: file path => local file
-				input = new BufferedInputStream(new FileInputStream(new File(homePageURI)));
-			}
-
-			// Copy the content of the input into the given writer:
-			byte[] buffer = new byte[255];
-			int nbReads = 0;
-			while((nbReads = input.read(buffer)) > 0)
-				writer.print(new String(buffer, 0, nbReads));
-		}
-	}
-
 }