Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.Designer.cs	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.Designer.cs	(revision 4408)
@@ -45,222 +45,100 @@
     /// </summary>
     private void InitializeComponent() {
-      this.components = new System.ComponentModel.Container();
-      this.dataGridView1 = new System.Windows.Forms.DataGridView();
-      this.idDataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.nameDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.descriptionDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.algorithmClassBindingSource = new System.Windows.Forms.BindingSource(this.components);
-      this.refreshButton = new System.Windows.Forms.Button();
-      this.saveButton = new System.Windows.Forms.Button();
-      this.tabControl1 = new System.Windows.Forms.TabControl();
-      this.tabPage1 = new System.Windows.Forms.TabPage();
-      this.populateButton = new System.Windows.Forms.Button();
-      this.tabPage2 = new System.Windows.Forms.TabPage();
-      this.dataGridView2 = new System.Windows.Forms.DataGridView();
-      this.idDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.algorithmClassIdDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.platformIdDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.nameDataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.descriptionDataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.algorithmDataDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.algorithmClassDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.platformDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
-      this.algorithmBindingSource = new System.Windows.Forms.BindingSource(this.components);
-      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
-      ((System.ComponentModel.ISupportInitialize)(this.algorithmClassBindingSource)).BeginInit();
-      this.tabControl1.SuspendLayout();
-      this.tabPage1.SuspendLayout();
-      this.tabPage2.SuspendLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
-      ((System.ComponentModel.ISupportInitialize)(this.algorithmBindingSource)).BeginInit();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.algorithmClassesTabPage = new System.Windows.Forms.TabPage();
+      this.algorithmsTabPage = new System.Windows.Forms.TabPage();
+      this.refreshAlgorithmsButton = new System.Windows.Forms.Button();
+      this.algorithmCollectionView = new HeuristicLab.Clients.OKB.AlgorithmCollectionView();
+      this.algorithmClassCollectionView = new HeuristicLab.Clients.OKB.AlgorithmClassCollectionView();
+      this.refreshAlgorithmClassesButton = new System.Windows.Forms.Button();
+      this.tabControl.SuspendLayout();
+      this.algorithmClassesTabPage.SuspendLayout();
+      this.algorithmsTabPage.SuspendLayout();
       this.SuspendLayout();
       // 
-      // dataGridView1
+      // tabControl
       // 
-      this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                   | System.Windows.Forms.AnchorStyles.Left)
                   | System.Windows.Forms.AnchorStyles.Right)));
-      this.dataGridView1.AutoGenerateColumns = false;
-      this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
-      this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
-      this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
-            this.idDataGridViewTextBoxColumn1,
-            this.nameDataGridViewTextBoxColumn,
-            this.descriptionDataGridViewTextBoxColumn});
-      this.dataGridView1.DataSource = this.algorithmClassBindingSource;
-      this.dataGridView1.Location = new System.Drawing.Point(6, 6);
-      this.dataGridView1.Name = "dataGridView1";
-      this.dataGridView1.Size = new System.Drawing.Size(707, 368);
-      this.dataGridView1.TabIndex = 0;
-      this.dataGridView1.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellEndEdit);
-      this.dataGridView1.UserAddedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView1_UserAddedRow);
-      this.dataGridView1.UserDeletedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView1_UserDeletedRow);
+      this.tabControl.Controls.Add(this.algorithmClassesTabPage);
+      this.tabControl.Controls.Add(this.algorithmsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 0);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(727, 435);
+      this.tabControl.TabIndex = 2;
       // 
-      // idDataGridViewTextBoxColumn1
+      // algorithmClassesTabPage
       // 
-      this.idDataGridViewTextBoxColumn1.DataPropertyName = "Id";
-      this.idDataGridViewTextBoxColumn1.HeaderText = "Id";
-      this.idDataGridViewTextBoxColumn1.Name = "idDataGridViewTextBoxColumn1";
-      this.idDataGridViewTextBoxColumn1.ReadOnly = true;
-      this.idDataGridViewTextBoxColumn1.Width = 41;
+      this.algorithmClassesTabPage.Controls.Add(this.refreshAlgorithmClassesButton);
+      this.algorithmClassesTabPage.Controls.Add(this.algorithmClassCollectionView);
+      this.algorithmClassesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.algorithmClassesTabPage.Name = "algorithmClassesTabPage";
+      this.algorithmClassesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.algorithmClassesTabPage.Size = new System.Drawing.Size(719, 409);
+      this.algorithmClassesTabPage.TabIndex = 0;
+      this.algorithmClassesTabPage.Text = "Algorithm Classes";
+      this.algorithmClassesTabPage.UseVisualStyleBackColor = true;
       // 
-      // nameDataGridViewTextBoxColumn
+      // algorithmsTabPage
       // 
-      this.nameDataGridViewTextBoxColumn.DataPropertyName = "Name";
-      this.nameDataGridViewTextBoxColumn.HeaderText = "Name";
-      this.nameDataGridViewTextBoxColumn.Name = "nameDataGridViewTextBoxColumn";
-      this.nameDataGridViewTextBoxColumn.Width = 60;
+      this.algorithmsTabPage.Controls.Add(this.refreshAlgorithmsButton);
+      this.algorithmsTabPage.Controls.Add(this.algorithmCollectionView);
+      this.algorithmsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.algorithmsTabPage.Name = "algorithmsTabPage";
+      this.algorithmsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.algorithmsTabPage.Size = new System.Drawing.Size(719, 409);
+      this.algorithmsTabPage.TabIndex = 1;
+      this.algorithmsTabPage.Text = "Algorithms";
+      this.algorithmsTabPage.UseVisualStyleBackColor = true;
       // 
-      // descriptionDataGridViewTextBoxColumn
+      // refreshAlgorithmsButton
       // 
-      this.descriptionDataGridViewTextBoxColumn.DataPropertyName = "Description";
-      this.descriptionDataGridViewTextBoxColumn.HeaderText = "Description";
-      this.descriptionDataGridViewTextBoxColumn.Name = "descriptionDataGridViewTextBoxColumn";
-      this.descriptionDataGridViewTextBoxColumn.Width = 85;
+      this.refreshAlgorithmsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.refreshAlgorithmsButton.Location = new System.Drawing.Point(6, 380);
+      this.refreshAlgorithmsButton.Name = "refreshAlgorithmsButton";
+      this.refreshAlgorithmsButton.Size = new System.Drawing.Size(75, 23);
+      this.refreshAlgorithmsButton.TabIndex = 1;
+      this.refreshAlgorithmsButton.Text = "&Refresh";
+      this.refreshAlgorithmsButton.UseVisualStyleBackColor = true;
+      this.refreshAlgorithmsButton.Click += new System.EventHandler(this.refreshAlgorithmsButton_Click);
       // 
-      // algorithmClassBindingSource
+      // algorithmCollectionView
       // 
