Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9362)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9395)
@@ -18,4 +18,5 @@
     public static readonly string EXPERIMENT_BLOB_CONTAINER = "experiment";
     public static readonly string VISUAL_BLOB_CONTAINER = "visualextensions";
+    public static readonly string JOB_TABLE = "Job";
     public static readonly string CLOUD_SETTINGS_KEY = "Cloudia.WindowsAzure.Storage";
 
@@ -311,8 +312,103 @@
 
     public string FindById(string algorithmId) {
-      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
-      container.CreateIfNotExist();
-      var blob = container.GetBlobReference(algorithmId);
-      return blob.DownloadText();
+      try {
+        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
+        container.CreateIfNotExist();
+        var blob = container.GetBlobReference(algorithmId);
+        return blob.DownloadText();
+      }
+      catch (Exception ex) {
+        Trace.TraceError(ex.ToString());
+        return null;
+      }
+    }
+
+
+    public bool Exists(string algorithmId) {
+      try {
+        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.VISUAL_BLOB_CONTAINER);
+        container.CreateIfNotExist();
+        var blob = container.GetBlobReference(algorithmId);
+        blob.FetchAttributes();
+        return true;
+      }
+      catch (StorageClientException ex) {
+        if (ex.ErrorCode == StorageErrorCode.ResourceNotFound) {
+          return false;
+        }
+        Trace.TraceError(ex.ToString());
+        return false;
+      }
+    }
+  }
+
+  internal sealed class JobEntity : TableServiceEntity {
+    public JobEntity() {
+    }
+
+    public JobEntity(string user, string experimentName, string experimentId, string jobId) {
+      PartitionKey = "JobPartition";
+      RowKey = user + "_" + jobId;
+      User = user;
+      ExperimentId = experimentId;
+      JobId = jobId;
+    }
+
+    public string ExperimentId { get; set; }
+
+    public string User { get; set; }
+
+    public string JobId { get; set; }
+  }
+
+  public class JobDao : IJobDao {
+    public IExperimentDao ExperimentDao { get; set; }
+    public CloudTableClient TableClient { get; set; }
+
+    public bool Add(string username, Experiment experiment, string jobId) {
+      try {
+        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
+        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
+        serviceContext.AddObject(AzureConstants.JOB_TABLE,
+          new JobEntity(username, experiment.Name, experiment.Id, jobId)
+        );
+        serviceContext.SaveChangesWithRetries();
+        return true;
+      }
+      catch (Exception ex) {
+        Trace.TraceError(ex.ToString());
+        return false;
+      }
+    }
+
+    public bool Delete(string username, string jobId) {
+      try {
+        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
+        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
+        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
+                      where e.JobId == jobId && e.User == username
+                      select e).FirstOrDefault();
+        serviceContext.DeleteObject(entity);        
+        return true;
+      }
+      catch (Exception ex) {
+        Trace.TraceError(ex.ToString());
+        return false;
+      }
+    }
+
+    public Experiment FindByJobId(string username, string jobId) {
+      try {
+        TableServiceContext serviceContext = TableClient.GetDataServiceContext();
+        TableClient.CreateTableIfNotExist(AzureConstants.JOB_TABLE);
+        var entity = (from e in serviceContext.CreateQuery<JobEntity>(AzureConstants.JOB_TABLE)
+                      where e.JobId == jobId && e.User == username
+                      select e).FirstOrDefault();
+        return ExperimentDao.GetExperimentById(new User() { Username = username }, entity.ExperimentId);
+      }
+      catch (Exception ex) {
+        Trace.TraceError(ex.ToString());
+        return null;
+      }
     }
   }
@@ -323,4 +419,5 @@
     private IExperimentDao expDao;
     private IVisualExtensionDao visualDao;
+    private IJobDao jobDao;
 
     private CloudStorageAccount storageAccount;
@@ -377,4 +474,14 @@
       }
     }
+
+
+    public IJobDao JobDao {
+      get {
+        if (jobDao == null) {
+          jobDao = new JobDao() { ExperimentDao = ExperimentDao, TableClient = StorageAccount.CreateCloudTableClient() };
+        }
+        return jobDao;
+      }
+    }
   }
 }
