diff --git a/src/eu/simstadt/nf4j/Connector.java b/src/eu/simstadt/nf4j/Connector.java
index 826ee289dfef2fc90e7b83ad60e3a8b7ddc4d085..169e8f4ffc6f5fe0c6bc8521a06cea4cd2ff940f 100644
--- a/src/eu/simstadt/nf4j/Connector.java
+++ b/src/eu/simstadt/nf4j/Connector.java
@@ -48,7 +48,7 @@ public void sendAndUpdateExportJob(E exportJob)
 	 *     <Product>_<Tile>.start
 	 *     
 	 * The start file should contain the level to which your manipulated CityGML should be imported. Your CityGML
-	 * file has to be named after the following naming convention:
+	 * file and the ZIP archive to be sent has to be named after the following naming convention:
 	 * 
 	 *     <Product>_<Tile>_<Level>_<Operation>.gml
 	 *    
diff --git a/src/eu/simstadt/nf4j/Job.java b/src/eu/simstadt/nf4j/Job.java
index ec9b53f9b013bc34c46815a8c28ab90a96bfcf4b..7938914f71e92fda2cf75b9c2643edbcbb51fce5 100644
--- a/src/eu/simstadt/nf4j/Job.java
+++ b/src/eu/simstadt/nf4j/Job.java
@@ -17,7 +17,8 @@ public abstract class Job {
 	protected Connector<?, ?> connector;
 	
 	/**
-	 * Every job has it's status. Look up the different possible values in the JobStatus enumeration.
+	 * Every job has a status. This method returns it. Look up the different possible values in the JobStatus
+	 * enumeration.
 	 * 
 	 * @return Returns the status of this job.
 	 */
diff --git a/src/eu/simstadt/nf4j/async/AsyncExportJob.java b/src/eu/simstadt/nf4j/async/AsyncExportJob.java
index 69d3a965b3d80c31852af98433a697ca82140734..63938096a508bbfc6fef9d7e5b37529c0abe7aa4 100644
--- a/src/eu/simstadt/nf4j/async/AsyncExportJob.java
+++ b/src/eu/simstadt/nf4j/async/AsyncExportJob.java
@@ -114,8 +114,8 @@ public synchronized void send() throws FailedTransmissionException, InvalidJobDe
 	}
 	
 	/**
-	 * Frequently queries the remote status of the nF export job and updates the local status accordingly.
-	 * The queries will be performed asynchronously in a separate thread. Job status listener will be notified
+	 * Frequently queries the status of the remote nF export job and updates the local status accordingly.
+	 * The queries will be performed asynchronously in a separate thread. Job status listeners will be notified
 	 * upon every new status change.
 	 * 
 	 * Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
@@ -142,6 +142,16 @@ public synchronized void poll(int interval) throws FailedTransmissionException {
 	/**
 	 * Convenience method for polling with a predefined default interval.
 	 * 
+	 * Frequently queries the status of the remote nF export job and updates the local status accordingly.
+	 * The queries will be performed asynchronously in a separate thread. Job status listeners will be notified
+	 * upon every new status change.
+	 * 
+	 * Note, there can only be one polling thread at a time. Subsequent calls of poll() will stop the previously
+	 * started poll threads.
+	 * 
+	 * @param interval Amount of seconds to wait before the next status update request will be sent to the
+	 * nF server.
+	 * @throws FailedTransmissionException If your job has not been sent yet, then you will get some of this. 
 	 * @see poll(int)
 	 */
 	public synchronized void poll() throws FailedTransmissionException {
diff --git a/src/eu/simstadt/nf4j/async/AsyncImportJob.java b/src/eu/simstadt/nf4j/async/AsyncImportJob.java
index f19d71c126713d331d730d76c41833bfeb122896..c7e7c6205efa6024ccbf8cec4fad5558441483e3 100644
--- a/src/eu/simstadt/nf4j/async/AsyncImportJob.java
+++ b/src/eu/simstadt/nf4j/async/AsyncImportJob.java
@@ -90,7 +90,7 @@ public synchronized void send() throws InvalidJobDescriptorException, FailedTran
 	}
 	
 	/**
-	 * Frequently queries the remote status of the nF export job and updates the local status accordingly.
+	 * Frequently queries the status of the remote nF export job and updates the local status accordingly.
 	 * The queries will be performed asynchronously in a separate thread. Job status listener will be notified
 	 * upon every new status change.
 	 *  
diff --git a/src/eu/simstadt/nf4j/async/AsyncJob.java b/src/eu/simstadt/nf4j/async/AsyncJob.java
index 25a4fa173b037eb01befc1d3c70c2d045535cd43..03e7e8a0a2d4661ae9cbc10d82cd82cea810f4cd 100644
--- a/src/eu/simstadt/nf4j/async/AsyncJob.java
+++ b/src/eu/simstadt/nf4j/async/AsyncJob.java
@@ -13,7 +13,7 @@
 public interface AsyncJob {
 
 	/**
-	 * Frequently queries the remote status of the nF export job and updates the local status accordingly.
+	 * Frequently queries the status of the remote nF export job and updates the local status accordingly.
 	 * The queries will be performed asynchronously in a separate thread. Job status listener will be notified
 	 * upon every new status change.
 	 * 
diff --git a/src/eu/simstadt/nf4j/async/HTTPConnection.java b/src/eu/simstadt/nf4j/async/HTTPConnection.java
index 888bde0f704580325f0e63d07f80dd27b4d863de..6349899954d6ee03fb6932c56ad4abb2b60e1f1a 100644
--- a/src/eu/simstadt/nf4j/async/HTTPConnection.java
+++ b/src/eu/simstadt/nf4j/async/HTTPConnection.java
@@ -100,7 +100,7 @@ public class HTTPConnection implements Connector<AsyncImportJob, AsyncExportJob>
 	private String context;
 	
 	/**
-	 * Constructs your NFConnector instance.
+	 * Constructs your Connector instance.
 	 * 
 	 * @param server The host name of the nF server with which you want to establish a data connection.
 	 */