-      this.algorithmClassBindingSource.DataSource = typeof(HeuristicLab.Clients.OKB.OKBAdmin.AlgorithmClass);
-      this.algorithmClassBindingSource.Sort = "";
+      this.algorithmCollectionView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmCollectionView.Caption = "AlgorithmCollection View";
+      this.algorithmCollectionView.Content = null;
+      this.algorithmCollectionView.Location = new System.Drawing.Point(6, 6);
+      this.algorithmCollectionView.Name = "algorithmCollectionView";
+      this.algorithmCollectionView.ReadOnly = false;
+      this.algorithmCollectionView.Size = new System.Drawing.Size(707, 368);
+      this.algorithmCollectionView.TabIndex = 0;
       // 
-      // refreshButton
+      // algorithmClassCollectionView
       // 
-      this.refreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.refreshButton.Location = new System.Drawing.Point(6, 380);
-      this.refreshButton.Name = "refreshButton";
-      this.refreshButton.Size = new System.Drawing.Size(75, 23);
-      this.refreshButton.TabIndex = 1;
-      this.refreshButton.Text = "&Refresh";
-      this.refreshButton.UseVisualStyleBackColor = true;
-      this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
+      this.algorithmClassCollectionView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.algorithmClassCollectionView.Caption = "AlgorithmClassCollection View";
+      this.algorithmClassCollectionView.Content = null;
+      this.algorithmClassCollectionView.Location = new System.Drawing.Point(6, 6);
+      this.algorithmClassCollectionView.Name = "algorithmClassCollectionView";
+      this.algorithmClassCollectionView.ReadOnly = false;
+      this.algorithmClassCollectionView.Size = new System.Drawing.Size(707, 368);
+      this.algorithmClassCollectionView.TabIndex = 0;
       // 
-      // saveButton
+      // refreshAlgorithmClassesButton
       // 
-      this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.saveButton.Location = new System.Drawing.Point(87, 380);
-      this.saveButton.Name = "saveButton";
-      this.saveButton.Size = new System.Drawing.Size(75, 23);
-      this.saveButton.TabIndex = 1;
-      this.saveButton.Text = "&Save";
-      this.saveButton.UseVisualStyleBackColor = true;
-      this.saveButton.Click += new System.EventHandler(this.saveButton_Click);
-      // 
-      // tabControl1
-      // 
-      this.tabControl1.Controls.Add(this.tabPage1);
-      this.tabControl1.Controls.Add(this.tabPage2);
-      this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.tabControl1.Location = new System.Drawing.Point(0, 0);
-      this.tabControl1.Name = "tabControl1";
-      this.tabControl1.SelectedIndex = 0;
-      this.tabControl1.Size = new System.Drawing.Size(727, 435);
-      this.tabControl1.TabIndex = 2;
-      // 
-      // tabPage1
-      // 
-      this.tabPage1.Controls.Add(this.dataGridView1);
-      this.tabPage1.Controls.Add(this.refreshButton);
-      this.tabPage1.Controls.Add(this.populateButton);
-      this.tabPage1.Controls.Add(this.saveButton);
-      this.tabPage1.Location = new System.Drawing.Point(4, 22);
-      this.tabPage1.Name = "tabPage1";
-      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
-      this.tabPage1.Size = new System.Drawing.Size(719, 409);
-      this.tabPage1.TabIndex = 0;
-      this.tabPage1.Text = "tabPage1";
-      this.tabPage1.UseVisualStyleBackColor = true;
-      // 
-      // populateButton
-      // 
-      this.populateButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.populateButton.Location = new System.Drawing.Point(168, 380);
-      this.populateButton.Name = "populateButton";
-      this.populateButton.Size = new System.Drawing.Size(75, 23);
-      this.populateButton.TabIndex = 1;
-      this.populateButton.Text = "&Populate";
-      this.populateButton.UseVisualStyleBackColor = true;
-      this.populateButton.Click += new System.EventHandler(this.populateButton_Click);
-      // 
-      // tabPage2
-      // 
-      this.tabPage2.Controls.Add(this.dataGridView2);
-      this.tabPage2.Location = new System.Drawing.Point(4, 22);
-      this.tabPage2.Name = "tabPage2";
-      this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
-      this.tabPage2.Size = new System.Drawing.Size(719, 409);
-      this.tabPage2.TabIndex = 1;
-      this.tabPage2.Text = "tabPage2";
-      this.tabPage2.UseVisualStyleBackColor = true;
-      // 
-      // dataGridView2
-      // 
-      this.dataGridView2.AutoGenerateColumns = false;
-      this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
-      this.dataGridView2.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
-            this.idDataGridViewTextBoxColumn,
-            this.algorithmClassIdDataGridViewTextBoxColumn,
-            this.platformIdDataGridViewTextBoxColumn,
-            this.nameDataGridViewTextBoxColumn1,
-            this.descriptionDataGridViewTextBoxColumn1,
-            this.algorithmDataDataGridViewTextBoxColumn,
-            this.algorithmClassDataGridViewTextBoxColumn,
-            this.platformDataGridViewTextBoxColumn});
-      this.dataGridView2.DataSource = this.algorithmBindingSource;
-      this.dataGridView2.Location = new System.Drawing.Point(6, 6);
-      this.dataGridView2.Name = "dataGridView2";
-      this.dataGridView2.Size = new System.Drawing.Size(707, 344);
-      this.dataGridView2.TabIndex = 0;
-      // 
-      // idDataGridViewTextBoxColumn
-      // 
-      this.idDataGridViewTextBoxColumn.DataPropertyName = "Id";
-      this.idDataGridViewTextBoxColumn.HeaderText = "Id";
-      this.idDataGridViewTextBoxColumn.Name = "idDataGridViewTextBoxColumn";
-      // 
-      // algorithmClassIdDataGridViewTextBoxColumn
-      // 
-      this.algorithmClassIdDataGridViewTextBoxColumn.DataPropertyName = "AlgorithmClassId";
-      this.algorithmClassIdDataGridViewTextBoxColumn.HeaderText = "AlgorithmClassId";
-      this.algorithmClassIdDataGridViewTextBoxColumn.Name = "algorithmClassIdDataGridViewTextBoxColumn";
-      // 
-      // platformIdDataGridViewTextBoxColumn
-      // 
-      this.platformIdDataGridViewTextBoxColumn.DataPropertyName = "PlatformId";
-      this.platformIdDataGridViewTextBoxColumn.HeaderText = "PlatformId";
-      this.platformIdDataGridViewTextBoxColumn.Name = "platformIdDataGridViewTextBoxColumn";
-      // 
-      // nameDataGridViewTextBoxColumn1
-      // 
-      this.nameDataGridViewTextBoxColumn1.DataPropertyName = "Name";
-      this.nameDataGridViewTextBoxColumn1.HeaderText = "Name";
-      this.nameDataGridViewTextBoxColumn1.Name = "nameDataGridViewTextBoxColumn1";
-      // 
-      // descriptionDataGridViewTextBoxColumn1
-      // 
-      this.descriptionDataGridViewTextBoxColumn1.DataPropertyName = "Description";
-      this.descriptionDataGridViewTextBoxColumn1.HeaderText = "Description";
-      this.descriptionDataGridViewTextBoxColumn1.Name = "descriptionDataGridViewTextBoxColumn1";
-      // 
-      // algorithmDataDataGridViewTextBoxColumn
-      // 
-      this.algorithmDataDataGridViewTextBoxColumn.DataPropertyName = "AlgorithmData";
-      this.algorithmDataDataGridViewTextBoxColumn.HeaderText = "AlgorithmData";
-      this.algorithmDataDataGridViewTextBoxColumn.Name = "algorithmDataDataGridViewTextBoxColumn";
-      // 
-      // algorithmClassDataGridViewTextBoxColumn
-      // 
-      this.algorithmClassDataGridViewTextBoxColumn.DataPropertyName = "AlgorithmClass";
-      this.algorithmClassDataGridViewTextBoxColumn.HeaderText = "AlgorithmClass";
-      this.algorithmClassDataGridViewTextBoxColumn.Name = "algorithmClassDataGridViewTextBoxColumn";
-      // 
-      // platformDataGridViewTextBoxColumn
-      // 
-      this.platformDataGridViewTextBoxColumn.DataPropertyName = "Platform";
-      this.platformDataGridViewTextBoxColumn.HeaderText = "Platform";
-      this.platformDataGridViewTextBoxColumn.Name = "platformDataGridViewTextBoxColumn";
-      // 
-      // algorithmBindingSource
-      // 
-      this.algorithmBindingSource.DataSource = typeof(HeuristicLab.Clients.OKB.OKBAdmin.Algorithm);
+      this.refreshAlgorithmClassesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.refreshAlgorithmClassesButton.Location = new System.Drawing.Point(6, 380);
+      this.refreshAlgorithmClassesButton.Name = "refreshAlgorithmClassesButton";
+      this.refreshAlgorithmClassesButton.Size = new System.Drawing.Size(75, 23);
+      this.refreshAlgorithmClassesButton.TabIndex = 2;
+      this.refreshAlgorithmClassesButton.Text = "&Refresh";
+      this.refreshAlgorithmClassesButton.UseVisualStyleBackColor = true;
+      this.refreshAlgorithmClassesButton.Click += new System.EventHandler(this.refreshAlgorithmClassesButton_Click);
       // 
       // AdministrationView
