Index: /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.Designer.cs	(revision 13539)
+++ /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.Designer.cs	(revision 13540)
@@ -51,13 +51,21 @@
       this.tabControl = new System.Windows.Forms.TabControl();
       this.parametersTabPage = new System.Windows.Forms.TabPage();
+      this.parameterCollectionView = new HeuristicLab.Core.Views.ParameterCollectionView();
       this.characteristicsTabPage = new System.Windows.Forms.TabPage();
-      this.parameterCollectionView = new HeuristicLab.Core.Views.ParameterCollectionView();
+      this.characteristicSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.calculatorListView = new System.Windows.Forms.ListView();
+      this.characteristicColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.calculateButton = new System.Windows.Forms.Button();
+      this.characteristicsMatrixView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
+      this.uploadCharacteristicsButton = new System.Windows.Forms.Button();
       this.downloadCharacteristicsButton = new System.Windows.Forms.Button();
-      this.uploadCharacteristicsButton = new System.Windows.Forms.Button();
-      this.characteristicsMatrixView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.tabControl.SuspendLayout();
       this.parametersTabPage.SuspendLayout();
       this.characteristicsTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.characteristicSplitContainer)).BeginInit();
+      this.characteristicSplitContainer.Panel1.SuspendLayout();
+      this.characteristicSplitContainer.Panel2.SuspendLayout();
+      this.characteristicSplitContainer.SuspendLayout();
       this.SuspendLayout();
       // 
@@ -82,5 +90,5 @@
       // problemComboBox
       // 
-      this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+      this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
@@ -104,5 +112,4 @@
       // 
       this.refreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.refreshButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Refresh;
       this.refreshButton.Location = new System.Drawing.Point(682, -1);
       this.refreshButton.Name = "refreshButton";
@@ -116,5 +123,4 @@
       // 
       this.cloneProblemButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.cloneProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Clone;
       this.cloneProblemButton.Location = new System.Drawing.Point(652, -1);
       this.cloneProblemButton.Name = "cloneProblemButton";
@@ -127,6 +133,6 @@
       // tabControl
       // 
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      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.tabControl.Controls.Add(this.parametersTabPage);
@@ -148,17 +154,4 @@
       this.parametersTabPage.Text = "Parameters";
       this.parametersTabPage.UseVisualStyleBackColor = true;
-      // 
-      // characteristicsTabPage
-      // 
-      this.characteristicsTabPage.Controls.Add(this.characteristicsMatrixView);
-      this.characteristicsTabPage.Controls.Add(this.uploadCharacteristicsButton);
-      this.characteristicsTabPage.Controls.Add(this.downloadCharacteristicsButton);
-      this.characteristicsTabPage.Location = new System.Drawing.Point(4, 22);
-      this.characteristicsTabPage.Name = "characteristicsTabPage";
-      this.characteristicsTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.characteristicsTabPage.Size = new System.Drawing.Size(692, 314);
-      this.characteristicsTabPage.TabIndex = 1;
-      this.characteristicsTabPage.Text = "Characteristics";
-      this.characteristicsTabPage.UseVisualStyleBackColor = true;
       // 
       // parameterCollectionView
@@ -175,4 +168,93 @@
       this.parameterCollectionView.TabIndex = 8;
       // 