@@ -109,7 +109,7 @@ public HTTPConnection(String server) {
 	}
 	
 	/**
-	 * Constructs your NFConnector instance.
+	 * Constructs your Connector instance.
 	 * 
 	 * @param server The host name of the nF server with which you want to establish a data connection.
 	 * @param port The port of the nF web application.
@@ -298,8 +298,9 @@ private String getResponse(HttpURLConnection httpConnection) throws UnsupportedE
 	
 	/**
 	 * If everything works as expected, then nF's servlets will respond with XML reports to your requests. The job
-	 * status will be extracted from the response string. The XML reports have a certain structure. Read the nF
-	 * manual for more information about the XML reports and have a look at the DTD of the XML reports.
+	 * id and status will be extracted from the response string. The id of the passed job instance will be updated.
+	 * The XML reports have a certain structure. Read the nF manual for more information about the XML reports and
+	 * have a look at the DTD of the XML reports.
 	 * 
 	 * @param xml A XML string that is supposed to be a XML document.
 	 * @param An empty job status object about to be filled with the actual result. It will be UNKOWN if there was
@@ -421,7 +422,7 @@ public void sendAndUpdateExportJob(AsyncExportJob job)
 	 *     <Product>_<Tile>.start
 	 * 
 	 * The start file should contain the level to which your manipulated CityGML should be imported. Your CityGML
-	 * file has to be named after the following naming convention:
+	 * file and the ZIP archive has to be named after the following naming convention:
 	 * 
 	 *     <Product>_<Tile>_<Level>_<Operation>.gml
 	 *    
@@ -466,6 +467,11 @@ public void sendAndUpdateImportJob(AsyncImportJob job)
 			os.flush();
 			writer.append(CRLF).flush();
 			getJobFromResponse(job, getResponse(connection));
+			if (job.getId() > 0) {
+				job.setStatus(JobStatus.SENT, Optional.empty());
+			} else {
+				throw new FailedTransmissionException("Job didn't receive an id from the nF server.");
+			}
 		} catch (MalformedURLException ex) {
 			job.getStatus().setMessage(MALFORMED_URL);
 			throw new FailedTransmissionException(ex.getMessage());
diff --git a/src/eu/simstadt/nf4j/async/SendExportJobTask.java b/src/eu/simstadt/nf4j/async/SendExportJobTask.java
index e46a1691381c6b64484d5a395ff1b9d1cc0ba0ff..b7495dc413869277da4a351474190673a27f08f4 100644
--- a/src/eu/simstadt/nf4j/async/SendExportJobTask.java
+++ b/src/eu/simstadt/nf4j/async/SendExportJobTask.java
@@ -36,7 +36,6 @@ public void run() {
 		try {
 			HTTPConnection connector = (HTTPConnection) job.getConnector();
 			connector.sendAndUpdateExportJob(job);
-			job.setStatus(JobStatus.SENT, Optional.empty());
 			job.poll();
 		} catch (InvalidJobDescriptorException ex) {
 			signalError("Job cancel because of an invalid job description!");
@@ -46,10 +45,10 @@ public void run() {
 	}
 	
 	/**
-	 * This method is superfluous I guess? Please refactor it.
+	 * This method is superfluous I guess? TODO: Please check and refactor it.
 	 */
 	private void signalError(String errorMessage) {
 		job.setStatus(JobStatus.UNKOWN, Optional.of(errorMessage));
 	}
 