@@ -268,14 +146,10 @@
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.Controls.Add(this.tabControl1);
+      this.Controls.Add(this.tabControl);
       this.Name = "AdministrationView";
       this.Size = new System.Drawing.Size(727, 435);
-      ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
-      ((System.ComponentModel.ISupportInitialize)(this.algorithmClassBindingSource)).EndInit();
-      this.tabControl1.ResumeLayout(false);
-      this.tabPage1.ResumeLayout(false);
-      this.tabPage2.ResumeLayout(false);
-      ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
-      ((System.ComponentModel.ISupportInitialize)(this.algorithmBindingSource)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.algorithmClassesTabPage.ResumeLayout(false);
+      this.algorithmsTabPage.ResumeLayout(false);
       this.ResumeLayout(false);
 
@@ -284,25 +158,11 @@
     #endregion
 
-    private System.Windows.Forms.DataGridView dataGridView1;
-    private System.Windows.Forms.Button refreshButton;
-    private System.Windows.Forms.Button saveButton;
-    private System.Windows.Forms.BindingSource algorithmClassBindingSource;
-    private System.Windows.Forms.TabControl tabControl1;
-    private System.Windows.Forms.TabPage tabPage1;
-    private System.Windows.Forms.TabPage tabPage2;
-    private System.Windows.Forms.DataGridView dataGridView2;
-    private System.Windows.Forms.DataGridViewTextBoxColumn idDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn algorithmClassIdDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn platformIdDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn1;
-    private System.Windows.Forms.DataGridViewTextBoxColumn descriptionDataGridViewTextBoxColumn1;
-    private System.Windows.Forms.DataGridViewTextBoxColumn algorithmDataDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn algorithmClassDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn platformDataGridViewTextBoxColumn;
-    private System.Windows.Forms.BindingSource algorithmBindingSource;
-    private System.Windows.Forms.Button populateButton;
-    private System.Windows.Forms.DataGridViewTextBoxColumn idDataGridViewTextBoxColumn1;
-    private System.Windows.Forms.DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn;
-    private System.Windows.Forms.DataGridViewTextBoxColumn descriptionDataGridViewTextBoxColumn;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage algorithmClassesTabPage;
+    private System.Windows.Forms.TabPage algorithmsTabPage;
+    private System.Windows.Forms.Button refreshAlgorithmsButton;
+    private AlgorithmCollectionView algorithmCollectionView;
+    private System.Windows.Forms.Button refreshAlgorithmClassesButton;
+    private AlgorithmClassCollectionView algorithmClassCollectionView;
 
   }
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.cs	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.cs	(revision 4408)
@@ -20,54 +20,38 @@
 #endregion
 
+using System;
 using System.Windows.Forms;
+using HeuristicLab.Clients.Common;
+using HeuristicLab.Clients.OKB.AdminService;
 using HeuristicLab.MainForm;
