Index: /trunk/sources/HeuristicLab.CEDMA.Core/AgentList.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Core/AgentList.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Core/AgentList.cs	(revision 390)
@@ -64,7 +64,7 @@
       Agent agent = new Agent();
       agent.Name = DateTime.Now.ToString();
-      agent.Status = ProcessStatus.Unkown;
+      agent.Status = ProcessStatus.Unknown;
       agent.Database = database;
-      long id = database.InsertAgent(agent.Name, DbPersistenceManager.Save(agent));
+      long id = database.InsertAgent(null, agent.Name, true, DbPersistenceManager.Save(agent));
       agent.Id = id;
       agentList.Add(agent);
Index: /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.Designer.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.Designer.cs	(revision 390)
@@ -119,4 +119,5 @@
       this.agentTreeView.TabIndex = 0;
       this.agentTreeView.BeforeExpand += new System.Windows.Forms.TreeViewCancelEventHandler(this.agentTreeView_BeforeExpand);
+      this.agentTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.agentTreeView_AfterSelect);
       // 
       // AgentListView
Index: /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Core/AgentListView.cs	(revision 390)
@@ -69,18 +69,4 @@
     }
 
-    private void variablesListView_SelectedIndexChanged(object sender, EventArgs e) {
-      if(detailsGroupBox.Controls.Count > 0)
-        detailsGroupBox.Controls[0].Dispose();
-      detailsGroupBox.Controls.Clear();
-      detailsGroupBox.Enabled = false;
-      if(agentTreeView.SelectedNode!=null) {
-        IAgent agent = (IAgent)agentTreeView.SelectedNode.Tag;
-        Control control = (Control)new AgentView(agent);
-        detailsGroupBox.Controls.Add(control);
-        control.Dock = DockStyle.Fill;
-        detailsGroupBox.Enabled = true;
-      }
-    }
-
     #region Button Events
     private void addButton_Click(object sender, EventArgs e) {
@@ -92,4 +78,18 @@
     private void agentTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
     }
+
+    private void agentTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      if(detailsGroupBox.Controls.Count > 0)
+        detailsGroupBox.Controls[0].Dispose();
+      detailsGroupBox.Controls.Clear();
+      detailsGroupBox.Enabled = false;
+      if(agentTreeView.SelectedNode != null) {
+        IAgent agent = (IAgent)agentTreeView.SelectedNode.Tag;
+        Control control = (Control)new AgentView(agent);
+        detailsGroupBox.Controls.Add(control);
+        control.Dock = DockStyle.Fill;
+        detailsGroupBox.Enabled = true;
+      }
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.CEDMA.Core/AgentView.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Core/AgentView.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Core/AgentView.cs	(revision 390)
@@ -58,5 +58,5 @@
         }
 
-        if(Agent.Status == ProcessStatus.Unkown) activateButton.Enabled = true;
+        if(Agent.Status == ProcessStatus.Unknown) activateButton.Enabled = true;
         else activateButton.Enabled = false;
       }
Index: /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/AgentEntry.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/AgentEntry.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/AgentEntry.cs	(revision 390)
@@ -33,8 +33,12 @@
     public long Id { get; set; }
     [DataMember]
+    public long? ParentAgentId { get; set; }
+    [DataMember]
     public string Name { get; set; }
     [DataMember]
     public ProcessStatus Status { get; set; }
     [DataMember]
+    public bool ControllerAgent { get; set; }
+    [DataMember]
     public byte[] RawData { get; set; }
   }
Index: /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/HeuristicLab.CEDMA.DB.Interfaces.csproj
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/HeuristicLab.CEDMA.DB.Interfaces.csproj	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/HeuristicLab.CEDMA.DB.Interfaces.csproj	(revision 390)
@@ -56,5 +56,4 @@
     <Compile Include="AgentEntry.cs" />
     <Compile Include="ProcessStatus.cs" />
-    <Compile Include="RunEntry.cs" />
     <Compile Include="ResultEntry.cs" />
     <Compile Include="HeuristicLabCedmaDbInterfacesPlugin.cs" />