+      // characteristicsTabPage
+      // 
+      this.characteristicsTabPage.Controls.Add(this.characteristicSplitContainer);
+      this.characteristicsTabPage.Controls.Add(this.uploadCharacteristicsButton);
+      this.characteristicsTabPage.Controls.Add(this.downloadCharacteristicsButton);
+      this.characteristicsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.characteristicsTabPage.Name = "characteristicsTabPage";
+      this.characteristicsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.characteristicsTabPage.Size = new System.Drawing.Size(692, 314);
+      this.characteristicsTabPage.TabIndex = 1;
+      this.characteristicsTabPage.Text = "Characteristics";
+      this.characteristicsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // characteristicSplitContainer
+      // 
+      this.characteristicSplitContainer.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.characteristicSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.characteristicSplitContainer.Location = new System.Drawing.Point(0, 35);
+      this.characteristicSplitContainer.Name = "characteristicSplitContainer";
+      // 
+      // characteristicSplitContainer.Panel1
+      // 
+      this.characteristicSplitContainer.Panel1.Controls.Add(this.calculatorListView);
+      this.characteristicSplitContainer.Panel1.Controls.Add(this.calculateButton);
+      // 
+      // characteristicSplitContainer.Panel2
+      // 
+      this.characteristicSplitContainer.Panel2.Controls.Add(this.characteristicsMatrixView);
+      this.characteristicSplitContainer.Size = new System.Drawing.Size(692, 279);
+      this.characteristicSplitContainer.SplitterDistance = 221;
+      this.characteristicSplitContainer.TabIndex = 2;
+      // 
+      // calculatorListView
+      // 
+      this.calculatorListView.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.calculatorListView.CheckBoxes = true;
+      this.calculatorListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.characteristicColumnHeader});
+      this.calculatorListView.Location = new System.Drawing.Point(3, 0);
+      this.calculatorListView.Name = "calculatorListView";
+      this.calculatorListView.Size = new System.Drawing.Size(215, 244);
+      this.calculatorListView.TabIndex = 0;
+      this.calculatorListView.UseCompatibleStateImageBehavior = false;
+      this.calculatorListView.View = System.Windows.Forms.View.Details;
+      // 
+      // characteristicColumnHeader
+      // 
+      this.characteristicColumnHeader.Text = "Characteristic";
+      this.characteristicColumnHeader.Width = 211;
+      // 
+      // calculateButton
+      // 
+      this.calculateButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.calculateButton.Location = new System.Drawing.Point(6, 250);
+      this.calculateButton.Name = "calculateButton";
+      this.calculateButton.Size = new System.Drawing.Size(212, 23);
+      this.calculateButton.TabIndex = 0;
+      this.calculateButton.Text = "Calculate";
+      this.calculateButton.UseVisualStyleBackColor = true;
+      this.calculateButton.Click += new System.EventHandler(this.calculateButton_Click);
+      // 
+      // characteristicsMatrixView
+      // 
+      this.characteristicsMatrixView.Caption = "StringConvertibleMatrix View";
+      this.characteristicsMatrixView.Content = null;
+      this.characteristicsMatrixView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.characteristicsMatrixView.Location = new System.Drawing.Point(0, 0);
+      this.characteristicsMatrixView.Name = "characteristicsMatrixView";
+      this.characteristicsMatrixView.ReadOnly = false;
+      this.characteristicsMatrixView.ShowRowsAndColumnsTextBox = false;
+      this.characteristicsMatrixView.ShowStatisticalInformation = false;
+      this.characteristicsMatrixView.Size = new System.Drawing.Size(467, 279);
+      this.characteristicsMatrixView.TabIndex = 1;
+      // 
+      // uploadCharacteristicsButton
+      // 
+      this.uploadCharacteristicsButton.Location = new System.Drawing.Point(38, 6);
+      this.uploadCharacteristicsButton.Name = "uploadCharacteristicsButton";
+      this.uploadCharacteristicsButton.Size = new System.Drawing.Size(26, 23);
+      this.uploadCharacteristicsButton.TabIndex = 0;
+      this.uploadCharacteristicsButton.Text = "Upload";
+      this.uploadCharacteristicsButton.UseVisualStyleBackColor = true;
+      this.uploadCharacteristicsButton.Click += new System.EventHandler(this.uploadCharacteristicsButton_Click);
+      // 
       // downloadCharacteristicsButton
       // 
@@ -184,29 +266,4 @@
       this.downloadCharacteristicsButton.UseVisualStyleBackColor = true;
       this.downloadCharacteristicsButton.Click += new System.EventHandler(this.downloadCharacteristicsButton_Click);
-      // 
-      // uploadCharacteristicsButton
-      // 
-      this.uploadCharacteristicsButton.Location = new System.Drawing.Point(38, 6);
-      this.uploadCharacteristicsButton.Name = "uploadCharacteristicsButton";
-      this.uploadCharacteristicsButton.Size = new System.Drawing.Size(26, 23);
-      this.uploadCharacteristicsButton.TabIndex = 0;
-      this.uploadCharacteristicsButton.Text = "Upload";
-      this.uploadCharacteristicsButton.UseVisualStyleBackColor = true;
-      this.uploadCharacteristicsButton.Click += new System.EventHandler(this.uploadCharacteristicsButton_Click);
-      // 
-      // characteristicsMatrixView
-      // 
-      this.characteristicsMatrixView.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.characteristicsMatrixView.Caption = "StringConvertibleMatrix View";
-      this.characteristicsMatrixView.Content = null;
-      this.characteristicsMatrixView.Location = new System.Drawing.Point(6, 35);
-      this.characteristicsMatrixView.Name = "characteristicsMatrixView";
-      this.characteristicsMatrixView.ReadOnly = false;
-      this.characteristicsMatrixView.ShowRowsAndColumnsTextBox = false;
-      this.characteristicsMatrixView.ShowStatisticalInformation = false;
-      this.characteristicsMatrixView.Size = new System.Drawing.Size(680, 273);
-      this.characteristicsMatrixView.TabIndex = 1;
       // 
       // OKBProblemView
@@ -233,4 +290,8 @@
       this.parametersTabPage.ResumeLayout(false);
       this.characteristicsTabPage.ResumeLayout(false);
+      this.characteristicSplitContainer.Panel1.ResumeLayout(false);
+      this.characteristicSplitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.characteristicSplitContainer)).EndInit();
+      this.characteristicSplitContainer.ResumeLayout(false);
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -251,4 +312,8 @@
     private System.Windows.Forms.Button uploadCharacteristicsButton;
     private System.Windows.Forms.Button downloadCharacteristicsButton;
+    private System.Windows.Forms.SplitContainer characteristicSplitContainer;
+    private System.Windows.Forms.ListView calculatorListView;
+    private System.Windows.Forms.ColumnHeader characteristicColumnHeader;
+    private System.Windows.Forms.Button calculateButton;
 
 
Index: /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.cs	(revision 13539)
+++ /trunk/sources/HeuristicLab.Clients.OKB.Views/3.3/RunCreation/Views/OKBProblemView.cs	(revision 13540)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 using System.Linq;
 using System.Windows.Forms;
