diff --git a/src/tap/AbstractTAPFactory.java b/src/tap/AbstractTAPFactory.java
index 359b3cbde1ce780131d4e098f6299a4393388574..cc364a31b01345868c936a88eedbd50f6cf063d0 100644
--- a/src/tap/AbstractTAPFactory.java
+++ b/src/tap/AbstractTAPFactory.java
@@ -215,6 +215,7 @@ public abstract class AbstractTAPFactory extends TAPFactory {
 	public UWSService createUWS() throws TAPException{
 		try{
 			UWSService uws = new UWSService(this, this.service.getFileManager(), this.service.getLogger());
+			uws.setName("TAP/async");
 			uws.setErrorWriter(errorWriter);
 			return uws;
 		}catch(UWSException ue){
diff --git a/src/tap/ServiceConnection.java b/src/tap/ServiceConnection.java
index 444df9d8a6edf73a1b01bf2f7ad95c69de2c4614..37eddb236cb70bb548e67893afb4b8bebd28b264 100644
--- a/src/tap/ServiceConnection.java
+++ b/src/tap/ServiceConnection.java
@@ -91,7 +91,8 @@ public interface ServiceConnection {
 
 	/**
 	 * <i><b>[MANDATORY]</b></i>
-	 * <p>This function controls the state of the whole TAP service.</p>
+	 * <p>This function tells whether the TAP service is available
+	 * (that's to say, "able to execute requests" ; resources like /availability, /capabilities and /tables may still work).</p>
 	 * 
 	 * <p>
 	 * 	A message explaining the current state of the TAP service could be provided thanks to {@link #getAvailability()}.
@@ -111,6 +112,21 @@ public interface ServiceConnection {
 	 */
 	public String getAvailability();
 
+	/**
+	 * <i><b>[MANDATORY]</b></i>
+	 * <p>This function sets the state of the whole TAP service.
+	 * 	If true, all TAP resources will be able to execute resources.
+	 * 	If false, /sync and /async won't answer any more to requests and a HTTP-503 (Service unavailable)
+	 * 	error will be returned.
+	 * </p>
+	 * 
+	 * @param isAvailable	<i>true</i> to enable all resources, <i>false</i> to forbid /sync and /async (all other resources will still be available).
+	 * @param message		A message describing the current state of the service. If NULL, a default message may be set by the library.
+	 * 
+	 * @since 2.0
+	 */
+	public void setAvailable(final boolean isAvailable, final String message);
+
 	/**
 	 * <i>[OPTIONAL]</i>
 	 * <p>Get the limit of the retention period.</p>
diff --git a/src/tap/TAPFactory.java b/src/tap/TAPFactory.java
index 49d3421ec3b963411faacbfd5d2bfaf1b0fe09fd..580e232831db6aebb92c5bc738dd0b7dd749c435 100644
--- a/src/tap/TAPFactory.java
+++ b/src/tap/TAPFactory.java
@@ -61,7 +61,7 @@ import adql.query.ADQLQuery;
  * </ul>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 2.0 (11/2014)
+ * @version 2.0 (12/2014)
  */
 public abstract class TAPFactory implements UWSFactory {
 
@@ -90,7 +90,7 @@ public abstract class TAPFactory implements UWSFactory {
 	 * 
 	 * @return	The error writer to use.
 	 * 
-	 * @since 4.1
+	 * @since 2.0
 	 */
 	public abstract ServiceErrorWriter getErrorWriter();
 
@@ -125,6 +125,8 @@ public abstract class TAPFactory implements UWSFactory {
 	 * @return	A new and free connection to the database. <b>MUST BE NOT NULL, or otherwise a TAPException should be returned.</b>
 	 * 
 	 * @throws TAPException	If there is any error while getting a free connection.
+	 * 
+	 * @since 2.0
 	 */
 	public abstract DBConnection getConnection(final String jobID) throws TAPException;
 
@@ -142,6 +144,8 @@ public abstract class TAPFactory implements UWSFactory {
 	 * </i></p>
 	 * 
 	 * @param conn	The connection to close.
+	 * 
+	 * @since 2.0
 	 */
 	public abstract void freeConnection(final DBConnection conn);
 
@@ -163,9 +167,23 @@ public abstract class TAPFactory implements UWSFactory {
 	 * 
 	 * @return	The number of connections still available,
 	 *        	or <=0 in case of problem (<i>note: in this case, the error must be logged in the implementation of this function</i>).
+	 * 
+	 * @since 2.0
 	 */
 	public abstract int countFreeConnections();
 
+	/**
+	 * <p>Destroy all resources (and particularly DB connections and JDBC driver) allocated in this factory.</p>
+	 * 
+	 * <p><i>Note:
+	 * 	This function is called when the TAP service is shutting down.
+	 * 	After this call, the factory may not be able to provide any closed resources ; its behavior may be unpredictable.
+	 * </i></p>
+	 * 
+	 * @since 2.0
+	 */
+	public abstract void destroy();
+
 	/* *************** */
 	/* ADQL MANAGEMENT */
 	/* *************** */
diff --git a/src/tap/resource/ASync.java b/src/tap/resource/ASync.java
index fd0e7cdf5ae4d9ec43369f6104475dbb9349fe39..ccd94df703d6420efad34a6121f91e054fc40e92 100644
--- a/src/tap/resource/ASync.java
+++ b/src/tap/resource/ASync.java
@@ -175,7 +175,8 @@ public class ASync implements TAPResource {
 
 	@Override
 	public void destroy(){
-		;
+		if (uws != null)
+			uws.destroy();
 	}
 
 	@Override
diff --git a/src/tap/resource/TAP.java b/src/tap/resource/TAP.java
index 918f2116ce1e7582f693b0978814a2c23a4a2a8f..65ec8b0d06c3e52f8a3dc11f5cffc704e5affcbe 100644
--- a/src/tap/resource/TAP.java
+++ b/src/tap/resource/TAP.java
@@ -154,8 +154,18 @@ public class TAP implements VOSIResource {
 	 * @see TAPResource#destroy()
 	 */
 	public void destroy(){
+		// Set the availability to "false" and the reason to "The application server is stopping!":
+		service.setAvailable(false, "The application server is stopping!");
+
+		// Destroy all web resources:
 		for(TAPResource res : resources.values())
 			res.destroy();
+
+		// Destroy also all resources allocated in the factory:
+		service.getFactory().destroy();
+
+		// Log the end:
+		getLogger().logTAP(LogLevel.INFO, this, "STOP", "TAP Service stopped!", null);
 	}
 
 	/**
diff --git a/src/uws/job/manager/AbstractQueuedExecutionManager.java b/src/uws/job/manager/AbstractQueuedExecutionManager.java
index 49a1d0be3b1f67a92a0987f0dff3f3857f6a046d..3fa56c22afc45f4f6c1e792fa6a3a7d5e750e177 100644
--- a/src/uws/job/manager/AbstractQueuedExecutionManager.java
+++ b/src/uws/job/manager/AbstractQueuedExecutionManager.java
@@ -34,17 +34,25 @@ import uws.service.log.UWSLog.LogLevel;
 
 /**
  * <p>Abstract implementation of the interface {@link ExecutionManager} which lets managing an execution queue.</p>
+ * 
  * <p>
  * 	When calling {@link #execute(UWSJob)}, ALL jobs are put into the list of queued jobs (so their phase is changed
  * 	to {@link ExecutionPhase#QUEUED}). A call to {@link #refresh()}, reads this list and tries to execute the first job of the list.
  * 	The function {@link #isReadyForExecution(UWSJob)} decides whether the first job of the queue can be executed NOW or not.
  * </p>
+ * 
  * <p><i>Note:
  * 	The order of queued jobs is preserved: it is implemented by a FIFO queue.
  * </i></p>
  * 
+ * <p><i>Note:
+ *	After a call to {@link #stopAll()}, this manager is still able to execute new jobs.
+ *	Except if it was not possible to stop them properly, stopped jobs could be executed again by calling
+ *	afterwards {@link #execute(UWSJob)} with these jobs in parameter.
+ * </i></p>
+ * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (08/2014)
+ * @version 4.1 (12/2014)
  */
 public abstract class AbstractQueuedExecutionManager implements ExecutionManager {
 
@@ -237,4 +245,36 @@ public abstract class AbstractQueuedExecutionManager implements ExecutionManager
 			refresh();
 		}
 	}
+
+	@Override
+	public final synchronized void stopAll(){
+		// Set back all queued jobs to the PENDING phase:
+		for(UWSJob qj : queuedJobs){
+			try{
+				qj.setPhase(ExecutionPhase.PENDING, true);
+			}catch(UWSException ue){
+				if (logger != null)
+					logger.logJob(LogLevel.WARNING, qj, "ABORT", "Can not set back the job to the PENDING phase.", ue);
+			}
+		}
+
+		// Empty the queue:
+		queuedJobs.clear();
+
+		// Stop all running jobs and set them back to the PENDING phase:
+		for(UWSJob rj : runningJobs.values()){
+			try{
+				// Stop the job:
+				rj.abort();
+				// Set its phase back to PENDING:
+				rj.setPhase(ExecutionPhase.PENDING, true);
+			}catch(UWSException ue){
+				if (logger != null)
+					logger.logJob(LogLevel.WARNING, rj, "ABORT", "Can not stop the job nicely. The thread may continue to run until its end.", ue);
+			}
+		}
+
+		// Empty the list of running jobs:
+		runningJobs.clear();
+	}
 }
diff --git a/src/uws/job/manager/DefaultDestructionManager.java b/src/uws/job/manager/DefaultDestructionManager.java
index 24bff3e6e1ae765a08ef33f8f9a65b50e0056d34..8a0314c2129b75a7edafabd0d100c61f457b8544 100644
--- a/src/uws/job/manager/DefaultDestructionManager.java
+++ b/src/uws/job/manager/DefaultDestructionManager.java
@@ -16,11 +16,11 @@ package uws.job.manager;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  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),
+ *                       Astronomisches Rechen Institut (ARI)
  */
 
 import java.io.Serializable;
-
 import java.util.Comparator;
 import java.util.Date;
 import java.util.Timer;
@@ -34,19 +34,27 @@ import uws.job.UWSJob;
  * 	The default implementation of the {@link DestructionManager} interface.
  * 	Its goal is to manage the automatic destruction any given jobs.
  * </p>
+ * 
  * <p>
  *	Jobs can be added thanks to {@link #update(UWSJob)} and removed with {@link #remove(UWSJob)}.
  *	All added jobs are stored in a {@link TreeSet} which sorts them by ascending destruction time.
  *	The job which must be destroyed in first is used to start a timer.
  *	This one will destroyed the job once its destruction time is reached.
  * </p>
+ * 
  * <p>
  * 	The list of jobs to destroy is supposed to be updated each time the destruction time of a job is changed. This update works only if
  *  the job knows its jobs list ({@link UWSJob#getJobList()} != null) and its jobs list has a destruction manager.
  * </p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 05/2012
+ * <p><i>Note:
+ * 	The {@link #stop()} function lets stop this manager to watch for destructions of job until {@link #refresh()} or
+ * 	{@link #update(UWSJob)} or {@link #remove(UWSJob)} is called. When stopped, the inner timer is canceled and set
+ * 	to NULL ; no more thread resources is used.
+ * </i></p>
+ * 
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 4.1 (12/2014)
  */
 public class DefaultDestructionManager implements DestructionManager {
 	private static final long serialVersionUID = 1L;
@@ -83,7 +91,8 @@ public class DefaultDestructionManager implements DestructionManager {
 	/**
 	 * Stops the timer if running and set to <i>null</i> {@link #timDestruction}, {@link #currentDate} and {@link #currentJob}.
 	 */
-	protected synchronized final void stop(){
+	@Override
+	public synchronized final void stop(){
 		if (timDestruction != null)
 			timDestruction.cancel();
 		timDestruction = null;
@@ -111,18 +120,22 @@ public class DefaultDestructionManager implements DestructionManager {
 	/**
 	 * <p>Returns <i>true</i> if {@link #currentDate} is different from <i>null</i>.</p>
 	 */
+	@Override
 	public final boolean isRunning(){
 		return currentDate != null;
 	}
 
+	@Override
 	public final Date getNextDestruction(){
 		return currentDate;
 	}
 
+	@Override
 	public final String getNextJobToDestroy(){
 		return (currentJob == null) ? null : currentJob.getJobId();
 	}
 
+	@Override
 	public final int getNbJobsToDestroy(){
 		return jobsToDestroy.size() + (isRunning() ? 1 : 0);
 	}
@@ -147,6 +160,7 @@ public class DefaultDestructionManager implements DestructionManager {
 	 * @see #stop()
 	 * @see #destroyJob(UWSJob)
 	 */
+	@Override
 	public synchronized void refresh(){
 		// Finish the current timer if...
 		if (isRunning()){
@@ -196,6 +210,7 @@ public class DefaultDestructionManager implements DestructionManager {
 	 * @see #destroyJob(UWSJob)
 	 * @see #refresh()
 	 */
+	@Override
 	public synchronized void update(UWSJob job){
 		if (job != null && job.getJobList() != null && job.getDestructionTime() != null){
 			if (job.getDestructionTime().before(new Date()))
@@ -217,6 +232,7 @@ public class DefaultDestructionManager implements DestructionManager {
 	 * @see	#stop()
 	 * @see #refresh()
 	 */
+	@Override
 	public synchronized void remove(UWSJob job){
 		if (job == null)
 			return;
diff --git a/src/uws/job/manager/DefaultExecutionManager.java b/src/uws/job/manager/DefaultExecutionManager.java
index 333cbca0294adc0c4549dc754df0355c57d78091..7049aaf6a76690c24a2babd1db7c2905c79b6ff2 100644
--- a/src/uws/job/manager/DefaultExecutionManager.java
+++ b/src/uws/job/manager/DefaultExecutionManager.java
@@ -36,9 +36,15 @@ import uws.service.log.UWSLog.LogLevel;
  * 
  * <p>This manager does not have a queue. That is to say that all jobs are always immediately starting.
  * Consequently this manager is just used to gather all running jobs.</p>
+ * 
+ * <p><i>Note:
+ *	After a call to {@link #stopAll()}, this manager is still able to execute new jobs.
+ *	Except if it was not possible to stop them properly, stopped jobs could be executed again by calling
+ *	afterwards {@link #execute(UWSJob)} with these jobs in parameter.
+ * </i></p>
  *
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (08/2014)
+ * @version 4.1 (12/2014)
  */
 public class DefaultExecutionManager implements ExecutionManager {
 
@@ -147,4 +153,22 @@ public class DefaultExecutionManager implements ExecutionManager {
 		if (jobToRemove != null)
 			runningJobs.remove(jobToRemove.getJobId());
 	}
+
+	@Override
+	public synchronized void stopAll(){
+		// Stop all running jobs:
+		for(UWSJob rj : runningJobs.values()){
+			try{
+				// Stop the job:
+				rj.abort();
+				// Set its phase back to PENDING:
+				rj.setPhase(ExecutionPhase.PENDING, true);
+			}catch(UWSException ue){
+				if (logger != null)
+					logger.logJob(LogLevel.WARNING, rj, "ABORT", "Can not stop the job nicely. The thread may continue to run until its end.", ue);
+			}
+		}
+		// Empty the list of running jobs:
+		runningJobs.clear();
+	}
 }
diff --git a/src/uws/job/manager/DestructionManager.java b/src/uws/job/manager/DestructionManager.java
index 5bb89066a3b998da8e23cb787638b2ff97c61e77..022ecbc41717fe988a3c5ef7f53e1477b68cb97f 100644
--- a/src/uws/job/manager/DestructionManager.java
+++ b/src/uws/job/manager/DestructionManager.java
@@ -16,16 +16,15 @@ package uws.job.manager;
  * You should have received a copy of the GNU Lesser General Public License
  * along with UWSLibrary.  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),
+ *                       Astronomisches Rechen Institut (ARI)
  */
 
 import java.io.Serializable;
-
 import java.util.Date;
 
 import uws.job.JobList;
 import uws.job.UWSJob;
-
 import uws.service.UWS;
 
 /**
@@ -50,8 +49,8 @@ import uws.service.UWS;
  * 	</i>
  * </p>
  * 
- * @author Gr&eacute;gory Mantelet (CDS)
- * @version 05/2012
+ * @author Gr&eacute;gory Mantelet (CDS;ARI)
+ * @version 4.1 (12/2014)
  * 
  * @see DefaultDestructionManager
  */
@@ -114,4 +113,15 @@ public interface DestructionManager extends Serializable {
 	 * @param job	The job to remove.
 	 */
 	public void remove(UWSJob job);
+
+	/**
+	 * <p>Stop watching the destruction of jobs.</p>
+	 * 
+	 * <p><i>Note:
+	 * 	A subsequent call to {@link #update(UWSJob)} may enable again this manager.
+	 * </i></p>
+	 * 
+	 * @since 4.1
+	 */
+	public void stop();
 }
diff --git a/src/uws/job/manager/ExecutionManager.java b/src/uws/job/manager/ExecutionManager.java
index f95bd620161e1b87b77309406215bd033073245a..e50d86d9b0a23e771e17d7293bf5102ecf9c0e2e 100644
--- a/src/uws/job/manager/ExecutionManager.java
+++ b/src/uws/job/manager/ExecutionManager.java
@@ -36,7 +36,7 @@ import uws.job.UWSJob;
  * </p>
  * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
- * @version 4.1 (08/2014)
+ * @version 4.1 (12/2014)
  */
 public interface ExecutionManager {
 
@@ -102,4 +102,17 @@ public interface ExecutionManager {
 	 * @param jobToRemove		The job to remove.
 	 */
 	public void remove(final UWSJob jobToRemove);
+
+	/**
+	 * <p>Stop all running jobs. No more job, even the queued ones, must be executed after a call to this function.
+	 * All stopped or aborted queued jobs should be set forcedly back to the PENDING status.</p>
+	 * 
+	 * <p><i>Note:
+	 * 	A call to {@link #execute(UWSJob)} would re-activate this manager. However jobs stopped or
+	 * 	aborted using this function might not be starting again. These behaviors at implementation-dependent.
+	 * </i></p> 
+	 * 
+	 * @since 4.1
+	 */
+	public void stopAll();
 }
diff --git a/src/uws/service/UWS.java b/src/uws/service/UWS.java
index ebd0689add0a0a40e423e4c89c892d80039ae1f1..9c545b259a2ae171b5e984083483448d07a702ac 100644
--- a/src/uws/service/UWS.java
+++ b/src/uws/service/UWS.java
@@ -58,6 +58,11 @@ import uws.service.request.UWSRequestParser;
  * 	the UWS and the servlet.
  * </p>
  * 
+ * <p><b>IMPORTANT:
+ * 	All implementations of this interface should implement properly the function {@link #closeService()} and should call it
+ * 	when the JVM or the HTTP server application is closing.
+ * </b></p>
+ * 
  * @author Gr&eacute;gory Mantelet (CDS;ARI)
  * @version 4.1 (12/2014)
  */
@@ -85,6 +90,28 @@ public interface UWS extends Iterable<JobList> {
 	 */
 	public String getDescription();
 
+	/* ***************** */
+	/* RESOURCES RELEASE */
+	/* ***************** */
+
+	/**
+	 * <p>
+	 * 	End properly this UWS: jobs should be backuped (if this feature is enable), timers and threads should be stopped,
+	 * 	open files and database connections should be closed, etc...
+	 * 	In brief, this function should release all used resources.
+	 * </p>
+	 * 
+	 * <p><b>IMPORTANT: This function should be called only when the JVM or the Web Application Server is stopping.</b></p> 
+	 * 
+	 * <p><i>Note:
+	 * 	A call to this function may prevent this instance of {@link UWS} to execute any subsequent HTTP request, or the behavior
+	 * 	would be unpredictable.
+	 * </i></p>
+	 * 
+	 * @since 4.1
+	 */
+	public void destroy();
+
 	/* ******************* */
 	/* JOB LIST MANAGEMENT */
 	/* ******************* */
diff --git a/src/uws/service/UWSService.java b/src/uws/service/UWSService.java
index a2b1e74b174a964fd9608241e47619e17d93360c..9867ef694fc5ae1ec80ffcb7eb8ed9ecfcd09c1f 100644
--- a/src/uws/service/UWSService.java
+++ b/src/uws/service/UWSService.java
@@ -37,6 +37,7 @@ import uws.UWSException;
 import uws.UWSToolBox;
 import uws.job.ExecutionPhase;
 import uws.job.JobList;
+import uws.job.JobThread;
 import uws.job.UWSJob;
 import uws.job.manager.DefaultExecutionManager;
 import uws.job.serializer.JSONSerializer;
@@ -414,6 +415,35 @@ public class UWSService implements UWS {
 			logger.logUWS(LogLevel.INFO, this, "INIT", "UWS successfully initialized.", null);
 	}
 
+	@Override
+	public void destroy(){
+		// Backup all jobs:
+		/* Jobs are backuped now so that running jobs are set back to the PENDING phase in the backup.
+		 * Indeed, the "stopAll" operation of the ExecutionManager may fail and would set the phase to ERROR
+		 * for the wrong reason. */
+		if (backupManager != null){
+			// save all jobs:
+			backupManager.setEnabled(true);
+			backupManager.saveAll();
+			// stop the automatic backup, if there is one:
+			backupManager.setEnabled(false);
+		}
+
+		// Stop all jobs and stop watching for the jobs' destruction:
+		for(JobList jl : mapJobLists.values()){
+			jl.getExecutionManager().stopAll();
+			jl.getDestructionManager().stop();
+		}
+
+		// Just in case that previous clean "stop"s did not work, try again an interruption for all running threads:
+		/* note: timers are not part of this ThreadGroup and so, they won't be affected by this function call. */
+		JobThread.tg.interrupt();
+
+		// Log the service is stopped:
+		if (logger != null)
+			logger.logUWS(LogLevel.INFO, this, "STOP", "UWS Service \"" + getName() + "\" stopped!", null);
+	}
+
 	/* ************** */
 	/* LOG MANAGEMENT */
 	/* ************** */
diff --git a/src/uws/service/UWSServlet.java b/src/uws/service/UWSServlet.java
index da9b7f5b1ec1f371e4c34c9f11208db6024e84a8..e755f4e2633db2ba1482fce40e57caefa350f246 100644
--- a/src/uws/service/UWSServlet.java
+++ b/src/uws/service/UWSServlet.java
@@ -47,6 +47,7 @@ import uws.UWSExceptionFactory;
 import uws.UWSToolBox;
 import uws.job.ErrorSummary;
 import uws.job.JobList;
+import uws.job.JobThread;
 import uws.job.Result;
 import uws.job.UWSJob;
 import uws.job.parameters.DestructionTimeController;
@@ -240,6 +241,38 @@ public abstract class UWSServlet extends HttpServlet implements UWS, UWSFactory
 
 	public abstract void initUWS() throws UWSException;
 
+	@Override
+	public void destroy(){
+		// Backup all jobs:
+		/* Jobs are backuped now so that running jobs are set back to the PENDING phase in the backup.
+		 * Indeed, the "stopAll" operation of the ExecutionManager may fail and would set the phase to ERROR
+		 * for the wrong reason. */
+		if (backupManager != null){
+			// save all jobs:
+			backupManager.setEnabled(true);
+			backupManager.saveAll();
+			// stop the automatic backup, if there is one:
+			backupManager.setEnabled(false);
+		}
+
+		// Stop all jobs and stop watching for the jobs' destruction:
+		for(JobList jl : mapJobLists.values()){
+			jl.getExecutionManager().stopAll();
+			jl.getDestructionManager().stop();
+		}
+
+		// Just in case that previous clean "stop"s did not work, try again an interruption for all running threads:
+		/* note: timers are not part of this ThreadGroup and so, they won't be affected by this function call. */
+		JobThread.tg.interrupt();
+
+		// Log the service is stopped:
+		if (logger != null)
+			logger.logUWS(LogLevel.INFO, this, "STOP", "UWS Service \"" + getName() + "\" stopped!", null);
+
+		// Default destroy function:
+		super.destroy();
+	}
+
 	public UWSFileManager createFileManager() throws UWSException{
 		UWSFileManager fm = null;
 		String rootPath = getServletConfig().getInitParameter("rootDirectory");
diff --git a/src/uws/service/backup/DefaultUWSBackupManager.java b/src/uws/service/backup/DefaultUWSBackupManager.java
index 6b198bdc4cb4c1f3323178b9ea9fef8ceae1b679..3081bedc59c2db9ca170b4bbaad8e7c32a1b780f 100644
--- a/src/uws/service/backup/DefaultUWSBackupManager.java
+++ b/src/uws/service/backup/DefaultUWSBackupManager.java
@@ -401,7 +401,7 @@ public class DefaultUWSBackupManager implements UWSBackupManager {
 
 		// Build the report and log it:
 		int[] report = new int[]{nbSavedJobs,nbJobs,nbSavedOwners,nbOwners};
-		getLogger().logUWS(LogLevel.INFO, report, "BACKUPED", "UWS backuped! (" + nbSavedJobs + "/" + nbJobs + " jobs backuped ; " + nbSavedOwners + "/" + nbOwners + " users backuped)", null);
+		getLogger().logUWS(LogLevel.INFO, report, "BACKUPED", "UWS Service \"" + uws.getName() + "\" backuped!", null);
 
 		lastBackup = new Date();
 
@@ -465,7 +465,7 @@ public class DefaultUWSBackupManager implements UWSBackupManager {
 			out.endObject();
 
 			// Log the "save" report:
-			getLogger().logUWS(LogLevel.INFO, saveReport, "BACKUPED", "UWS backuped! (" + saveReport[0] + "/" + saveReport[1] + " users backuped)", null);
+			getLogger().logUWS(LogLevel.INFO, saveReport, "BACKUPED", "UWS backuped!", null);
 
 			lastBackup = new Date();
 
@@ -756,7 +756,7 @@ public class DefaultUWSBackupManager implements UWSBackupManager {
 
 		// Build the restoration report and log it:
 		int[] report = new int[]{nbRestoredJobs,nbJobs,nbRestoredUsers,nbUsers};
-		getLogger().logUWS(LogLevel.INFO, report, "RESTORED", "UWS restored! (" + nbRestoredJobs + "/" + nbJobs + " jobs restored ; " + nbRestoredUsers + "/" + nbUsers + " users restored)", null);
+		getLogger().logUWS(LogLevel.INFO, report, "RESTORED", "UWS restored!", null);
 
 		return report;
 	}
diff --git a/src/uws/service/log/DefaultUWSLog.java b/src/uws/service/log/DefaultUWSLog.java
index a1ef8b70f2dd977353a558655b3ec1fe795ed523..cfaadb47430a31511e131ec141376f6ff2593e17 100644
--- a/src/uws/service/log/DefaultUWSLog.java
+++ b/src/uws/service/log/DefaultUWSLog.java
@@ -390,6 +390,16 @@ public class DefaultUWSLog implements UWSLog {
 
 	@Override
 	public void logUWS(LogLevel level, Object obj, String event, String message, Throwable error){
+		// CASE "BACKUPED": Append to the message the backup report:
+		if (event != null && event.equalsIgnoreCase("BACKUPED") && obj != null && obj.getClass().getName().equals("[I")){
+			int[] backupReport = (int[])obj;
+			message += "\t(" + backupReport[0] + "/" + backupReport[1] + " jobs backuped ; " + backupReport[2] + "/" + backupReport[3] + " users backuped)";
+		}else if (event != null && event.equalsIgnoreCase("RESTORED") && obj != null && obj.getClass().getName().equals("[I")){
+			int[] restoreReport = (int[])obj;
+			message += "\t(" + restoreReport[0] + "/" + restoreReport[1] + " jobs restored ; " + restoreReport[2] + "/" + restoreReport[3] + " users restored)";
+		}
+
+		// Log the message
 		log(level, "UWS", event, null, message, error);
 	}
 
diff --git a/src/uws/service/log/UWSLog.java b/src/uws/service/log/UWSLog.java
index c0771f624d0613eb8dd0fac6bbdbbe49c024b7cd..94a901b23e506c363206f5676494036cea30089d 100644
--- a/src/uws/service/log/UWSLog.java
+++ b/src/uws/service/log/UWSLog.java
@@ -191,6 +191,7 @@ public interface UWSLog {
 	 * 	<li>RESTORED (with "obj" as an integer array of 4 items: nb of restored jobs, total nb of jobs, nb of restored users, total nb of users)</li>
 	 * 	<li>BACKUPED (with "obj" as an integer array of 4 items: nb of saved jobs, total nb of jobs, nb of saved users, total nb of users or with just 2 items (the two last ones))</li>
 	 * 	<li>FORMAT_ERROR (with a NULL "obj")</li>
+	 * 	<li>STOP (with "obj" as an instance of {@link UWS})</li>
 	 * </ul>
 	 * 
 	 * @param level		Level of the log (info, warning, error, ...). <i>SHOULD NOT be NULL, but if NULL anyway, the level SHOULD be considered as INFO</i>
diff --git a/test/tap/formatter/JSONFormatTest.java b/test/tap/formatter/JSONFormatTest.java
index fee9143f1473a5416cda1065c621f515a5228561..c7cb39361c02e63296eb7d583d3586183e68b7eb 100644
--- a/test/tap/formatter/JSONFormatTest.java
+++ b/test/tap/formatter/JSONFormatTest.java
@@ -264,6 +264,9 @@ public class JSONFormatTest {
 			return -1;
 		}
 
+		@Override
+		public void setAvailable(boolean isAvailable, String message){}
+
 	}
 
 }
diff --git a/test/tap/formatter/SVFormatTest.java b/test/tap/formatter/SVFormatTest.java
index d32b3dc09a662828e3b6c3a84c1035082a72c2e9..d523abfdb1c544a601b43229d4f3e34eef258e70 100644
--- a/test/tap/formatter/SVFormatTest.java
+++ b/test/tap/formatter/SVFormatTest.java
@@ -258,6 +258,9 @@ public class SVFormatTest {
 			return -1;
 		}
 
+		@Override
+		public void setAvailable(boolean isAvailable, String message){}
+
 	}
 
 }
diff --git a/test/tap/formatter/TextFormatTest.java b/test/tap/formatter/TextFormatTest.java
index 97145b23e947ea4b5c2e8fddb72fd5b0fec60cd2..d6632da5a0d245398c0cfb10723b6cdee943e4d3 100644
--- a/test/tap/formatter/TextFormatTest.java
+++ b/test/tap/formatter/TextFormatTest.java
@@ -258,6 +258,9 @@ public class TextFormatTest {
 			return -1;
 		}
 
+		@Override
+		public void setAvailable(boolean isAvailable, String message){}
+
 	}
 
 }
diff --git a/test/tap/formatter/VOTableFormatTest.java b/test/tap/formatter/VOTableFormatTest.java
index dca3751b977ae07ced1f388d74e97e9f24b03bdb..d55200a8820abcd614a482995d34788873500b7a 100644
--- a/test/tap/formatter/VOTableFormatTest.java
+++ b/test/tap/formatter/VOTableFormatTest.java
@@ -263,6 +263,9 @@ public class VOTableFormatTest {
 			return -1;
 		}
 
+		@Override
+		public void setAvailable(boolean isAvailable, String message){}
+
 	}
 
 }
diff --git a/test/tap/parameters/ServiceConnectionOfTest.java b/test/tap/parameters/ServiceConnectionOfTest.java
index 1d390ce84cf933eb737a3cb4966757a7eaf91d4d..cb0d79360556b13dadbd0ce576898ed608171e98 100644
--- a/test/tap/parameters/ServiceConnectionOfTest.java
+++ b/test/tap/parameters/ServiceConnectionOfTest.java
@@ -20,6 +20,8 @@ import adql.db.FunctionDef;
 
 public class ServiceConnectionOfTest implements ServiceConnection {
 
+	private boolean available = true;
+	private String availability = "TAP Service available!";
 	private int[] retentionPeriod = new int[]{-1,-1};
 	private int[] executionDuration = new int[]{(int)TAPJob.UNLIMITED_DURATION,(int)TAPJob.UNLIMITED_DURATION};
 	private int[] outputLimit = new int[]{TAPJob.UNLIMITED_MAX_REC,TAPJob.UNLIMITED_MAX_REC};
@@ -37,12 +39,21 @@ public class ServiceConnectionOfTest implements ServiceConnection {
 
 	@Override
 	public boolean isAvailable(){
-		return true;
+		return available;
+	}
+
+	@Override
+	public void setAvailable(boolean isAvailable, String message){
+		available = isAvailable;
+		if (message != null)
+			availability = message;
+		else
+			availability = (isAvailable ? "TAP Service available!" : "TAP Service momentarily UNavailable!");
 	}
 
 	@Override
 	public String getAvailability(){
-		return null;
+		return availability;
 	}
 
 	@Override