Index: /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/IDatabase.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/IDatabase.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/IDatabase.cs	(revision 390)
@@ -31,5 +31,5 @@
   public interface IDatabase {
     [OperationContract]
-    long InsertAgent(string name, byte[] rawData);
+    long InsertAgent(long? parentAgentId, string name, bool controllerAgent, byte[] rawData);
 
     [OperationContract(Name = "UpdateAgentName")]
@@ -43,21 +43,8 @@
 
     [OperationContract]
-    long InsertRun(long agentId, byte[] rawData);
+    long InsertResult(long agentId, string summary, string description, byte[] rawData);
 
     [OperationContract]
-    void UpdateRunStart(long runId, DateTime CreationTime);
-
-    [OperationContract]
-    void UpdateRunFinished(long runId, DateTime CreationTime);
-
-    [OperationContract]
-    void UpdateRunStatus(long runId, ProcessStatus status);
-
-    [OperationContract]
-    long InsertResult(long runId, byte[] rawData);
-
-    [OperationContract]
-    long InsertSubResult(long resultId, byte[] rawData);
-
+    long InsertSubResult(long resultId, string summary, string description, byte[] rawData);
 
     // should be replaced by more powerful querying interface (LINQ provider?)
@@ -66,11 +53,11 @@
 
     [OperationContract]
-    ICollection<RunEntry> GetRuns(long agentId);
+    ICollection<AgentEntry> GetSubAgents(long parentAgentId);
 
     [OperationContract]
-    ICollection<ResultEntry> GetResults(long runId);
+    ICollection<ResultEntry> GetResults(long agentId);
 
     [OperationContract]
-    ICollection<ResultEntry> GetSubResults(long resultId);
+    ICollection<ResultEntry> GetSubResults(long parentResultId);
 
   }
Index: /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ProcessStatus.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ProcessStatus.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ProcessStatus.cs	(revision 390)
@@ -26,4 +26,4 @@
 
 namespace HeuristicLab.CEDMA.DB.Interfaces {
-  public enum ProcessStatus { Unkown, Active, Finished, Error, Waiting}
+  public enum ProcessStatus { Unknown, Active, Finished, Error, Waiting}
 }
Index: /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ResultEntry.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ResultEntry.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/ResultEntry.cs	(revision 390)
@@ -33,7 +33,7 @@
     public long Id { get; set; }
     [DataMember]
-    public long RunId { get; set; }
+    public long? AgentId { get; set; }
     [DataMember]
-    public long ResultId { get; set; }
+    public long? ParentResultId { get; set; }
     [DataMember]
     public string Summary { get; set; }
Index: unk/sources/HeuristicLab.CEDMA.DB.Interfaces/RunEntry.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB.Interfaces/RunEntry.cs	(revision 389)
+++ 	(revision )
@@ -1,43 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.CEDMA.DB.Interfaces;
-using System.Runtime.Serialization;
-
-namespace HeuristicLab.CEDMA.DB.Interfaces {
-  [DataContract]
-  public class RunEntry {
-    [DataMember]
-    public long Id { get; set; }
-    [DataMember]
-    public long AgentId { get; set; }
-    [DataMember]
-    public DateTime CreationTime { get; set; }
-    [DataMember]
-    public ProcessStatus Status { get; set; }
-    [DataMember]
-    public byte[] RawData { get; set; }
-  }
-}
Index: /trunk/sources/HeuristicLab.CEDMA.DB/Database.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.DB/Database.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.DB/Database.cs	(revision 390)
@@ -55,18 +55,13 @@
             }
             using(DbCommand cmd = cnn.CreateCommand()) {
-              cmd.CommandText = "CREATE TABLE Agent (ID integer primary key autoincrement, ProjectId integer, Name text, Status text default 'Unknown', RawData Blob)";
+              cmd.CommandText = "CREATE TABLE Agent (ID integer primary key autoincrement, ProjectId integer, ParentAgentId integer, Name text, Status text default 'Unknown', ControllerAgent integer, RawData Blob)";
               cmd.Transaction = t;
               cmd.ExecuteNonQuery();
             }
             using(DbCommand cmd = cnn.CreateCommand()) {
-              cmd.CommandText = "CREATE TABLE Run (ID integer primary key autoincrement, AgentId integer, CreationTime DateTime, StartTime DateTime, FinishedTime DateTime, Status text default 'Unknown', RawData Blob)";
+              cmd.CommandText = "CREATE TABLE Result (ID integer primary key autoincrement, AgentId integer, ParentResultId integer, Summary text, Description text, CreationTime DateTime, RawData Blob)";
               cmd.Transaction = t;
               cmd.ExecuteNonQuery();
             }
-            using(DbCommand cmd = cnn.CreateCommand()) {
-              cmd.CommandText = "CREATE TABLE Result (ID integer primary key autoincrement, RunId integer, ResultId integer, CreationTime DateTime, RawData Blob)";
-              cmd.Transaction = t;
-              cmd.ExecuteNonQuery();
-            }
             t.Commit();
           }
@@ -79,5 +74,5 @@
 
     #region insert agent/run/result/sub-result