-}
+}
\ No newline at end of file
diff --git a/src/eu/simstadt/nf4j/async/SendImportJobTask.java b/src/eu/simstadt/nf4j/async/SendImportJobTask.java
index b9eeef51557f2ea373c81b266931a309da25297e..07b3073055aa3674b06b46ab04cea4b4bfdfb48f 100644
--- a/src/eu/simstadt/nf4j/async/SendImportJobTask.java
+++ b/src/eu/simstadt/nf4j/async/SendImportJobTask.java
@@ -36,7 +36,6 @@ public void run() {
 		try {
 			HTTPConnection connector = (HTTPConnection) job.getConnector();
 			connector.sendAndUpdateImportJob(job);
-			job.setStatus(JobStatus.SENT, Optional.empty());
 			job.poll();
 		} catch (InvalidJobDescriptorException ex) {
 			signalError("Job cancel because of an invalid job description!");
@@ -45,8 +44,11 @@ public void run() {
 		}
 	}
 	
+	/**
+	 * This method is superfluous I guess? TODO: Please check and refactor it.
+	 */
 	private void signalError(String errorMessage) {
 		job.setStatus(JobStatus.UNKOWN, Optional.of(errorMessage));
 	}
 
-}
+}
\ No newline at end of file
diff --git a/src/eu/simstadt/nf4j/async/Client.java b/test/eu/simstadt/nf4j/async/test/SuccessfulExportJob.java
similarity index 50%
rename from src/eu/simstadt/nf4j/async/Client.java
rename to test/eu/simstadt/nf4j/async/test/SuccessfulExportJob.java
index d90bf9505a9e76d982a94faf17e1bccd35bad48c..fd8a752750d9e22af8436132dd84c36853645817 100644
--- a/src/eu/simstadt/nf4j/async/Client.java
+++ b/test/eu/simstadt/nf4j/async/test/SuccessfulExportJob.java
@@ -1,82 +1,94 @@
-package eu.simstadt.nf4j.async;
+package eu.simstadt.nf4j.async.test;
 
 import java.io.File;
 
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
 import eu.simstadt.nf4j.FailedTransmissionException;
 import eu.simstadt.nf4j.InvalidJobDescriptorException;
 import eu.simstadt.nf4j.JobStatus;
+import eu.simstadt.nf4j.async.AsyncExportJob;
+import eu.simstadt.nf4j.async.ExportJobDescription;
+import eu.simstadt.nf4j.async.HTTPConnection;
+import eu.simstadt.nf4j.async.JobStatusEvent;
+import eu.simstadt.nf4j.async.JobStatusListener;
+import eu.simstadt.nf4j.async.Layer;
+import eu.simstadt.nf4j.async.Unit;
 
 /**
- * This is a class for development and test purposes. It is not needed for production. You may want to delete it.
- *  
+ * This class contains client oriented export job tests. It will send an export job and listens to
+ * status updates. Every of the subsequent status' LOCAL, SENT, PENDING, RUNNING, FINISHED and DOWNLOAD
+ * have to be signaled to this test class. 
+ *   
  * @author Marcel Bruse
  */