-using HeuristicLab.Clients.Common;
-using HeuristicLab.Clients.OKB.OKBAdmin;
-using System.ComponentModel;
-using System.Collections.Generic;
-using System.Data;
-using System;
+using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Clients.OKB {
   [View("OKB Administration")]
   public partial class AdministrationView : HeuristicLab.MainForm.WindowsForms.View {
-    List<AlgorithmClass> data;
-
     public AdministrationView() {
       InitializeComponent();
     }
 
-    private void refreshButton_Click(object sender, System.EventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-      data = adminService.GetAlgorithmClasses();
-      algorithmClassBindingSource.DataSource = data;
+    private void refreshAlgorithmClassesButton_Click(object sender, EventArgs e) {
+      using (AdminServiceClient adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>()) {
+        try {
+          algorithmClassCollectionView.Content = new EntityCollection<AlgorithmClass>(adminService.GetAlgorithmClasses());
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(ex);
+        }
+      }
     }
 
-    private void saveButton_Click(object sender, System.EventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-    }
-
-    private void populateButton_Click(object sender, System.EventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-      for (int i = 0; i < 100; i++)
-        adminService.AddAlgorithmClass(new AlgorithmClass() { Name = Guid.NewGuid().ToString() });
-    }
-
-    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-      adminService.UpdateAlgorithmClass(data[e.RowIndex]);
-    }
-
-    private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-      adminService.AddAlgorithmClass(new AlgorithmClass() {
-        Name = (string)e.Row.Cells["Name"].Value,
-        Description = (string)e.Row.Cells["Description"].Value
-      });
-    }
-
-    private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e) {
-      IAdminService adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>();
-      adminService.DeleteAlgorithmClass((long)e.Row.Cells["Id"].Value);
+    private void refreshAlgorithmsButton_Click(object sender, EventArgs e) {
+      using (AdminServiceClient adminService = ClientFactory.CreateClient<AdminServiceClient, IAdminService>()) {
+        try {
+          algorithmCollectionView.Content = new EntityCollection<Algorithm>(adminService.GetAlgorithms());
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(ex);
+        }
+      }
     }
   }
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.resx
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.resx	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AdministrationView.resx	(revision 4408)
@@ -118,12 +118,3 @@
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <metadata name="algorithmClassBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>17, 17</value>
-  </metadata>
-  <metadata name="algorithmBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>228, 17</value>
-  </metadata>
-  <metadata name="algorithmBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
-    <value>228, 17</value>
-  </metadata>
 </root>
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.Designer.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.Designer.cs	(revision 4408)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+namespace HeuristicLab.Clients.OKB {
+  partial class AlgorithmClassCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmClassCollectionView.cs	(revision 4408)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Windows.Forms;
+using HeuristicLab.Clients.OKB.AdminService;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Clients.OKB {
+  [View("AlgorithmClassCollection View")]
+  [Content(typeof(IEntityCollection<AlgorithmClass>), false)]
+  public partial class AlgorithmClassCollectionView : EntityCollectionView<AlgorithmClass> {
+    public AlgorithmClassCollectionView() {
+      InitializeComponent();
+      entitiesGroupBox.Text = "Algorithm Classes";
+    }
+
+    protected override AlgorithmClass CreateEntity() {
+      return new AlgorithmClass();
+    }
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.Designer.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.Designer.cs	(revision 4408)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+namespace HeuristicLab.Clients.OKB {
+  partial class AlgorithmCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/AlgorithmCollectionView.cs	(revision 4408)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Windows.Forms;
+using HeuristicLab.Clients.OKB.AdminService;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Clients.OKB {
+  [View("AlgorithmCollection View")]
+  [Content(typeof(IEntityCollection<Algorithm>), false)]
+  public partial class AlgorithmCollectionView : EntityCollectionView<Algorithm> {
+    public AlgorithmCollectionView() {
+      InitializeComponent();
+      entitiesGroupBox.Text = "Algorithms";
+    }
+
+    protected override Algorithm CreateEntity() {
+      return new Algorithm();
+    }
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollection.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollection.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollection.cs	(revision 4408)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Drawing;
+using HeuristicLab.Collections;
+
+namespace HeuristicLab.Clients.OKB.AdminService {
+  public class EntityCollection<T> : ObservableCollection<T>, IEntityCollection<T> where T : class, IEntity {
+    public virtual Image EntityImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Class; }
+    }
+
+    public EntityCollection() : base() { }
+    public EntityCollection(int capacity) : base(capacity) { }
+    public EntityCollection(IEnumerable<T> collection) : base(collection) { }
+
+    public new ReadOnlyEntityCollection<T> AsReadOnly() {
+      return new ReadOnlyEntityCollection<T>(this);
+    }
+
+    public override string ToString() {
+      return GetType().Name;
+    }
+
+    public event EventHandler EntityImageChanged;
+    protected virtual void OnEntityImageChanged() {
+      EventHandler handler = EntityImageChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ToStringChanged;
+    protected virtual void OnToStringChanged() {
+      EventHandler handler = ToStringChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.Designer.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.Designer.cs	(revision 4408)
@@ -0,0 +1,262 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Windows.Forms;
+
+namespace HeuristicLab.Clients.OKB {
+  partial class EntityCollectionView<T> {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
+        foreach (ListViewItem item in entitiesListView.Items) {
+          ((T)item.Tag).EntityImageChanged -= new EventHandler(Entity_EntityImageChanged);
+          ((T)item.Tag).ToStringChanged -= new EventHandler(Entity_ToStringChanged);
+        }
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.entitiesListView = new System.Windows.Forms.ListView();
+      this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.imageList = new System.Windows.Forms.ImageList(this.components);
+      this.sortDescendingButton = new System.Windows.Forms.Button();
+      this.sortAscendingButton = new System.Windows.Forms.Button();
+      this.removeButton = new System.Windows.Forms.Button();
+      this.addButton = new System.Windows.Forms.Button();
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.entitiesGroupBox = new System.Windows.Forms.GroupBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.showDetailsCheckBox = new System.Windows.Forms.CheckBox();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.entitiesGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.Location = new System.Drawing.Point(3, 16);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.showDetailsCheckBox);
+      this.splitContainer.Panel1.Controls.Add(this.entitiesListView);
+      this.splitContainer.Panel1.Controls.Add(this.sortDescendingButton);
+      this.splitContainer.Panel1.Controls.Add(this.sortAscendingButton);
+      this.splitContainer.Panel1.Controls.Add(this.removeButton);
+      this.splitContainer.Panel1.Controls.Add(this.addButton);
+      this.splitContainer.Panel1MinSize = 100;
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.detailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(526, 364);
+      this.splitContainer.SplitterDistance = 250;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // entitiessListView
+      // 
+      this.entitiesListView.AllowDrop = true;
+      this.entitiesListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.entitiesListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.columnHeader1});
+      this.entitiesListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
+      this.entitiesListView.HideSelection = false;
+      this.entitiesListView.Location = new System.Drawing.Point(3, 33);
+      this.entitiesListView.Name = "entitiessListView";
+      this.entitiesListView.ShowItemToolTips = true;
+      this.entitiesListView.Size = new System.Drawing.Size(244, 327);
+      this.entitiesListView.SmallImageList = this.imageList;
+      this.entitiesListView.TabIndex = 5;
+      this.entitiesListView.UseCompatibleStateImageBehavior = false;
+      this.entitiesListView.View = System.Windows.Forms.View.Details;
+      this.entitiesListView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.entitiesListView_ItemDrag);
+      this.entitiesListView.SelectedIndexChanged += new System.EventHandler(this.entitiesListView_SelectedIndexChanged);
+      this.entitiesListView.DragDrop += new System.Windows.Forms.DragEventHandler(this.entitiesListView_DragDrop);
+      this.entitiesListView.DragEnter += new System.Windows.Forms.DragEventHandler(this.entitiesListView_DragEnterOver);
+      this.entitiesListView.DragOver += new System.Windows.Forms.DragEventHandler(this.entitiesListView_DragEnterOver);
+      this.entitiesListView.DoubleClick += new System.EventHandler(this.entitiesListView_DoubleClick);
+      this.entitiesListView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.entitiesListView_KeyDown);
+      // 
+      // imageList
+      // 
+      this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
+      this.imageList.ImageSize = new System.Drawing.Size(16, 16);
+      this.imageList.TransparentColor = System.Drawing.Color.Transparent;
+      // 
+      // sortDescendingButton
+      // 
+      this.sortDescendingButton.Enabled = false;
+      this.sortDescendingButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.SortUp;
+      this.sortDescendingButton.Location = new System.Drawing.Point(33, 3);
+      this.sortDescendingButton.Name = "sortDescendingButton";
+      this.sortDescendingButton.Size = new System.Drawing.Size(24, 24);
+      this.sortDescendingButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.sortDescendingButton, "Sort Descending");
+      this.sortDescendingButton.UseVisualStyleBackColor = true;
+      this.sortDescendingButton.Click += new System.EventHandler(this.sortDescendingButton_Click);
+      // 
+      // sortAscendingButton
+      // 
+      this.sortAscendingButton.Enabled = false;
+      this.sortAscendingButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Sort;
+      this.sortAscendingButton.Location = new System.Drawing.Point(63, 3);
+      this.sortAscendingButton.Name = "sortAscendingButton";
+      this.sortAscendingButton.Size = new System.Drawing.Size(24, 24);
+      this.sortAscendingButton.TabIndex = 2;
+      this.toolTip.SetToolTip(this.sortAscendingButton, "Sort Ascending");
+      this.sortAscendingButton.UseVisualStyleBackColor = true;
+      this.sortAscendingButton.Click += new System.EventHandler(this.sortAscendingButton_Click);
+      // 
+      // removeButton
+      // 
+      this.removeButton.Enabled = false;
+      this.removeButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Remove;
+      this.removeButton.Location = new System.Drawing.Point(93, 3);
+      this.removeButton.Name = "removeButton";
+      this.removeButton.Size = new System.Drawing.Size(24, 24);
+      this.removeButton.TabIndex = 3;
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      this.removeButton.UseVisualStyleBackColor = true;
+      this.removeButton.Click += new System.EventHandler(this.removeButton_Click);
+      // 
+      // addButton
+      // 
+      this.addButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Add;
+      this.addButton.Location = new System.Drawing.Point(3, 3);
+      this.addButton.Name = "addButton";
+      this.addButton.Size = new System.Drawing.Size(24, 24);
+      this.addButton.TabIndex = 0;
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      this.addButton.UseVisualStyleBackColor = true;
+      this.addButton.Click += new System.EventHandler(this.addButton_Click);
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.detailsGroupBox.Controls.Add(this.viewHost);
+      this.detailsGroupBox.Location = new System.Drawing.Point(3, 27);
+      this.detailsGroupBox.Name = "detailsGroupBox";
+      this.detailsGroupBox.Size = new System.Drawing.Size(266, 335);
+      this.detailsGroupBox.TabIndex = 0;
+      this.detailsGroupBox.TabStop = false;
+      this.detailsGroupBox.Text = "Details";
+      // 
+      // viewHost
+      // 
+      this.viewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Location = new System.Drawing.Point(6, 19);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = false;
+      this.viewHost.Size = new System.Drawing.Size(254, 310);
+      this.viewHost.TabIndex = 0;
+      this.viewHost.ViewType = null;
+      // 
+      // entitiesGroupBox
+      // 
+      this.entitiesGroupBox.Controls.Add(this.splitContainer);
+      this.entitiesGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.entitiesGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.entitiesGroupBox.Name = "entitiesGroupBox";
+      this.entitiesGroupBox.Size = new System.Drawing.Size(532, 383);
+      this.entitiesGroupBox.TabIndex = 0;
+      this.entitiesGroupBox.TabStop = false;
+      this.entitiesGroupBox.Text = "Entities";
+      // 
+      // showDetailsCheckBox
+      // 
+      this.showDetailsCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.showDetailsCheckBox.Checked = true;
+      this.showDetailsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showDetailsCheckBox.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Properties;
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(123, 3);
+      this.showDetailsCheckBox.Name = "showDetailsCheckBox";
+      this.showDetailsCheckBox.Size = new System.Drawing.Size(24, 24);
+      this.showDetailsCheckBox.TabIndex = 4;
+      this.toolTip.SetToolTip(this.showDetailsCheckBox, "Show/Hide Details");
+      this.showDetailsCheckBox.UseVisualStyleBackColor = true;
+      this.showDetailsCheckBox.CheckedChanged += new System.EventHandler(this.showDetailsCheckBox_CheckedChanged);
+      // 
+      // EntityCollectionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Controls.Add(this.entitiesGroupBox);
+      this.Name = "EntityCollectionView";
+      this.Size = new System.Drawing.Size(532, 383);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.entitiesGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.SplitContainer splitContainer;
+    protected System.Windows.Forms.ColumnHeader columnHeader1;
+    protected GroupBox entitiesGroupBox;
+    protected ListView entitiesListView;
+    protected GroupBox detailsGroupBox;
+    protected Button addButton;
+    protected Button removeButton;
+    protected ToolTip toolTip;
+    protected ImageList imageList;
+    protected HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
+    protected Button sortAscendingButton;
+    protected Button sortDescendingButton;
+    protected CheckBox showDetailsCheckBox;
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityCollectionView.cs	(revision 4408)
@@ -0,0 +1,334 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Windows.Forms;
+using HeuristicLab.Clients.OKB.AdminService;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Clients.OKB {
+  [View("EntityCollection View")]
+  [Content(typeof(EntityCollection<>), true)]
+  [Content(typeof(IEntityCollection<>), false)]
+  public partial class EntityCollectionView<T> : EntityView where T : class, IEntity {
+    protected TypeSelectorDialog typeSelectorDialog;
+
+    public new IEntityCollection<T> Content {
+      get { return (IEntityCollection<T>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ListView EntitiesListView {
+      get { return entitiesListView; }
+    }
+
+    public EntityCollectionView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
+      Content.CollectionReset -= new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded);
+      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved);
+      Content.CollectionReset += new CollectionItemsChangedEventHandler<T>(Content_CollectionReset);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      while (entitiesListView.Items.Count > 0) RemoveListViewItem(entitiesListView.Items[0]);
+      viewHost.Content = null;
+      if (Content != null) {
+        Caption += " (" + Content.GetType().Name + ")";
+        foreach (T entity in Content)
+          AddListViewItem(CreateListViewItem(entity));
+        AdjustListViewColumnSizes();
+        SortItemsListView(SortOrder.Ascending);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      if (Content == null) {
+        addButton.Enabled = false;
+        sortAscendingButton.Enabled = false;
+        sortDescendingButton.Enabled = false;
+        removeButton.Enabled = false;
+        entitiesListView.Enabled = false;
+        detailsGroupBox.Enabled = false;
+      } else {
+        addButton.Enabled = !Content.IsReadOnly && !ReadOnly;
+        sortAscendingButton.Enabled = entitiesListView.Items.Count > 1;
+        sortDescendingButton.Enabled = entitiesListView.Items.Count > 1;
+        removeButton.Enabled = !Content.IsReadOnly && !ReadOnly && entitiesListView.SelectedItems.Count > 0;
+        entitiesListView.Enabled = true;
+        detailsGroupBox.Enabled = entitiesListView.SelectedItems.Count == 1;
+      }
+    }
+
+    protected virtual T CreateEntity() {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select Entity";
+        typeSelectorDialog.TypeSelector.Caption = "Available Entities";
+        typeSelectorDialog.TypeSelector.Configure(typeof(T), false, true);
+      }
+
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          return (T)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+      return null;
+    }
+    protected virtual ListViewItem CreateListViewItem(T entity) {
+      ListViewItem listViewItem = new ListViewItem();
+      listViewItem.Text = entity.ToString();
+//TODO      listViewItem.ToolTipText = entity.ItemName + ": " + entity.ItemDescription;
+      listViewItem.Tag = entity;
+      entitiesListView.SmallImageList.Images.Add(entity.EntityImage);
+      listViewItem.ImageIndex = entitiesListView.SmallImageList.Images.Count - 1;
+      return listViewItem;
+    }
+    protected virtual void AddListViewItem(ListViewItem listViewItem) {
+      entitiesListView.Items.Add(listViewItem);
+      ((T)listViewItem.Tag).EntityImageChanged += new EventHandler(Entity_EntityImageChanged);
+      ((T)listViewItem.Tag).ToStringChanged += new EventHandler(Entity_ToStringChanged);
+      sortAscendingButton.Enabled = entitiesListView.Items.Count > 1;
+      sortDescendingButton.Enabled = entitiesListView.Items.Count > 1;
+    }
+    protected virtual void RemoveListViewItem(ListViewItem listViewItem) {
+      ((T)listViewItem.Tag).EntityImageChanged -= new EventHandler(Entity_EntityImageChanged);
+      ((T)listViewItem.Tag).ToStringChanged -= new EventHandler(Entity_ToStringChanged);
+      listViewItem.Remove();
+      foreach (ListViewItem other in entitiesListView.Items)
+        if (other.ImageIndex > listViewItem.ImageIndex) other.ImageIndex--;
+      entitiesListView.SmallImageList.Images.RemoveAt(listViewItem.ImageIndex);
+      sortAscendingButton.Enabled = entitiesListView.Items.Count > 1;
+      sortDescendingButton.Enabled = entitiesListView.Items.Count > 1;
+    }
+    protected virtual void UpdateListViewItemImage(ListViewItem listViewItem) {
+      int i = listViewItem.ImageIndex;
+      listViewItem.ImageList.Images[i] = ((T)listViewItem.Tag).EntityImage;
+      listViewItem.ImageIndex = -1;
+      listViewItem.ImageIndex = i;
+    }
+    protected virtual void UpdateListViewItemText(ListViewItem listViewItem) {
+      if (!listViewItem.Text.Equals(listViewItem.Tag.ToString()))
+        listViewItem.Text = listViewItem.Tag.ToString();
+    }
+    protected virtual IEnumerable<ListViewItem> GetListViewItemsForEntity(T entity) {
+      foreach (ListViewItem listViewItem in entitiesListView.Items) {
+        if (((T)listViewItem.Tag) == entity)
+          yield return listViewItem;
+      }
+    }
+
+    #region ListView Events
+    protected virtual void entitiesListView_SelectedIndexChanged(object sender, EventArgs e) {
+      removeButton.Enabled = (Content != null) && !Content.IsReadOnly && !ReadOnly && entitiesListView.SelectedItems.Count > 0;
+      AdjustListViewColumnSizes();
+      if (showDetailsCheckBox.Checked) {
+        if (entitiesListView.SelectedItems.Count == 1) {
+          T entity = (T)entitiesListView.SelectedItems[0].Tag;
+          detailsGroupBox.Enabled = true;
+          viewHost.Content = entity;
+        } else {
+          viewHost.Content = null;
+          detailsGroupBox.Enabled = false;
+        }
+      }
+    }
+    protected virtual void entitiesListView_KeyDown(object sender, KeyEventArgs e) {
+      if (e.KeyCode == Keys.Delete) {
+        if ((entitiesListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
+          foreach (ListViewItem item in entitiesListView.SelectedItems)
+            Content.Remove((T)item.Tag);
+        }
+      }
+    }
+    protected virtual void entitiesListView_DoubleClick(object sender, EventArgs e) {
+      if (entitiesListView.SelectedItems.Count == 1) {
+        T entity = (T)entitiesListView.SelectedItems[0].Tag;
+        IContentView view = MainFormManager.MainForm.ShowContent(entity);
+        if (view != null) {
+          view.ReadOnly = ReadOnly;
+          view.Locked = Locked;
+        }
+      }
+    }
+    protected virtual void entitiesListView_ItemDrag(object sender, ItemDragEventArgs e) {
+      if (!Locked) {
+        ListViewItem listViewItem = (ListViewItem)e.Item;
+        T entity = (T)listViewItem.Tag;
+        DataObject data = new DataObject();
+        data.SetData("Type", entity.GetType());
+        data.SetData("Value", entity);
+        if (Content.IsReadOnly || ReadOnly) {
+          DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
+        } else {
+          DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
+          if ((result & DragDropEffects.Move) == DragDropEffects.Move)
+            Content.Remove(entity);
+        }
+      }
+    }
+    protected virtual void entitiesListView_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      Type type = e.Data.GetData("Type") as Type;
+      if (!Content.IsReadOnly && !ReadOnly && (type != null) && (typeof(T).IsAssignableFrom(type))) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy) e.Effect = DragDropEffects.Copy;
+        else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) e.Effect = DragDropEffects.Move;
+        else if ((e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link) e.Effect = DragDropEffects.Link;
+      }
+    }
+    protected virtual void entitiesListView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        T entity = e.Data.GetData("Value") as T;
+//TODO        if ((e.Effect & DragDropEffects.Copy) == DragDropEffects.Copy) entity = (T)entity.Clone();
+        Content.Add(entity);
+      }
+    }
+    #endregion
+
+    #region Button Events
+    protected virtual void addButton_Click(object sender, EventArgs e) {
+      T entity = CreateEntity();
+      if (entity != null)
+        Content.Add(entity);
+    }
+    protected virtual void sortAscendingButton_Click(object sender, EventArgs e) {
+      SortItemsListView(SortOrder.Ascending);
+    }
+    protected virtual void sortDescendingButton_Click(object sender, EventArgs e) {
+      SortItemsListView(SortOrder.Descending);
+    }
+    protected virtual void removeButton_Click(object sender, EventArgs e) {
+      if (entitiesListView.SelectedItems.Count > 0) {
+        foreach (ListViewItem item in entitiesListView.SelectedItems)
+          Content.Remove((T)item.Tag);
+        entitiesListView.SelectedItems.Clear();
+      }
+    }
+    #endregion
+
+    #region CheckBox Events
+    protected virtual void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = entitiesListView.SelectedItems.Count == 1;
+        viewHost.Content = entitiesListView.SelectedItems.Count == 1 ? (T)entitiesListView.SelectedItems[0].Tag : null;
+      } else {
+        splitContainer.Panel2Collapsed = true;
+        viewHost.Content = null;
+      }
+    }
+    #endregion
+
+    #region Content Events
+    protected virtual void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsAdded), sender, e);
+      else {
+        foreach (T item in e.Items)
+          AddListViewItem(CreateListViewItem(item));
+        AdjustListViewColumnSizes();
+      }
+
+    }
+    protected virtual void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_ItemsRemoved), sender, e);
+      else {
+        foreach (T item in e.Items) {
+          // remove only the first matching ListViewItem, because the IEntity could be contained multiple times in the EntityCollection
+          ListViewItem listviewItem = GetListViewItemsForEntity(item).FirstOrDefault();
+          if (listviewItem != null) RemoveListViewItem(listviewItem);
+        }
+      }
+    }
+    protected virtual void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<T> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<T>(Content_CollectionReset), sender, e);
+      else {
+        foreach (T item in e.OldItems) {
+          // remove only the first matching ListViewItem, because the IEntity could be contained multiple times in the EntityCollection
+          ListViewItem listviewItem = GetListViewItemsForEntity(item).FirstOrDefault();
+          if (listviewItem != null) RemoveListViewItem(listviewItem);
+        }
+        foreach (T item in e.Items)
+          AddListViewItem(CreateListViewItem(item));
+      }
+    }
+    #endregion
+
+    #region Entity Events
+    protected virtual void Entity_EntityImageChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Entity_EntityImageChanged), sender, e);
+      else {
+        T item = (T)sender;
+        foreach (ListViewItem listViewItem in GetListViewItemsForEntity(item))
+          UpdateListViewItemImage(listViewItem);
+      }
+    }
+    protected virtual void Entity_ToStringChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Entity_ToStringChanged), sender, e);
+      else {
+        T item = (T)sender;
+        foreach (ListViewItem listViewItem in GetListViewItemsForEntity(item))
+          UpdateListViewItemText(listViewItem);
+      }
+    }
+    #endregion
+
+    #region Helpers
+    protected virtual void SortItemsListView(SortOrder sortOrder) {
+      entitiesListView.Sorting = SortOrder.None;
+      entitiesListView.Sorting = sortOrder;
+      entitiesListView.Sorting = SortOrder.None;
+    }
+    protected virtual void AdjustListViewColumnSizes() {
+      if (entitiesListView.Items.Count > 0) {
+        for (int i = 0; i < entitiesListView.Columns.Count; i++)
+          entitiesListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+      }
+    }
+    #endregion
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.Designer.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.Designer.cs	(revision 4408)
@@ -0,0 +1,53 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+namespace HeuristicLab.Clients.OKB {
+  partial class EntityView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/EntityView.cs	(revision 4408)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Clients.OKB.AdminService;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Clients.OKB {
+  public partial class EntityView : AsynchronousContentView {
+    public new IEntity Content {
+      get { return (IEntity)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public EntityView() {
+      InitializeComponent();
+    }
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/Extensions.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/Extensions.cs	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/Extensions.cs	(revision 4408)
@@ -20,8 +20,56 @@
 #endregion
 
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
 using HeuristicLab.Common;
 
 namespace HeuristicLab.Clients.OKB.AdminService {
-  public partial class AlgorithmClass : IContent { }
-  public partial class Algorithm : IContent { }
+  public interface IEntity : IContent, INotifyPropertyChanged {
+    Image EntityImage { get; }
+
+    event EventHandler EntityImageChanged;
+    event EventHandler ToStringChanged;
+  }
+
+  public interface INamedEntity : IEntity {
+    string Name { get; set; }
+    string Description { get; set; }
+  }
+
+  public interface IEntityCollection<T> : IObservableCollection<T>, IEntity where T : class, IEntity { }
+
+  public partial class AlgorithmClass : INamedEntity {
+    public Image EntityImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Class; }
+    }
+
+    public event EventHandler EntityImageChanged;
+    protected virtual void OnEntityImageChanged() {
+      EventHandler handler = EntityImageChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ToStringChanged;
+    protected virtual void OnToStringChanged() {
+      EventHandler handler = ToStringChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+  public partial class Algorithm : INamedEntity {
+    public Image EntityImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Class; }
+    }
+
+    public event EventHandler EntityImageChanged;
+    protected virtual void OnEntityImageChanged() {
+      EventHandler handler = EntityImageChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ToStringChanged;
+    protected virtual void OnToStringChanged() {
+      EventHandler handler = ToStringChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
 }
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLab.Clients.OKB-3.3.csproj
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLab.Clients.OKB-3.3.csproj	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLab.Clients.OKB-3.3.csproj	(revision 4408)
@@ -39,7 +39,10 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="HeuristicLab.Clients.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Clients.Common-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Clients.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
-    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.2.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.MainForm-3.3">
@@ -68,4 +71,10 @@
   <ItemGroup>
     <Compile Include="AdministrationMenuItem.cs" />
+    <Compile Include="AlgorithmCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlgorithmCollectionView.Designer.cs">
+      <DependentUpon>AlgorithmCollectionView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Extensions.cs" />
     <Compile Include="HeuristicLabClientsOKBPlugin.cs" />
@@ -76,5 +85,31 @@
       <DependentUpon>AdministrationView.cs</DependentUpon>
     </Compile>
+    <Compile Include="EntityCollection.cs" />
+    <Compile Include="EntityCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="EntityCollectionView.Designer.cs">
+      <DependentUpon>EntityCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="EntityView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="EntityView.Designer.cs">
+      <DependentUpon>EntityView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="NamedEntityView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="NamedEntityView.Designer.cs">
+      <DependentUpon>NamedEntityView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AlgorithmClassCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlgorithmClassCollectionView.Designer.cs">
+      <DependentUpon>AlgorithmClassCollectionView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ReadOnlyEntityCollection.cs" />
     <Compile Include="Service References\AdminService\Reference.cs">
       <AutoGen>True</AutoGen>
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLabClientsOKBPlugin.cs.frame
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLabClientsOKBPlugin.cs.frame	(revision 4405)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/HeuristicLabClientsOKBPlugin.cs.frame	(revision 4408)
@@ -28,4 +28,9 @@
   [Plugin("HeuristicLab.Clients.OKB", "3.3.0.$WCREV$")]
   [PluginFile("HeuristicLab.Clients.OKB-3.3.dll", PluginFileType.Assembly)]  
+  [PluginDependency("HeuristicLab.Clients.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
   [PluginDependency("HeuristicLab.MainForm", "3.3")]
   [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.Designer.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.Designer.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.Designer.cs	(revision 4408)
@@ -0,0 +1,119 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+namespace HeuristicLab.Clients.OKB {
+  partial class NamedEntityView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.nameLabel = new System.Windows.Forms.Label();
+      this.nameTextBox = new System.Windows.Forms.TextBox();
+      this.descriptionLabel = new System.Windows.Forms.Label();
+      this.descriptionTextBox = new System.Windows.Forms.TextBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.SuspendLayout();
+      // 
+      // nameLabel
+      // 
+      this.nameLabel.AutoSize = true;
+      this.nameLabel.Location = new System.Drawing.Point(3, 3);
+      this.nameLabel.Name = "nameLabel";
+      this.nameLabel.Size = new System.Drawing.Size(38, 13);
+      this.nameLabel.TabIndex = 0;
+      this.nameLabel.Text = "&Name:";
+      // 
+      // nameTextBox
+      // 
+      this.nameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.nameTextBox.Location = new System.Drawing.Point(72, 0);
+      this.nameTextBox.Name = "nameTextBox";
+      this.nameTextBox.Size = new System.Drawing.Size(279, 20);
+      this.nameTextBox.TabIndex = 1;
+      this.nameTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.nameTextBox_KeyDown);
+      this.nameTextBox.Validated += new System.EventHandler(this.nameTextBox_Validated);
+      // 
+      // descriptionLabel
+      // 
+      this.descriptionLabel.AutoSize = true;
+      this.descriptionLabel.Location = new System.Drawing.Point(3, 29);
+      this.descriptionLabel.Name = "descriptionLabel";
+      this.descriptionLabel.Size = new System.Drawing.Size(63, 13);
+      this.descriptionLabel.TabIndex = 2;
+      this.descriptionLabel.Text = "&Description:";
+      // 
+      // descriptionTextBox
+      // 
+      this.descriptionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.descriptionTextBox.Location = new System.Drawing.Point(72, 26);
+      this.descriptionTextBox.Name = "descriptionTextBox";
+      this.descriptionTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+      this.descriptionTextBox.Size = new System.Drawing.Size(279, 20);
+      this.descriptionTextBox.TabIndex = 3;
+      this.descriptionTextBox.DoubleClick += new System.EventHandler(this.descriptionTextBox_DoubleClick);
+      this.descriptionTextBox.Validated += new System.EventHandler(this.descriptionTextBox_Validated);
+      // 
+      // NamedEntityView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.descriptionTextBox);
+      this.Controls.Add(this.nameTextBox);
+      this.Controls.Add(this.descriptionLabel);
+      this.Controls.Add(this.nameLabel);
+      this.Name = "NamedEntityView";
+      this.Size = new System.Drawing.Size(351, 52);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.TextBox nameTextBox;
+    protected System.Windows.Forms.Label nameLabel;
+    protected System.Windows.Forms.Label descriptionLabel;
+    protected System.Windows.Forms.TextBox descriptionTextBox;
+    protected System.Windows.Forms.ToolTip toolTip;
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/NamedEntityView.cs	(revision 4408)
@@ -0,0 +1,124 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.ComponentModel;
+using System.Windows.Forms;
+using HeuristicLab.Clients.OKB.AdminService;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Clients.OKB {
+  [View("NamedEntoty View")]
+  [Content(typeof(INamedEntity), false)]
+  public partial class NamedEntityView : EntityView {
+    public new INamedEntity Content {
+      get { return (INamedEntity)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public NamedEntityView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.PropertyChanged -= new PropertyChangedEventHandler(Content_PropertyChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PropertyChanged += new PropertyChangedEventHandler(Content_PropertyChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        nameTextBox.Text = string.Empty;
+        descriptionTextBox.Text = string.Empty;
+        toolTip.SetToolTip(descriptionTextBox, string.Empty);
+        if (ViewAttribute.HasViewAttribute(this.GetType()))
+          this.Caption = ViewAttribute.GetViewName(this.GetType());
+        else
+          this.Caption = "NamedEntity View";
+      } else {
+        nameTextBox.Text = Content.Name;
+        descriptionTextBox.Text = Content.Description;
+        toolTip.SetToolTip(descriptionTextBox, Content.Description);
+        Caption = Content.Name;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      if (Content == null) {
+        nameTextBox.Enabled = false;
+        descriptionTextBox.Enabled = false;
+      } else {
+        nameTextBox.Enabled = true;
+        nameTextBox.ReadOnly = ReadOnly;
+        descriptionTextBox.Enabled = true;
+        descriptionTextBox.ReadOnly = ReadOnly;
+      }
+    }
+
+    protected virtual void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (InvokeRequired)
+        Invoke(new PropertyChangedEventHandler(Content_PropertyChanged), sender, e);
+      else {
+        switch (e.PropertyName) {
+          case "Name":
+            nameTextBox.Text = Content.Name;
+            Caption = Content.Name;
+            break;
+          case "Description":
+            descriptionTextBox.Text = Content.Description;
+            toolTip.SetToolTip(descriptionTextBox, Content.Description);
+            break;
+        }
+        nameTextBox.Text = Content.Name;
+        Caption = Content.Name;
+      }
+    }
+
+    protected virtual void nameTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        nameLabel.Focus();  // set focus on label to validate data
+      if (e.KeyCode == Keys.Escape) {
+        nameTextBox.Text = Content.Name;
+        nameLabel.Focus();  // set focus on label to validate data
+      }
+    }
+    protected virtual void nameTextBox_Validated(object sender, EventArgs e) {
+      Content.Name = nameTextBox.Text;
+    }
+    protected virtual void descriptionTextBox_Validated(object sender, EventArgs e) {
+      Content.Description = descriptionTextBox.Text;
+    }
+
+    protected void descriptionTextBox_DoubleClick(object sender, EventArgs e) {
+      using (TextDialog dialog = new TextDialog("Description of " + Content.Name, descriptionTextBox.Text, ReadOnly)) {
+        if (dialog.ShowDialog(this) == DialogResult.OK)
+          Content.Description = dialog.Content;
+      }
+    }
+  }
+}
Index: branches/OKB/HeuristicLab.Clients.OKB-3.3/ReadOnlyEntityCollection.cs
===================================================================
--- branches/OKB/HeuristicLab.Clients.OKB-3.3/ReadOnlyEntityCollection.cs	(revision 4408)
+++ branches/OKB/HeuristicLab.Clients.OKB-3.3/ReadOnlyEntityCollection.cs	(revision 4408)
@@ -0,0 +1,50 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Drawing;
+using HeuristicLab.Collections;
+
+namespace HeuristicLab.Clients.OKB.AdminService {
+  public class ReadOnlyEntityCollection<T> : ReadOnlyObservableCollection<T>, IEntityCollection<T> where T : class, IEntity {
+    public virtual Image EntityImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Class; }
+    }
+
+    public ReadOnlyEntityCollection() : base(new EntityCollection<T>()) { }
+    public ReadOnlyEntityCollection(IEntityCollection<T> collection) : base(collection) { }
+
+    public override string ToString() {
+      return GetType().Name;
+    }
+
+    public event EventHandler EntityImageChanged;
+    protected virtual void OnEntityImageChanged() {
+      EventHandler handler = EntityImageChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ToStringChanged;
+    protected virtual void OnToStringChanged() {
+      EventHandler handler = ToStringChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