@@ -28,4 +29,6 @@
 using HeuristicLab.Data;
 using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Clients.OKB.RunCreation {
@@ -41,4 +44,8 @@
     public OKBProblemView() {
       InitializeComponent();
+      refreshButton.Text = string.Empty;
+      refreshButton.Image = VSImageLibrary.Refresh;
+      cloneProblemButton.Text = string.Empty;
+      cloneProblemButton.Image = VSImageLibrary.Clone;
       downloadCharacteristicsButton.Text = string.Empty;
       downloadCharacteristicsButton.Image = VSImageLibrary.Refresh;
@@ -72,4 +79,5 @@
         parameterCollectionView.Content = Content.Parameters;
       }
+      UpdateCharacteristicCalculators();
     }
 
@@ -92,4 +100,23 @@
     }
 
+    private void UpdateCharacteristicCalculators() {
+      calculatorListView.Items.Clear();
+      calculatorListView.Groups.Clear();
+      if (Content == null || Content.ProblemId == -1) return;
+      var problem = Content.CloneProblem();
+      var calculators = ApplicationManager.Manager.GetInstances<ICharacteristicCalculator>().Where(x => x.CanCalculate(problem)).ToList();
+      try {
+        calculatorListView.BeginUpdate();
+        foreach (var calc in calculators) {
+          var group = calculatorListView.Groups.Add(calc.Name, calc.Name);
+          group.Tag = calc;
+          foreach (var c in calc.Characteristics) {
+            var item = calculatorListView.Items.Add(c, c);
+            item.Group = group;
+          }
+        }
+      } finally { calculatorListView.EndUpdate(); }
+    }
+
     private void RunCreationClient_Refreshing(object sender, EventArgs e) {
       if (InvokeRequired) {
@@ -161,4 +188,46 @@
       } catch (Exception ex) { PluginInfrastructure.ErrorHandling.ShowErrorDialog(ex); }
     }
+    private void calculateButton_Click(object sender, EventArgs e) {
+      var problem = Content.CloneProblem();
+      var characteristics = calculatorListView.CheckedItems.OfType<ListViewItem>().GroupBy(x => x.Group);
+      var results = new Dictionary<string, double>();
+      foreach (var c in characteristics) {
+        var calc = (ICharacteristicCalculator)c.Key.Tag;
+        foreach (var result in calc.Calculate(problem, c.Select(x => x.Text).ToArray()))
+          results[result.Key] = result.Value;
+      }
+      var matrix = characteristicsMatrixView.Content as StringMatrix;
+      if (matrix == null) matrix = new StringMatrix(results.Count, 3);
+      for (var i = 0; i < matrix.Rows; i++) {
+        double r;
+        if (results.TryGetValue(matrix[i, 0], out r)) {
+          matrix[i, 1] = r.ToString(CultureInfo.CurrentCulture.NumberFormat);
+          matrix[i, 2] = "DoubleValue";
+          results.Remove(matrix[i, 0]);
+        }
+      }
+      if (results.Count == 0) return;
+      var resultsList = results.ToList();
+      var counter = resultsList.Count - 1;
+      for (var i = 0; i < matrix.Rows; i++) {
+        if (string.IsNullOrEmpty(matrix[i, 0])) {
+          matrix[i, 0] = resultsList[counter].Key;
+          matrix[i, 1] = resultsList[counter].Value.ToString(CultureInfo.CurrentCulture.NumberFormat);
+          matrix[i, 2] = "DoubleValue";
+          resultsList.RemoveAt(counter);
+          counter--;
+          if (counter < 0) return;
+        }
+      }
+      if (counter >= 0) {
+        ((IStringConvertibleMatrix)matrix).Rows += counter + 1;
+        for (var i = matrix.Rows - 1; counter >= 0; i--) {
+          matrix[i, 0] = resultsList[0].Key;
+          matrix[i, 1] = resultsList[0].Value.ToString(CultureInfo.CurrentCulture.NumberFormat);
+          matrix[i, 2] = "DoubleValue";
+          counter--;
+        }
+      }
+    }
     #endregion
 
Index: /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 13539)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 13540)
@@ -153,4 +153,5 @@
     <Compile Include="BasicProblems\Operators\SingleObjectiveMoveMaker.cs" />
     <Compile Include="BasicProblems\SingleObjectiveBasicProblem.cs" />
+    <Compile Include="Interfaces\ICharacteristicCalculator.cs" />
     <Compile Include="Interfaces\ILocalImprovementAlgorithmOperator.cs" />
     <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ICharacteristicCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ICharacteristicCalculator.cs	(revision 13540)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ICharacteristicCalculator.cs	(revision 13540)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface ICharacteristicCalculator : INamedItem {
+    IEnumerable<string> Characteristics { get; }
+    bool CanCalculate(IProblem problem);
+    IEnumerable<KeyValuePair<string, double>> Calculate(IProblem problem, IEnumerable<string> characteristics = null);
+  }
+}