-public class Client implements JobStatusListener {
+public class SuccessfulExportJob implements JobStatusListener {
 
     public AsyncExportJob job;
-
-    public static void main(String[] args) {		
-        Client client = new Client();
-        client.processJob();
-    }
-	
-    public void processJob() {
-        // Describe the export job
+    
+    @Test
+    public void processJob() throws InterruptedException {
         ExportJobDescription description= ExportJobDescription.getDefaultDescriptor();
         description.setInitiator("2758");
         description.setAccount("Bruse");
         description.setProduct("WU3");
         description.setJobnumber("Bruse_0815");
 		
-        // Set at least one unit. You could also define a region polygon.
         Unit unit = Unit.getDefaultUnit();
         unit.setValue("821");
         description.addUnit(unit);
 		
-        // Set at least one layer
         Layer layer = Layer.getDefaultLayer();
         layer.setProduct("WU3");
         layer.setName("GML");
         description.addLayer(layer);
 		
-        // Create a new export job with the job description and a HTTP connection
         job = new AsyncExportJob(description, new HTTPConnection("193.196.136.164"));
-	
-        // Register a job status listener
         job.addJobStatusListener(this);
 		
         try {
-            // Send the export job to the nF server in a separate thread
             job.send();
         } catch (FailedTransmissionException ex) {
-            // There was a problem with your connection or the job has been sent twice
             ex.printStackTrace();
         } catch (InvalidJobDescriptorException ex) {
-            // The export job description is invalid
             ex.printStackTrace();
         }
+        
+        // Wait for timeout, failure or that all tests pass
+        long timeout = 1000 * 60 * 3l; // 3 minutes maximum
+        long interval = 10000l;
+        while (!job.hasFinished() && !job.hasFailed() && timeout > 0) {
+        	Thread.sleep(interval);        	
+        	timeout -= interval;
+        }
     }
 
-    // This client is a job status listener and will get notified upon job status changes
     @Override
     public void jobStatusChanged(JobStatusEvent event) {
         JobStatus status = (JobStatus) event.getSource();
         System.out.println(status);
-        if (status == JobStatus.FINISHED) {
+        if (status == JobStatus.LOCAL) {
+        	assertTrue(true);
+        } else if (status == JobStatus.SENT) {
+        	assertTrue(true);        	
+        } else if (status == JobStatus.PENDING) {
+        	assertTrue(true);        	        	
+        } else if (status == JobStatus.RUNNING) {
+        	assertTrue(true);        	        	        	
+        } else if (status == JobStatus.FINISHED) {
             try {
-                // Start an asynchronous download of the resulting CityGML file
+            	assertTrue(true);
                 job.downloadResult();
             } catch (FailedTransmissionException ex) {
-                // Only finished jobs can download files
                 ex.printStackTrace();
             }
         } else if (status == JobStatus.DOWNLOAD) {
             try {
-                // Obtain the CityGML file handle
                 File file = job.getResult();
+                assertTrue(file.canRead());
                 System.out.println("CityGML at " + file.getAbsolutePath());
             } catch (FailedTransmissionException ex) {
-                // Download may have failed
                 ex.printStackTrace();
             }
         }
diff --git a/test/eu/simstadt/nf4j/async/test/SuccessfulImportJob.java b/test/eu/simstadt/nf4j/async/test/SuccessfulImportJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..b263644366e5c7167a96bed42b7865c77cd4205e
--- /dev/null
+++ b/test/eu/simstadt/nf4j/async/test/SuccessfulImportJob.java
@@ -0,0 +1,74 @@
+package eu.simstadt.nf4j.async.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.junit.Test;
+
+import eu.simstadt.nf4j.FailedTransmissionException;
+import eu.simstadt.nf4j.InvalidJobDescriptorException;
+import eu.simstadt.nf4j.JobStatus;
+import eu.simstadt.nf4j.async.AsyncImportJob;
+import eu.simstadt.nf4j.async.HTTPConnection;
+import eu.simstadt.nf4j.async.ImportJobDescription;
+import eu.simstadt.nf4j.async.JobStatusEvent;
+import eu.simstadt.nf4j.async.JobStatusListener;
+
+/**
+ * This class contains client oriented import job tests. It will send an import job and listens to
+ * status updates. Every of the subsequent status' LOCAL, SENT, PENDING, RUNNING, FINISHED
+ * have to be signaled to this test class. 
+ *   
+ * @author Marcel Bruse
+ */
+public class SuccessfulImportJob implements JobStatusListener {
+
+    public AsyncImportJob job;
+    
+    @Test
+    public void processJob() throws InterruptedException {
+		ImportJobDescription desc = ImportJobDescription.getDefaultDescriptor();
+		desc.setProduct("LBTEST");
+		desc.setLeaf("GR");
+		desc.setCityGMLFile(new File("SomeBuildings.gml"));
+		
+		HTTPConnection connector = new HTTPConnection("193.196.136.164");
+		job = new AsyncImportJob(desc, connector);
+		job.addJobStatusListener(this);
+		
+		try {
+			job.send();
+		} catch (InvalidJobDescriptorException ex) {
+			ex.printStackTrace();
+		} catch (FailedTransmissionException ex) {
+			ex.printStackTrace();
+		}
+		
+        // Wait for timeout, failure or that all tests pass
+        long timeout = 1000 * 60 * 5l; // 5 minutes maximum
+        long interval = 10000l;
+        while (!job.hasFinished() && !job.hasFailed() && timeout > 0) {
+        	Thread.sleep(interval);        	
+        	timeout -= interval;
+        }
+    }
+
+    @Override
+    public void jobStatusChanged(JobStatusEvent event) {
+        JobStatus status = (JobStatus) event.getSource();
+        System.out.println(status);
+        if (status == JobStatus.LOCAL) {
+        	assertTrue(true);
+        } else if (status == JobStatus.SENT) {
+        	assertTrue(true);
+        } else if (status == JobStatus.PENDING) {
+        	assertTrue(true);
+        } else if (status == JobStatus.RUNNING) {
+        	assertTrue(true);
+        } else if (status == JobStatus.FINISHED) {
+        	assertTrue(true);
+        }
+    }
+
+}
\ No newline at end of file