diff --git a/src/tap/ADQLExecutor.java b/src/tap/ADQLExecutor.java
index 7acfb281c2ab71dc842a9054746cc1d760bf4935..8ad271fded6862bd545759eb635f7b3f3d1ff2a0 100644
--- a/src/tap/ADQLExecutor.java
+++ b/src/tap/ADQLExecutor.java
@@ -445,7 +445,7 @@ public class ADQLExecutor {
 
 		// Upload them, if needed:
 		if (tables.length > 0){
-			logger.logTAP(LogLevel.INFO, report, "UPLOAD", "Loading uploaded tables (" + tables.length + ")...", null);
+			logger.logTAP(LogLevel.INFO, report, "UPLOADING", "Loading uploaded tables (" + tables.length + ")", null);
 			try{
 				uploadSchema = service.getFactory().createUploader(dbConn).upload(tables);
 			}finally{
@@ -478,6 +478,9 @@ public class ADQLExecutor {
 	 * @throws TAPException				If the TAP factory is unable to create the ADQL factory or the query checker.
 	 */
 	protected ADQLQuery parseADQL() throws ParseException, InterruptedException, TAPException{
+		// 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();
 
@@ -526,7 +529,13 @@ public class ADQLExecutor {
 	 * @see {@link DBConnection#executeQuery(ADQLQuery)}
 	 */
 	protected TableIterator executeADQL(final ADQLQuery adql) throws InterruptedException, TAPException{
+		// Log the start of execution:
+		logger.logTAP(LogLevel.INFO, report, "EXECUTING", "Executing ADQL: " + adql.toString().replaceAll("(\t|\r?\n)+", " "), null);
+
+		// Execute the ADQL query:
 		TableIterator result = dbConn.executeQuery(adql);
+
+		// Log the success or failure:
 		if (result == null)
 			logger.logTAP(LogLevel.INFO, report, "END_QUERY", "Query execution aborted after " + (System.currentTimeMillis() - startStep) + "ms!", null);
 		else
@@ -552,6 +561,9 @@ public class ADQLExecutor {
 	 * @see #writeResult(TableIterator, OutputFormat, OutputStream)
 	 */
 	protected final void writeResult(final TableIterator queryResult) throws InterruptedException, TAPException, UWSException{
+		// Log the start of the writing:
+		logger.logTAP(LogLevel.INFO, report, "WRITING_RESULT", "Writing the query result", null);
+
 		// Get the appropriate result formatter:
 		OutputFormat formatter = getFormatter();
 
diff --git a/src/tap/TAPSyncJob.java b/src/tap/TAPSyncJob.java
index 016b0da4f3803b52c4ee551bf3e349a060cdf07d..92b2a08b2cef6487efe1f3b8854c065cd8379f0f 100644
--- a/src/tap/TAPSyncJob.java
+++ b/src/tap/TAPSyncJob.java
@@ -229,16 +229,19 @@ public class TAPSyncJob {
 			// TAP EXCEPTION:
 			else if (error instanceof TAPException){
 				// log the error:
-				service.getLogger().logTAP(LogLevel.ERROR, this, "SYNC_END", "An error occured while executing the query of the synchronous job " + ID + ": " + error.getMessage(), error);
+				service.getLogger().logTAP(LogLevel.ERROR, this, "SYNC_END", "An error occured while executing the query of the synchronous job " + ID + ".", error);
 				// report the error to the user:
 				throw (TAPException)error;
 			}
 			// ANY OTHER EXCEPTION:
 			else{
 				// log the error:
-				service.getLogger().logTAP(LogLevel.FATAL, this, "SYNC_END", "An unexpected error has stopped the execution of the synchronous job " + ID + ": " + error.getMessage(), error);
+				service.getLogger().logTAP(LogLevel.FATAL, this, "SYNC_END", "An unexpected error has stopped the execution of the synchronous job " + ID + ".", error);
 				// report the error to the user:
-				throw new TAPException(error);
+				if (error instanceof Error)
+					throw (Error)error;
+				else
+					throw new TAPException(error);
 			}
 		}else
 			service.getLogger().logTAP(LogLevel.INFO, this, "SYNC_END", "The synchronous job " + ID + " successfully ended.", null);
@@ -340,10 +343,13 @@ public class TAPSyncJob {
 				// Log the end of the job:
 				if (e instanceof InterruptedException)
 					// Abortion:
-					executor.getLogger().logThread(LogLevel.INFO, this, "END", "Synchronous thread \"" + getId() + "\" cancelled.", null);
+					executor.getLogger().logThread(LogLevel.INFO, this, "END", "Synchronous thread \"" + ID + "\" cancelled.", null);
+				else if (e instanceof Error)
+					// GRAVE error:
+					executor.getLogger().logThread(LogLevel.FATAL, this, "END", "Synchronous thread \"" + ID + "\" ended with a FATAL error.", exception);
 				else
 					// Error:
-					executor.getLogger().logThread(LogLevel.ERROR, this, "END", "Synchronous thread \"" + getId() + "\" ended with an error.", exception);
+					executor.getLogger().logThread(LogLevel.ERROR, this, "END", "Synchronous thread \"" + ID + "\" ended with an error.", exception);
 			}
 		}
 
diff --git a/src/tap/db/JDBCConnection.java b/src/tap/db/JDBCConnection.java
index f3393e37bf0082954d5ee2205cb57bee2871cf26..72e87d429e54595e0a346036009ee85c221e2343 100644
--- a/src/tap/db/JDBCConnection.java
+++ b/src/tap/db/JDBCConnection.java
@@ -1481,9 +1481,10 @@ public class JDBCConnection implements DBConnection {
 			DatabaseMetaData dbMeta = connection.getMetaData();
 
 			// 1. Create the upload schema, if it does not already exist:
-			if (!isSchemaExisting(tableDef.getDBSchemaName(), dbMeta))
+			if (!isSchemaExisting(tableDef.getDBSchemaName(), dbMeta)){
 				stmt.executeUpdate("CREATE SCHEMA " + translator.getQualifiedSchemaName(tableDef) + ";");
-
+				logger.logDB(LogLevel.INFO, this, "SCHEMA_CREATED", "Schema \"" + tableDef.getADQLSchemaName() + "\" (in DB: " + translator.getQualifiedSchemaName(tableDef) + ") created.", null);
+			}
 			// 1bis. Ensure the table does not already exist and if it is the case, throw an understandable exception:
 			else if (isTableExisting(tableDef.getDBSchemaName(), tableDef.getDBName(), dbMeta)){
 				DBException de = new DBException("Impossible to create the user uploaded table in the database: " + translator.getQualifiedTableName(tableDef) + "! This table already exists.");
@@ -1516,6 +1517,9 @@ public class JDBCConnection implements DBConnection {
 			// Commit the transaction:
 			commit();
 
+			// Log the end:
+			logger.logDB(LogLevel.INFO, this, "TABLE_CREATED", "Table \"" + tableDef.getADQLName() + "\" (in DB: " + translator.getQualifiedTableName(tableDef) + ") created.", null);
+
 			return true;
 
 		}catch(SQLException se){
@@ -1633,6 +1637,12 @@ public class JDBCConnection implements DBConnection {
 			stmt = connection.createStatement();
 			int cnt = stmt.executeUpdate("DROP TABLE " + translator.getQualifiedTableName(tableDef) + ";");
 
+			// Log the end:
+			if (cnt == 0)
+				logger.logDB(LogLevel.INFO, this, "TABLE_DROPPED", "Table \"" + tableDef.getADQLName() + "\" (in DB: " + translator.getQualifiedTableName(tableDef) + ") dropped.", null);
+			else
+				logger.logDB(LogLevel.ERROR, this, "TABLE_DROPPED", "Table \"" + tableDef.getADQLName() + "\" (in DB: " + translator.getQualifiedTableName(tableDef) + ") NOT dropped.", null);
+
 			// Ensure the update is successful:
 			return (cnt == 0);
 
diff --git a/src/tap/error/DefaultTAPErrorWriter.java b/src/tap/error/DefaultTAPErrorWriter.java
index e6e725663efb27cae05b0536f943f76df19efc95..064d778d69161b586a1fe90519a731538b7d504c 100644
--- a/src/tap/error/DefaultTAPErrorWriter.java
+++ b/src/tap/error/DefaultTAPErrorWriter.java
@@ -36,7 +36,6 @@ import uws.job.ErrorType;
 import uws.job.user.JobOwner;
 import uws.service.error.DefaultUWSErrorWriter;
 import uws.service.error.ServiceErrorWriter;
-import uws.service.log.UWSLog.LogLevel;
 
 /**
  * <p>Default implementation of {@link ServiceErrorWriter} for a TAP service.</p>
@@ -109,12 +108,9 @@ public class DefaultTAPErrorWriter implements ServiceErrorWriter {
 			writeError(t.getMessage(), type, httpErrorCode, response, request, reqID, user, action);
 		}
 		// Otherwise, log it and write a message to the user:
-		else{
-			// log the error as GRAVE/FATAL (because unexpected/unmanaged):
-			logger.logTAP(LogLevel.FATAL, null, null, "[REQUEST N°" + reqID + "] " + t.getMessage(), t);
+		else
 			// write a message to the user:
-			writeError("INTERNAL SERVER ERROR! Sorry, this error is unexpected and no explaination can be provided for the moment. Details about this error have been reported in the service log files ; you should try again your request later or notify the administrator(s) by yourself (with the following REQ_ID).", ErrorType.FATAL, UWSException.INTERNAL_SERVER_ERROR, response, request, reqID, user, action);
-		}
+			writeError("INTERNAL SERVER ERROR! Sorry, this error is grave and unexpected. No explaination can be provided for the moment. Details about this error have been reported in the service log files ; you should try again your request later or notify the administrator(s) by yourself (with the following REQ_ID).", ErrorType.FATAL, UWSException.INTERNAL_SERVER_ERROR, response, request, reqID, user, action);
 	}
 
 	@Override
diff --git a/src/tap/log/TAPLog.java b/src/tap/log/TAPLog.java
index 40a9c715a84ab544a5a849802528ced6aaf57680..2e9118f783bbb2ac933aeef0ec162d7529af62df 100644
--- a/src/tap/log/TAPLog.java
+++ b/src/tap/log/TAPLog.java
@@ -79,7 +79,10 @@ public interface TAPLog extends UWSLog {
 	 * 	<li>SYNC_INIT (with "obj" as an instance of {@link TAPParameters})</li>
 	 * 	<li>ASYNC_INIT (with a NULL "obj")</li>
 	 * 	<li>SYNC_START (with "obj" as an instance of {@link TAPSyncJob})</li>
-	 * 	<li>UPLOAD (with "obj" as an instance of {@link TAPExecutionReport})</li>
+	 * 	<li>UPLOADING (with "obj" as an instance of {@link TAPExecutionReport})</li>
+	 * 	<li>PARSING (with "obj" as an instance of {@link TAPExecutionReport})</li>
+	 * 	<li>EXECUTING (with "obj" as an instance of {@link TAPExecutionReport})</li>
+	 * 	<li>WRITING_RESULT (with "obj" as an instance of {@link TAPExecutionReport})</li>
 	 * 	<li>FORMAT (with "obj" as an instance of {@link TAPExecutionReport})</li>
 	 * 	<li>START_STEP (with "obj" as an instance of {@link TAPExecutionReport})</li>
 	 * 	<li>END_EXEC (with "obj" as an instance of {@link TAPExecutionReport})</li>
diff --git a/src/tap/resource/Sync.java b/src/tap/resource/Sync.java
index 460b0095caba1dd1e574dc4350beba7079fcc047..b83fc0714b13bf38ad7771ae88254adaa50c1a89 100644
--- a/src/tap/resource/Sync.java
+++ b/src/tap/resource/Sync.java
@@ -115,7 +115,7 @@ public class Sync implements TAPResource {
 				return true;
 			}catch(TAPException te){
 				throw te;
-			}catch(Throwable t){
+			}catch(Exception t){
 				service.getLogger().logTAP(LogLevel.FATAL, params, "SYNC_INIT", "Unexpected error while executing the given ADQL query!", t);
 				throw new TAPException("Unexpected error while executing the given ADQL query!");
 			}
diff --git a/src/uws/job/JobThread.java b/src/uws/job/JobThread.java
index 1e979dbd481eb5a3738f7c51f99644975aad2046..8f8a4af20a33b0c7038396f8bdec134ccfb6c423 100644
--- a/src/uws/job/JobThread.java
+++ b/src/uws/job/JobThread.java
@@ -391,7 +391,9 @@ public abstract class JobThread extends Thread {
 
 		}catch(Throwable t){
 			// Build the error:
-			if (t.getMessage() == null || t.getMessage().trim().isEmpty())
+			if (t instanceof Error)
+				lastError = new UWSException(UWSException.INTERNAL_SERVER_ERROR, t, "A FATAL DEEP ERROR OCCURED WHILE EXECUTING THIS QUERY! This error is reported in the service logs.", ErrorType.FATAL);
+			else if (t.getMessage() == null || t.getMessage().trim().isEmpty())
 				lastError = new UWSException(UWSException.INTERNAL_SERVER_ERROR, t.getClass().getName(), ErrorType.FATAL);
 			else
 				lastError = new UWSException(UWSException.INTERNAL_SERVER_ERROR, t, ErrorType.FATAL);
@@ -402,18 +404,19 @@ public abstract class JobThread extends Thread {
 			// Publish the error if any has occurred:
 			if (lastError != null){
 				// Log the error:
-				logger.logThread(LogLevel.ERROR, this, "END", "Thread \"" + getId() + "\" ended with an error.", lastError);
+				LogLevel logLevel = (lastError.getCause() != null && lastError.getCause() instanceof Error) ? LogLevel.FATAL : LogLevel.ERROR;
+				logger.logThread(logLevel, this, "END", "Thread \"" + getId() + "\" ended with an error.", lastError);
 				// Set the error into the job:
 				try{
 					setError(lastError);
 				}catch(UWSException ue){
 					try{
-						logger.logThread(LogLevel.ERROR, this, "SET_ERROR", "[1st Attempt] Problem in JobThread.setError(UWSException), while setting the execution error of the job " + job.getJobId() + ". A last attempt will be done.", ue);
+						logger.logThread(logLevel, this, "SET_ERROR", "[1st Attempt] Problem in JobThread.setError(UWSException), while setting the execution error of the job " + job.getJobId() + ". A last attempt will be done.", ue);
 						setError(new ErrorSummary((lastError.getCause() != null) ? lastError.getCause().getMessage() : lastError.getMessage(), lastError.getUWSErrorType()));
 					}catch(UWSException ue2){
-						logger.logThread(LogLevel.ERROR, this, "SET_ERROR", "[2nd and last Attempt] Problem in JobThread.setError(ErrorSummary), while setting the execution error of the job " + job.getJobId() + ". This error can not be reported to the user, but it will be reported in the log in the JOB context.", ue2);
+						logger.logThread(logLevel, this, "SET_ERROR", "[2nd and last Attempt] Problem in JobThread.setError(ErrorSummary), while setting the execution error of the job " + job.getJobId() + ". This error can not be reported to the user, but it will be reported in the log in the JOB context.", ue2);
 						// Note: no need of a level 3: if the second attempt fails, it means the job is in a wrong phase and no error summary can never be set ; further attempt won't change anything!
-						logger.logJob(LogLevel.ERROR, job, "EXECUTING", "An error has interrupted the execution of the job \"" + job.getJobId() + "\". Here is its summary: " + lastError.getMessage(), lastError);
+						logger.logJob(logLevel, job, "EXECUTING", "An error has interrupted the execution of the job \"" + job.getJobId() + "\". Here is its summary: " + lastError.getMessage(), lastError);
 					}
 				}
 			}else