-    public long InsertAgent(string name, byte[] rawData) {
+    public long InsertAgent(long? parentAgentId, string name, bool controllerAgent, byte[] rawData) {
       rwLock.EnterWriteLock();
       try {
@@ -88,9 +83,17 @@
             using(DbCommand c = cnn.CreateCommand()) {
               c.Transaction = t;
-              c.CommandText = "Insert into Agent (Name, RawData) values (@Name, @RawData); select last_insert_rowid()";
+              c.CommandText = "Insert into Agent (Name, ParentAgentId, ControllerAgent, RawData) values (@Name, @ParentAgentId, @ControllerAgent, @RawData); select last_insert_rowid()";
               DbParameter nameParam = c.CreateParameter();
               nameParam.ParameterName = "@Name";
               nameParam.Value = name;
               c.Parameters.Add(nameParam);
+              DbParameter parentParam = c.CreateParameter();
+              parentParam.ParameterName = "@ParentAgentId";
+              parentParam.Value = parentAgentId;
+              c.Parameters.Add(parentParam);
+              DbParameter controllerParam = c.CreateParameter();
+              controllerParam.ParameterName = "@ControllerAgent";
+              controllerParam.Value = controllerAgent;
+              c.Parameters.Add(controllerParam);
               DbParameter dataParam = c.CreateParameter();
               dataParam.ParameterName = "@RawData";
@@ -108,5 +111,5 @@
     }
 
-    public long InsertRun(long agentId, byte[] rawData) {
+    public long InsertResult(long agentId, string summary, string description, byte[] rawData) {
       rwLock.EnterWriteLock();
       try {
@@ -117,5 +120,5 @@
             using(DbCommand c = cnn.CreateCommand()) {
               c.Transaction = t;
-              c.CommandText = "Insert into Run (AgentId, CreationTime, RawData) values (@AgentId, @CreationTime, @RawData); select last_insert_rowid()";
+              c.CommandText = "Insert into Result (AgentId, CreationTime, Summary, Description, RawData) values (@AgentId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()";
               DbParameter agentIdParam = c.CreateParameter();
               agentIdParam.ParameterName = "@AgentId";
@@ -127,4 +130,12 @@
               creationParam.Value = now;
               c.Parameters.Add(creationParam);
+              DbParameter summaryParam = c.CreateParameter();
+              summaryParam.ParameterName = "@Summary";
+              summaryParam.Value = summary;
+              c.Parameters.Add(summaryParam);
+              DbParameter descParam = c.CreateParameter();
+              descParam.ParameterName = "@Description";
+              descParam.Value = description;
+              c.Parameters.Add(descParam);
               DbParameter rawDataParam = c.CreateParameter();
               rawDataParam.ParameterName = "@RawData";
@@ -142,5 +153,5 @@
     }
 
-    public long InsertResult(long runId, byte[] rawData) {
+    public long InsertSubResult(long resultId, string summary, string description, byte[] rawData) {
       rwLock.EnterWriteLock();
       try {
@@ -151,41 +162,7 @@
             using(DbCommand c = cnn.CreateCommand()) {
               c.Transaction = t;
-              c.CommandText = "Insert into Result (RunId, CreationTime, RawData) values (@RunId, @CreationTime, @RawData); select last_insert_rowid()";
-              DbParameter runIdParam = c.CreateParameter();
-              runIdParam.ParameterName = "@RunId";
-              runIdParam.Value = runId;
-              c.Parameters.Add(runIdParam);
-              DbParameter creationParam = c.CreateParameter();
-              creationParam.ParameterName = "@CreationTime";
-              DateTime now = DateTime.Now;
-              creationParam.Value = now;
-              c.Parameters.Add(creationParam);
-              DbParameter rawDataParam = c.CreateParameter();
-              rawDataParam.ParameterName = "@RawData";
-              rawDataParam.Value = rawData;
-              c.Parameters.Add(rawDataParam);
-              id = (long)c.ExecuteScalar();
-            }
-            t.Commit();
-            return id;
-          }
-        }
-      } finally {
-        rwLock.ExitWriteLock();
-      }
-    }
-
-    public long InsertSubResult(long resultId, byte[] rawData) {
-      rwLock.EnterWriteLock();
-      try {
-        using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          long id;
-          using(DbTransaction t = cnn.BeginTransaction()) {
-            using(DbCommand c = cnn.CreateCommand()) {
-              c.Transaction = t;
-              c.CommandText = "Insert into Result (ResultId, CreationTime, RawData) values (@ResultId, @CreationTime, @RawData); select last_insert_rowid()";
+              c.CommandText = "Insert into Result (ParentResultId, CreationTime, Summary, Description, RawData) values (@ParentResultId, @CreationTime, @Summary, @Description, @RawData); select last_insert_rowid()";
               DbParameter resultIdParam = c.CreateParameter();
-              resultIdParam.ParameterName = "@ResultId";
+              resultIdParam.ParameterName = "@ParentResultId";
               resultIdParam.Value = resultId;
               c.Parameters.Add(resultIdParam);
@@ -195,4 +172,12 @@
               creationParam.Value = now;
               c.Parameters.Add(creationParam);
+              DbParameter summaryParam = c.CreateParameter();
+              summaryParam.ParameterName = "@Summary";
+              summaryParam.Value = summary;
+              c.Parameters.Add(summaryParam);
+              DbParameter descParam = c.CreateParameter();
+              descParam.ParameterName = "@Description";
+              descParam.Value = description;
+              c.Parameters.Add(descParam);
               DbParameter rawDataParam = c.CreateParameter();
               rawDataParam.ParameterName = "@RawData";
@@ -293,84 +278,84 @@
     }
 
-    public void UpdateRunStart(long runId, DateTime startTime) {
-      rwLock.EnterWriteLock();
-      try {
-        using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          using(SQLiteTransaction t = cnn.BeginTransaction()) {
-            using(SQLiteCommand c = cnn.CreateCommand()) {
-              c.Transaction = t;
-              c.CommandText = "Update Run set StartTime=@StartTime where id=@Id";
-              DbParameter startTimeParam = c.CreateParameter();
-              DbParameter idParam = c.CreateParameter();
-              startTimeParam.ParameterName = "@StartTime";
-              startTimeParam.Value = startTime;
-              idParam.ParameterName = "@Id";
-              idParam.Value = runId;
-              c.Parameters.Add(startTimeParam);
-              c.Parameters.Add(idParam);
-              c.ExecuteNonQuery();
-            }
-            t.Commit();
-          }
-        }
-      } finally {
-        rwLock.ExitWriteLock();
-      }
-    }
-
-    public void UpdateRunFinished(long runId, DateTime finishedTime) {
-      rwLock.EnterWriteLock();
-      try {
-        using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          using(SQLiteTransaction t = cnn.BeginTransaction()) {
-            using(SQLiteCommand c = cnn.CreateCommand()) {
-              c.Transaction = t;
-              c.CommandText = "Update Run set FinishedTime=@FinishedTime where id=@Id";
-              DbParameter finishedTimeParam = c.CreateParameter();
-              DbParameter idParam = c.CreateParameter();
-              finishedTimeParam.ParameterName = "@FinishedTime";
-              finishedTimeParam.Value = finishedTime;
-              idParam.ParameterName = "@Id";
-              idParam.Value = runId;
-              c.Parameters.Add(finishedTimeParam);
-              c.Parameters.Add(idParam);
-              c.ExecuteNonQuery();
-            }
-            t.Commit();
-          }
-        }
-      } finally {
-        rwLock.ExitWriteLock();
-      }
-    }
-
-    public void UpdateRunStatus(long runId, ProcessStatus status) {
-      rwLock.EnterWriteLock();
-      try {
-        using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          using(SQLiteTransaction t = cnn.BeginTransaction()) {
-            using(SQLiteCommand c = cnn.CreateCommand()) {
-              c.Transaction = t;
-              c.CommandText = "Update Run set Status=@Status where id=@Id";
-              DbParameter statusParam = c.CreateParameter();
-              DbParameter idParam = c.CreateParameter();
-              statusParam.ParameterName = "@Status";
-              statusParam.Value = status;
-              idParam.ParameterName = "@Id";
-              idParam.Value = runId;
-              c.Parameters.Add(statusParam);
-              c.Parameters.Add(idParam);
-              c.ExecuteNonQuery();
-            }
-            t.Commit();
-          }
-        }
-      } finally {
-        rwLock.ExitWriteLock();
-      }
-    }
+    //public void UpdateRunStart(long runId, DateTime startTime) {
+    //  rwLock.EnterWriteLock();
+    //  try {
+    //    using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
+    //      cnn.Open();
+    //      using(SQLiteTransaction t = cnn.BeginTransaction()) {
+    //        using(SQLiteCommand c = cnn.CreateCommand()) {
+    //          c.Transaction = t;
+    //          c.CommandText = "Update Run set StartTime=@StartTime where id=@Id";
+    //          DbParameter startTimeParam = c.CreateParameter();
+    //          DbParameter idParam = c.CreateParameter();
+    //          startTimeParam.ParameterName = "@StartTime";
+    //          startTimeParam.Value = startTime;
+    //          idParam.ParameterName = "@Id";
+    //          idParam.Value = runId;
+    //          c.Parameters.Add(startTimeParam);
+    //          c.Parameters.Add(idParam);
+    //          c.ExecuteNonQuery();
+    //        }
+    //        t.Commit();
+    //      }
+    //    }
+    //  } finally {
+    //    rwLock.ExitWriteLock();
+    //  }
+    //}
+
+    //public void UpdateRunFinished(long runId, DateTime finishedTime) {
+    //  rwLock.EnterWriteLock();
+    //  try {
+    //    using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
+    //      cnn.Open();
+    //      using(SQLiteTransaction t = cnn.BeginTransaction()) {
+    //        using(SQLiteCommand c = cnn.CreateCommand()) {
+    //          c.Transaction = t;
+    //          c.CommandText = "Update Run set FinishedTime=@FinishedTime where id=@Id";
+    //          DbParameter finishedTimeParam = c.CreateParameter();
+    //          DbParameter idParam = c.CreateParameter();
+    //          finishedTimeParam.ParameterName = "@FinishedTime";
+    //          finishedTimeParam.Value = finishedTime;
+    //          idParam.ParameterName = "@Id";
+    //          idParam.Value = runId;
+    //          c.Parameters.Add(finishedTimeParam);
+    //          c.Parameters.Add(idParam);
+    //          c.ExecuteNonQuery();
+    //        }
+    //        t.Commit();
+    //      }
+    //    }
+    //  } finally {
+    //    rwLock.ExitWriteLock();
+    //  }
+    //}
+
+    //public void UpdateRunStatus(long runId, ProcessStatus status) {
+    //  rwLock.EnterWriteLock();
+    //  try {
+    //    using(SQLiteConnection cnn = new SQLiteConnection(connectionString)) {
+    //      cnn.Open();
+    //      using(SQLiteTransaction t = cnn.BeginTransaction()) {
+    //        using(SQLiteCommand c = cnn.CreateCommand()) {
+    //          c.Transaction = t;
+    //          c.CommandText = "Update Run set Status=@Status where id=@Id";
+    //          DbParameter statusParam = c.CreateParameter();
+    //          DbParameter idParam = c.CreateParameter();
+    //          statusParam.ParameterName = "@Status";
+    //          statusParam.Value = status;
+    //          idParam.ParameterName = "@Id";
+    //          idParam.Value = runId;
+    //          c.Parameters.Add(statusParam);
+    //          c.Parameters.Add(idParam);
+    //          c.ExecuteNonQuery();
+    //        }
+    //        t.Commit();
+    //      }
+    //    }
+    //  } finally {
+    //    rwLock.ExitWriteLock();
+    //  }
+    //}
     #endregion
 
@@ -384,5 +369,5 @@
           cnn.Open();
           SQLiteCommand c = cnn.CreateCommand();
-          c.CommandText = "Select id, name, status, rawdata from Agent where Status=@Status";
+          c.CommandText = "Select id, name, ControllerAgent, rawdata from Agent where Status=@Status";
           DbParameter statusParameter = c.CreateParameter();
           statusParameter.ParameterName = "@Status";
@@ -393,7 +378,9 @@
           while(r.Read()) {
             AgentEntry agent = new AgentEntry();
+            agent.ParentAgentId = null;
+            agent.Status = status;
             agent.Id = r.GetInt32(0);
-            agent.Name = r.GetString(1);
-            agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2));
+            agent.Name = r.IsDBNull(1)?"":r.GetString(1);
+            agent.ControllerAgent = r.GetBoolean(2);
             agent.RawData = (byte[])r.GetValue(3);
             agents.Add(agent);
@@ -413,12 +400,42 @@
           cnn.Open();
           using(DbCommand c = cnn.CreateCommand()) {
-            c.CommandText = "Select id, name, status, rawdata from Agent";
+            c.CommandText = "Select id, ParentAgentId, name, status, ControllerAgent, rawdata from Agent";
             using(DbDataReader r = c.ExecuteReader()) {
               while(r.Read()) {
                 AgentEntry agent = new AgentEntry();
                 agent.Id = r.GetInt32(0);
+                agent.ParentAgentId = r.IsDBNull(1) ? null : new Nullable<long>(r.GetInt32(1));
+                agent.Name = r.GetString(2);
+                agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));
+                agent.ControllerAgent = r.GetBoolean(4);
+                agent.RawData = (byte[])r.GetValue(5);
+                agents.Add(agent);
+              }
+            }
+          }
+        }
+      } finally {
+        rwLock.ExitReadLock();
+      }
+      return agents;
+    }
+
+    public ICollection<AgentEntry> GetSubAgents(long parentAgentId) {
+      rwLock.EnterReadLock();
+      List<AgentEntry> agents = new List<AgentEntry>();
+      try {
+        using(DbConnection cnn = new SQLiteConnection(connectionString)) {
+          cnn.Open();
+          using(DbCommand c = cnn.CreateCommand()) {
+            c.CommandText = "Select id, name, status, controllerAgent, rawdata from Agent where ParentAgentId=@ParentAgentId";
+            using(DbDataReader r = c.ExecuteReader()) {
+              while(r.Read()) {
+                AgentEntry agent = new AgentEntry();
+                agent.ParentAgentId = parentAgentId;
+                agent.Id = r.GetInt32(0);
                 agent.Name = r.GetString(1);
                 agent.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(2));
-                agent.RawData = (byte[])r.GetValue(3);
+                agent.ControllerAgent = r.GetBoolean(3);
+                agent.RawData = (byte[])r.GetValue(4);
                 agents.Add(agent);
               }
@@ -432,69 +449,69 @@
     }
 
-    public ICollection<RunEntry> GetRuns(long agentId) {
-      List<RunEntry> runs = new List<RunEntry>();
-      rwLock.EnterReadLock();
-      try {
-        using(DbConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          using(DbCommand c = cnn.CreateCommand()) {
-            c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where AgentId=@AgentId";
-            DbParameter agentParameter = c.CreateParameter();
-            agentParameter.ParameterName = "@AgentId";
-            agentParameter.Value = agentId;
-            c.Parameters.Add(agentParameter);
-
-            using(DbDataReader r = c.ExecuteReader()) {
-              while(r.Read()) {
-                RunEntry run = new RunEntry();
-                run.Id = r.GetInt32(0);
-                run.AgentId = r.GetInt32(1);
-                run.CreationTime = r.GetDateTime(2);
-                run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));
-                run.RawData = (byte[])r.GetValue(4);
-                runs.Add(run);
-              }
-            }
-          }
-        }
-      } finally {
-        rwLock.ExitReadLock();
-      }
-      return runs;
-    }
-
-    public ICollection<RunEntry> GetRuns(ProcessStatus status) {
-      List<RunEntry> runs = new List<RunEntry>();
-      rwLock.EnterReadLock();
-      try {
-        using(DbConnection cnn = new SQLiteConnection(connectionString)) {
-          cnn.Open();
-          using(DbCommand c = cnn.CreateCommand()) {
-            c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where Status=@Status";
-            DbParameter statusParameter = c.CreateParameter();
-            statusParameter.ParameterName = "@Status";
-            statusParameter.Value = status;
-            c.Parameters.Add(statusParameter);
-
-            using(DbDataReader r = c.ExecuteReader()) {
-              while(r.Read()) {
-                RunEntry run = new RunEntry();
-                run.Id = r.GetInt32(0);
-                run.AgentId = r.GetInt32(1);
-                run.CreationTime = r.GetDateTime(2);
-                run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));
-                run.RawData = (byte[])r.GetValue(4);
-                runs.Add(run);
-              }
-            }
-          }
-        }
-      } finally {
-        rwLock.ExitReadLock();
-      }
-      return runs;
-    }
-
-    public ICollection<ResultEntry> GetResults(long runId) {
+    //public ICollection<RunEntry> GetRuns(long agentId) {
+    //  List<RunEntry> runs = new List<RunEntry>();
+    //  rwLock.EnterReadLock();
+    //  try {
+    //    using(DbConnection cnn = new SQLiteConnection(connectionString)) {
+    //      cnn.Open();
+    //      using(DbCommand c = cnn.CreateCommand()) {
+    //        c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where AgentId=@AgentId";
+    //        DbParameter agentParameter = c.CreateParameter();
+    //        agentParameter.ParameterName = "@AgentId";
+    //        agentParameter.Value = agentId;
+    //        c.Parameters.Add(agentParameter);
+
+    //        using(DbDataReader r = c.ExecuteReader()) {
+    //          while(r.Read()) {
+    //            RunEntry run = new RunEntry();
+    //            run.Id = r.GetInt32(0);
+    //            run.AgentId = r.GetInt32(1);
+    //            run.CreationTime = r.GetDateTime(2);
+    //            run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));
+    //            run.RawData = (byte[])r.GetValue(4);
+    //            runs.Add(run);
+    //          }
+    //        }
+    //      }
+    //    }
+    //  } finally {
+    //    rwLock.ExitReadLock();
+    //  }
+    //  return runs;
+    //}
+
+    //public ICollection<RunEntry> GetRuns(ProcessStatus status) {
+    //  List<RunEntry> runs = new List<RunEntry>();
+    //  rwLock.EnterReadLock();
+    //  try {
+    //    using(DbConnection cnn = new SQLiteConnection(connectionString)) {
+    //      cnn.Open();
+    //      using(DbCommand c = cnn.CreateCommand()) {
+    //        c.CommandText = "Select Id, AgentId, CreationTime, Status, Rawdata from Run where Status=@Status";
+    //        DbParameter statusParameter = c.CreateParameter();
+    //        statusParameter.ParameterName = "@Status";
+    //        statusParameter.Value = status;
+    //        c.Parameters.Add(statusParameter);
+
+    //        using(DbDataReader r = c.ExecuteReader()) {
+    //          while(r.Read()) {
+    //            RunEntry run = new RunEntry();
+    //            run.Id = r.GetInt32(0);
+    //            run.AgentId = r.GetInt32(1);
+    //            run.CreationTime = r.GetDateTime(2);
+    //            run.Status = (ProcessStatus)Enum.Parse(typeof(ProcessStatus), r.GetString(3));
+    //            run.RawData = (byte[])r.GetValue(4);
+    //            runs.Add(run);
+    //          }
+    //        }
+    //      }
+    //    }
+    //  } finally {
+    //    rwLock.ExitReadLock();
+    //  }
+    //  return runs;
+    //}
+
+    public ICollection<ResultEntry> GetResults(long agentId) {
       List<ResultEntry> results = new List<ResultEntry>();
       rwLock.EnterReadLock();
@@ -503,12 +520,18 @@
           cnn.Open();
           using(DbCommand c = cnn.CreateCommand()) {
-            c.CommandText = "Select Id, RunId, CreationTime, Rawdata from Result";
+            c.CommandText = "Select Id, CreationTime, Summary, Description, Rawdata from Result where AgentId=@AgentId";
+            DbParameter agentParam = c.CreateParameter();
+            agentParam.ParameterName = "@AgentId";
+            agentParam.Value = agentId;
+            c.Parameters.Add(agentParam);
             using(DbDataReader r = c.ExecuteReader()) {
               while(r.Read()) {
                 ResultEntry result = new ResultEntry();
+                result.AgentId = agentId;
                 result.Id = r.GetInt32(0);
-                result.RunId = r.GetInt32(1);
-                result.CreationTime = r.GetDateTime(2);
-                result.RawData = (byte[])r.GetValue(3);
+                result.CreationTime = r.GetDateTime(1);
+                result.Summary = r.GetString(2);
+                result.Description = r.GetString(3);
+                result.RawData = (byte[])r.GetValue(4);
                 results.Add(result);
               }
@@ -523,5 +546,33 @@
 
     public ICollection<ResultEntry> GetSubResults(long resultId) {
-      throw new NotImplementedException();
+      List<ResultEntry> results = new List<ResultEntry>();
+      rwLock.EnterReadLock();
+      try {
+        using(DbConnection cnn = new SQLiteConnection(connectionString)) {
+          cnn.Open();
+          using(DbCommand c = cnn.CreateCommand()) {
+            c.CommandText = "Select Id, CreationTime, Summary, Description, Rawdata from Result where ParentResultId=@ParentResultId";
+            DbParameter parentParam = c.CreateParameter();
+            parentParam.ParameterName = "@ParentResultId";
+            parentParam.Value = resultId;
+            c.Parameters.Add(parentParam);
+            using(DbDataReader r = c.ExecuteReader()) {
+              while(r.Read()) {
+                ResultEntry result = new ResultEntry();
+                result.ParentResultId = resultId;
+                result.Id = r.GetInt32(0);
+                result.CreationTime = r.GetDateTime(1);
+                result.Summary = r.GetString(2);
+                result.Description = r.GetString(3);
+                result.RawData = (byte[])r.GetValue(4);
+                results.Add(result);
+              }
+            }
+          }
+        }
+      } finally {
+        rwLock.ExitReadLock();
+      }
+      return results;
     }
     #endregion
Index: /trunk/sources/HeuristicLab.CEDMA.Operators/OnGridProcessor.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Operators/OnGridProcessor.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Operators/OnGridProcessor.cs	(revision 390)
@@ -44,4 +44,5 @@
 
     public override IOperation Apply(IScope scope) {
+      
       IOperatorGraph operatorGraph = scope.GetVariableValue<IOperatorGraph>("OperatorGraph", false);
       string serverUrl = scope.GetVariableValue<StringData>("ServerUrl", true).Data;
@@ -55,6 +56,6 @@
       using(ChannelFactory<IDatabase> factory = new ChannelFactory<IDatabase>(binding)) {
         IDatabase database = factory.CreateChannel(new EndpointAddress(serverUrl));
-        long id = database.InsertRun(agentId, DbPersistenceManager.Save(operatorGraph));
-        database.UpdateRunStatus(id, ProcessStatus.Waiting);
+        long id = database.InsertAgent(agentId, null, false, DbPersistenceManager.Save(operatorGraph));
+        database.UpdateAgent(id, ProcessStatus.Waiting);
       }
       return null;
Index: /trunk/sources/HeuristicLab.CEDMA.Server/AgentScheduler.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Server/AgentScheduler.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Server/AgentScheduler.cs	(revision 390)
@@ -65,5 +65,5 @@
     }
     private void CreateNewEngines() {
-      ICollection<AgentEntry> agents = database.GetAgents(ProcessStatus.Waiting);
+      IEnumerable<AgentEntry> agents = database.GetAgents(ProcessStatus.Waiting).Where(a=>a.ControllerAgent);
       foreach(AgentEntry a in agents) {
         SequentialEngine.SequentialEngine engine = new HeuristicLab.SequentialEngine.SequentialEngine();
Index: /trunk/sources/HeuristicLab.CEDMA.Server/RunScheduler.cs
===================================================================
--- /trunk/sources/HeuristicLab.CEDMA.Server/RunScheduler.cs	(revision 389)
+++ /trunk/sources/HeuristicLab.CEDMA.Server/RunScheduler.cs	(revision 390)
@@ -30,22 +30,24 @@
 using HeuristicLab.CEDMA.Core;
 using HeuristicLab.Grid;
+using System.Diagnostics;
 
 namespace HeuristicLab.CEDMA.Server {
   public class RunScheduler {
+    private class Job {
+      public long AgentId;
+      public WaitHandle WaitHandle;
+      public AtomicOperation Operation;
+    }
     private Database database;
     private JobManager jobManager;
     private const int RELEASE_INTERVAL = 5;
     private object remoteCommLock = new object();
-    private object collectionsLock = new object();
-    private Queue<WaitHandle> waithandles;
-    private Dictionary<WaitHandle, AtomicOperation> runningOperations;
-    private Dictionary<WaitHandle, long> runningEntries;
+    private object queueLock = new object();
+    private Queue<Job> jobQueue;
 
     public RunScheduler(Database database, JobManager jobManager) {
       this.database = database;
       this.jobManager = jobManager;
-      runningOperations = new Dictionary<WaitHandle, AtomicOperation>();
-      runningEntries = new Dictionary<WaitHandle, long>();
-      waithandles = new Queue<WaitHandle>();
+      jobQueue = new Queue<Job>();
       Thread resultsGatheringThread = new Thread(GatherResults);
       resultsGatheringThread.Start();
@@ -58,23 +60,24 @@
     }
     private void ReleaseWaitingRuns() {
-      ICollection<RunEntry> runs;
+      IEnumerable<AgentEntry> agents;
       lock(remoteCommLock) {
-        runs = database.GetRuns(ProcessStatus.Waiting);
+        agents = database.GetAgents(ProcessStatus.Waiting).Where(a=>!a.ControllerAgent);
       }
-      foreach(RunEntry entry in runs) {
+      foreach(AgentEntry entry in agents) {
         IOperatorGraph opGraph = (IOperatorGraph)DbPersistenceManager.Restore(entry.RawData);
-        Scope scope = new Scope();
-        AtomicOperation op = new AtomicOperation(opGraph.InitialOperator, scope);
+        AtomicOperation op = new AtomicOperation(opGraph.InitialOperator, new Scope());
         WaitHandle wHandle;
         lock(remoteCommLock) {
-          wHandle = jobManager.BeginExecuteOperation(scope, op);
-          database.UpdateRunStatus(entry.Id, ProcessStatus.Active);
-          database.UpdateRunStart(entry.Id, DateTime.Now);
+          wHandle = jobManager.BeginExecuteOperation(op.Scope, op);
+          database.UpdateAgent(entry.Id, ProcessStatus.Active);
         }
 
-        lock(collectionsLock) {
-          waithandles.Enqueue(wHandle);
-          runningOperations[wHandle] = op;
-          runningEntries[wHandle] = entry.Id;
+        Job job = new Job();
+        job.AgentId = entry.Id;
+        job.Operation = op;
+        job.WaitHandle = wHandle;
+
+        lock(queueLock) {
+          jobQueue.Enqueue(job);
         }
       }
@@ -82,27 +85,24 @@
 
     private void GatherResults() {
-      while(true) {
-        if(waithandles.Count == 0) Thread.Sleep(1000);
-        else {
-          WaitHandle w;
-          lock(collectionsLock) {
-            w = waithandles.Dequeue();
-          }
-          w.WaitOne();
-          long id;
-          AtomicOperation op;
-          lock(collectionsLock) {
-            id = runningEntries[w];
-            runningEntries.Remove(w);
-            op = runningOperations[w];
-            runningOperations.Remove(w);
-          }
-          w.Close();
-          lock(remoteCommLock) {
-            jobManager.EndExecuteOperation(op);
-            database.UpdateRunStatus(id, ProcessStatus.Finished);
-            database.UpdateRunFinished(id, DateTime.Now);
+      try {
+        while(true) {
+          int runningJobs;
+          lock(queueLock) runningJobs = jobQueue.Count;
+          if(runningJobs==0) Thread.Sleep(1000); // TASK: replace with waithandle
+          else {
+            Job job;
+            lock(queueLock) {
+              job = jobQueue.Dequeue();
+            }
+            job.WaitHandle.WaitOne();
+            job.WaitHandle.Close();
+            lock(remoteCommLock) {
+              jobManager.EndExecuteOperation(job.Operation);
+              database.UpdateAgent(job.AgentId, ProcessStatus.Finished);
+            }
           }
         }
+      } finally {
+        Debug.Assert(false); // make sure we are notified when this thread is killed while debugging
       }
     }
