Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -40,4 +40,15 @@
     }
 
+    public static DT.SingleObjectiveSolution ToDto(DA.SingleObjectiveSolution source) {
+      if (source == null) return null;
+      return new DT.SingleObjectiveSolution() {
+        Id = source.Id,
+        ProblemId = source.ProblemId.Value,
+        RunId = source.RunId,
+        Quality = source.Quality,
+        DataType = ToDto(source.DataType)
+      };
+    }
+
     private static DT.DataType ToDto(DA.DataType source) {
       if (source == null) return null;
@@ -68,4 +79,61 @@
         entity.Values.Add(Convert.ToEntity(value, entity, DA.ValueNameCategory.Result, okb, binCache));
       return entity;
+    }
+
+    public static DT.Value ToDto(DA.CharacteristicValue source) {
+      if (source == null) return null;
+      if (source.Characteristic.Type == DA.CharacteristicType.Bool) {
+        return new DT.BoolValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.BoolValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.Int) {
+        return new DT.IntValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.IntValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.TimeSpan) {
+        return new DT.TimeSpanValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.LongValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.Long) {
+        return new DT.LongValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.LongValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.Float) {
+        return new DT.FloatValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.FloatValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.Double) {
+        return new DT.DoubleValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.DoubleValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.Percent) {
+        return new DT.PercentValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.DoubleValue.GetValueOrDefault() };
+      } else if (source.Characteristic.Type == DA.CharacteristicType.String) {
+        return new DT.StringValue { Name = source.Characteristic.Name, DataType = Convert.ToDto(source.DataType), Value = source.StringValue };
+      } else {
+        throw new ArgumentException("Unknown characteristic type.", "source");
+      }
+    }
+
+    public static DA.CharacteristicValue ToEntity(DT.Value source, DA.OKBDataContext okb, DA.Problem problem, DA.CharacteristicType type) {
+      if (okb == null || problem == null || source == null || string.IsNullOrEmpty(source.Name)) throw new ArgumentNullException();
+      var entity = new DA.CharacteristicValue();
+      entity.Problem = problem;
+      entity.DataType = Convert.ToEntity(source.DataType, okb);
+      entity.Characteristic = Convert.ToEntity(source.Name, type, okb);
+      if (source is DT.BoolValue) {
+        entity.BoolValue = ((DT.BoolValue)source).Value;
+      } else if (source is DT.IntValue) {
+        entity.IntValue = ((DT.IntValue)source).Value;
+      } else if (source is DT.TimeSpanValue) {
+        entity.LongValue = ((DT.TimeSpanValue)source).Value;
+      } else if (source is DT.LongValue) {
+        entity.LongValue = ((DT.LongValue)source).Value;
+      } else if (source is DT.FloatValue) {
+        entity.FloatValue = ((DT.FloatValue)source).Value;
+      } else if (source is DT.DoubleValue) {
+        entity.DoubleValue = ((DT.DoubleValue)source).Value;
+      } else if (source is DT.PercentValue) {
+        entity.DoubleValue = ((DT.PercentValue)source).Value;
+      } else if (source is DT.StringValue) {
+        entity.StringValue = ((DT.StringValue)source).Value;
+      } else {
+        throw new ArgumentException("Unknown characteristic type.", "source");
+      }
+      return entity;
+    }
+
+    private static DA.Characteristic ToEntity(string name, DA.CharacteristicType type, DA.OKBDataContext okb) {
+      if (string.IsNullOrEmpty(name)) return null;
+      var entity = okb.Characteristics.FirstOrDefault(x => (x.Name == name) && (x.Type == type));
+      return entity ?? new DA.Characteristic() { Id = 0, Name = name, Type = type };
     }
 
@@ -108,7 +176,7 @@
     }
 
-    private static DA.DataType ToEntity(DT.DataType source, DA.OKBDataContext okb) {
-      if (source == null) return null;
-      var entity = okb.DataTypes.Where(x => (x.Name == source.Name) && (x.TypeName == source.TypeName)).FirstOrDefault();
+    public static DA.DataType ToEntity(DT.DataType source, DA.OKBDataContext okb) {
+      if (source == null) return null;
+      var entity = okb.DataTypes.FirstOrDefault(x => (x.Name == source.Name) && (x.TypeName == source.TypeName));
       if (entity == null)
         entity = new DA.DataType() { Id = 0, Name = source.Name, TypeName = source.TypeName };
@@ -118,5 +186,5 @@
     private static DA.ValueName ToEntity(string name, DA.ValueNameCategory category, DA.ValueNameType type, DA.OKBDataContext okb) {
       if (string.IsNullOrEmpty(name)) return null;
-      var entity = okb.ValueNames.Where(x => (x.Name == name) && (x.Category == category) && (x.Type == type)).FirstOrDefault();
+      var entity = okb.ValueNames.FirstOrDefault(x => (x.Name == name) && (x.Category == category) && (x.Type == type));
       if (entity == null)
         entity = new DA.ValueName() { Id = 0, Name = name, Category = category, Type = type };
@@ -131,9 +199,9 @@
       }
 
-      var cachedBinaryData = binCache.Where(x => x.Hash.SequenceEqual(hash)).FirstOrDefault();
+      var cachedBinaryData = binCache.FirstOrDefault(x => x.Hash.SequenceEqual(hash));
       if (cachedBinaryData != null)
         return cachedBinaryData;
 
-      var entity = okb.BinaryDatas.Where(x => x.Hash.Equals(hash)).FirstOrDefault();
+      var entity = okb.BinaryDatas.FirstOrDefault(x => x.Hash.Equals(hash));
       if (entity == null) {
         entity = new DA.BinaryData() { Id = 0, Data = data, Hash = hash };
@@ -143,4 +211,26 @@
       return entity;
     }
+
+    public static DA.SingleObjectiveSolution ToEntity(DT.SingleObjectiveSolution source, byte[] data, DA.OKBDataContext okb) {
+      var sol = okb.SingleObjectiveSolutions.SingleOrDefault(x => x.Id == source.Id) ?? new DA.SingleObjectiveSolution() {
+        ProblemId = source.ProblemId,
+        RunId = source.RunId,
+        Quality = source.Quality
+      };
+      if (source.DataType != null) {
+        sol.DataType = ToEntity(source.DataType, okb);
+      }
+      if (data != null && data.Length > 0) {
+        byte[] hash;
+        using (var sha1 = SHA1.Create()) {
+          hash = sha1.ComputeHash(data);
+        }
+        sol.BinaryData = new DA.BinaryData() {
+          Data = data,
+          Hash = hash
+        };
+      }
+      return sol;
+    }
     #endregion
   }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Algorithm.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Algorithm.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Algorithm.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/AlgorithmClass.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/AlgorithmClass.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/AlgorithmClass.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BinaryValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BinaryValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BinaryValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BoolValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BoolValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/BoolValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DataType.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DataType.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DataType.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DoubleValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DoubleValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/DoubleValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/FloatValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/FloatValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/FloatValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/IntValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/IntValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/IntValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/LongValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/LongValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/LongValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/PercentValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/PercentValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/PercentValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Problem.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Problem.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Problem.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/ProblemClass.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/ProblemClass.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/ProblemClass.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Run.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Run.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Run.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/SingleObjectiveSolution.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/SingleObjectiveSolution.cs	(revision 16692)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/SingleObjectiveSolution.cs	(revision 16692)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Services.OKB.RunCreation.DataTransfer {
+  [DataContract]
+  public class SingleObjectiveSolution : Solution {
+    [DataMember]
+    public double Quality { get; set; }
+  }
+}
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Solution.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Solution.cs	(revision 16692)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Solution.cs	(revision 16692)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.Serialization;
+
+namespace HeuristicLab.Services.OKB.RunCreation.DataTransfer {
+  [DataContract]
+  [KnownType(typeof(SingleObjectiveSolution))]
+  public class Solution {
+    [DataMember]
+    public long Id { get; set; }
+    [DataMember]
+    public long ProblemId { get; set; }
+    [DataMember]
+    public long? RunId { get; set; }
+    [DataMember]
+    public DataType DataType { get; set; }
+  }
+}
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/StringValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/StringValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/StringValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/TimeSpanValue.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/TimeSpanValue.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/TimeSpanValue.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Value.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Value.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/DataTransfer/Value.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,8 +20,8 @@
 #endregion
 
+using HeuristicLab.Services.OKB.RunCreation.DataTransfer;
 using System.Collections.Generic;
 using System.Net.Security;
 using System.ServiceModel;
-using HeuristicLab.Services.OKB.RunCreation.DataTransfer;
 
 namespace HeuristicLab.Services.OKB.RunCreation {
@@ -44,5 +44,35 @@
 
     [OperationContract]
+    [FaultContract(typeof(MissingProblem))]
+    IEnumerable<Solution> GetSolutions(long problemId);
+
+    [OperationContract]
+    Solution GetSolution(long solutionId);
+
+    [OperationContract]
+    [FaultContract(typeof(MissingSolution))]
+    byte[] GetSolutionData(long solutionId);
+
+    [OperationContract]
+    long AddSolution(Solution solution, byte[] data);
+
+    [OperationContract]
+    void DeleteSolution(Solution solution);
+
+    [OperationContract]
     void AddRun(Run run);
+
+    [OperationContract]
+    IEnumerable<Value> GetCharacteristicValues(long problemId);
+
+    [OperationContract]
+    [FaultContract(typeof(MissingProblem))]
+    [FaultContract(typeof(UnknownCharacteristicType))]
+    void SetCharacteristicValue(long problemId, Value value);
+
+    [OperationContract]
+    [FaultContract(typeof(MissingProblem))]
+    [FaultContract(typeof(UnknownCharacteristicType))]
+    void SetCharacteristicValues(long problemId, Value[] values);
   }
 }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs	(revision 16692)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs	(revision 16692)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.Serialization;
+
+namespace HeuristicLab.Services.OKB.RunCreation {
+  [DataContract]
+  public class MissingProblem {
+    [DataMember]
+    public string Message { get; set; }
+
+    public MissingProblem(long problemId) {
+      Message = string.Format("Problem with id {0} cannot be found", problemId);
+    }
+  }
+}
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingSolution.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingSolution.cs	(revision 16692)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/MissingSolution.cs	(revision 16692)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.Serialization;
+
+namespace HeuristicLab.Services.OKB.RunCreation {
+  [DataContract]
+  public class MissingSolution {
+    [DataMember]
+    public string Message { get; set; }
+
+    public MissingSolution(long solutionId) {
+      Message = string.Format("Solution with id {0} cannot be found", solutionId);
+    }
+  }
+}
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs	(revision 15697)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs	(revision 16692)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,10 +20,11 @@
 #endregion
 
+using HeuristicLab.Services.Access;
+using HeuristicLab.Services.OKB.DataAccess;
+using System;
 using System.Collections.Generic;
 using System.Data.Linq;
 using System.Linq;
 using System.ServiceModel;
-using HeuristicLab.Services.Access;
-using HeuristicLab.Services.OKB.DataAccess;
 
 namespace HeuristicLab.Services.OKB.RunCreation {
@@ -126,4 +127,92 @@
     }
 
+    public IEnumerable<DataTransfer.Solution> GetSolutions(long problemId) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var problem = okb.Problems.SingleOrDefault(x => x.Id == problemId);
+        if (problem == null) throw new FaultException<MissingProblem>(new MissingProblem(problemId));
+        // TODO: In case of multi-objective problems one has to check whether it contains single- or multi-objective problems
+        var result = problem.SingleObjectiveSolutions.Select(x => Convert.ToDto(x)).ToList();
+        if (roleVerifier.IsInRole(OKBRoles.OKBAdministrator)) {
+          return result;
+        } else {
+          var problemUsers = okb.ProblemUsers.Where(x => x.ProblemId == problemId).ToList();
+          if (problemUsers.Count == 0 || userManager.VerifyUser(userManager.CurrentUserId, problemUsers.Select(y => y.UserGroupId).ToList())) {
+            return result;
+          } else {
+            return null;
+          }
+        }
+      }
+    }
+
+    public DataTransfer.Solution GetSolution(long solutionId) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        // TODO: In case of multi-objective problems one has to check whether it contains single- or multi-objective problems
+        var result = Convert.ToDto(okb.SingleObjectiveSolutions.SingleOrDefault(x => x.Id == solutionId));
+        if (roleVerifier.IsInRole(OKBRoles.OKBAdministrator)) {
+          return result;
+        } else {
+          var problemUsers = okb.ProblemUsers.Where(x => x.ProblemId == result.ProblemId).ToList();
+          if (problemUsers.Count == 0 || userManager.VerifyUser(userManager.CurrentUserId, problemUsers.Select(y => y.UserGroupId).ToList())) {
+            return result;
+          } else {
+            return null;
+          }
+        }
+      }
+    }
+
+    public byte[] GetSolutionData(long solutionId) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var solution = okb.SingleObjectiveSolutions.SingleOrDefault(x => x.Id == solutionId);
+        if (solution == null) throw new FaultException<MissingSolution>(new MissingSolution(solutionId));
+
+        var result = solution.BinaryData.Data.ToArray();
+        if (roleVerifier.IsInRole(OKBRoles.OKBAdministrator)) {
+          return result;
+        } else {
+          var problemUsers = okb.ProblemUsers.Where(x => x.ProblemId == solution.ProblemId).ToList();
+          if (problemUsers.Count == 0 || userManager.VerifyUser(userManager.CurrentUserId, problemUsers.Select(y => y.UserGroupId).ToList())) {
+            return result;
+          } else {
+            return null;
+          }
+        }
+      }
+    }
+
+    public long AddSolution(DataTransfer.Solution solution, byte[] data) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var soSolution = solution as DataTransfer.SingleObjectiveSolution;
+        if (soSolution != null) {
+          DataAccess.SingleObjectiveSolution entity = Convert.ToEntity(soSolution, data, okb);
+          okb.SingleObjectiveSolutions.InsertOnSubmit(entity);
+          okb.SubmitChanges();
+          return entity.Id;
+        }
+      }
+      throw new FaultException(new FaultReason("The solution could not be added."));
+    }
+
+    public void DeleteSolution(DataTransfer.Solution solution) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var soSolution = solution as DataTransfer.SingleObjectiveSolution;
+        if (soSolution != null) {
+          okb.SingleObjectiveSolutions.DeleteOnSubmit(okb.SingleObjectiveSolutions.Single(x => x.Id == soSolution.Id));
+          okb.SubmitChanges();
+        }
+      }
+    }
+
     public void AddRun(DataTransfer.Run run) {
       roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
@@ -135,4 +224,89 @@
       }
     }
+
+    public IEnumerable<DataTransfer.Value> GetCharacteristicValues(long problemId) {
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var prob = okb.Problems.SingleOrDefault(x => x.Id == problemId);
+        if (prob == null) return Enumerable.Empty<DataTransfer.Value>();
+        return prob.CharacteristicValues.Select(Convert.ToDto).ToArray();
+      }
+    }
+
+    public void SetCharacteristicValue(long problemId, DataTransfer.Value value) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var problem = okb.Problems.SingleOrDefault(x => x.Id == problemId);
+        if (problem == null) throw new FaultException<MissingProblem>(new MissingProblem(problemId));
+
+        DoSetCharacteristicValue(okb, problem, value);
+        okb.SubmitChanges();
+      }
+    }
+
+    public void SetCharacteristicValues(long problemId, DataTransfer.Value[] values) {
+      roleVerifier.AuthenticateForAnyRole(OKBRoles.OKBAdministrator, OKBRoles.OKBUser);
+
+      using (OKBDataContext okb = new OKBDataContext()) {
+        var problem = okb.Problems.SingleOrDefault(x => x.Id == problemId);
+        if (problem == null) throw new FaultException<MissingProblem>(new MissingProblem(problemId));
+
+        foreach (var v in values) {
+          DoSetCharacteristicValue(okb, problem, v);
+        }
+        okb.SubmitChanges();
+      }
+    }
+
+    private void DoSetCharacteristicValue(OKBDataContext okb, Problem problem, DataTransfer.Value value) {
+      CharacteristicType characteristicType;
+      try {
+        characteristicType = GetCharacteristicType(value);
+      } catch (ArgumentException ex) {
+        throw new FaultException<UnknownCharacteristicType>(new UnknownCharacteristicType(ex.Message));
+      }
+
+      var entity = problem.CharacteristicValues.SingleOrDefault(x => x.Characteristic.Name == value.Name && x.Characteristic.Type == characteristicType);
+      if (entity != null) {
+        // Update
+        switch (characteristicType) {
+          case CharacteristicType.Bool: entity.BoolValue = ((DataTransfer.BoolValue)value).Value; break;
+          case CharacteristicType.Int: entity.IntValue = ((DataTransfer.IntValue)value).Value; break;
+          case CharacteristicType.Long: entity.LongValue = ((DataTransfer.LongValue)value).Value; break;
+          case CharacteristicType.Float: entity.FloatValue = ((DataTransfer.FloatValue)value).Value; break;
+          case CharacteristicType.Double: entity.DoubleValue = ((DataTransfer.DoubleValue)value).Value; break;
+          case CharacteristicType.Percent: entity.DoubleValue = ((DataTransfer.PercentValue)value).Value; break;
+          case CharacteristicType.String: entity.StringValue = ((DataTransfer.StringValue)value).Value; break;
+          case CharacteristicType.TimeSpan: entity.LongValue = ((DataTransfer.TimeSpanValue)value).Value; break;
+        }
+      } else {
+        // Insert
+        entity = Convert.ToEntity(value, okb, problem, characteristicType);
+        okb.CharacteristicValues.InsertOnSubmit(entity);
+      }
+
+    }
+
+    private CharacteristicType GetCharacteristicType(DataTransfer.Value source) {
+      if (source is DataTransfer.BoolValue) {
+        return CharacteristicType.Bool;
+      } else if (source is DataTransfer.IntValue) {
+        return CharacteristicType.Int;
+      } else if (source is DataTransfer.TimeSpanValue) {
+        return CharacteristicType.TimeSpan;
+      } else if (source is DataTransfer.LongValue) {
+        return CharacteristicType.Long;
+      } else if (source is DataTransfer.FloatValue) {
+        return CharacteristicType.Float;
+      } else if (source is DataTransfer.DoubleValue) {
+        return CharacteristicType.Double;
+      } else if (source is DataTransfer.PercentValue) {
+        return CharacteristicType.Percent;
+      } else if (source is DataTransfer.StringValue) {
+        return CharacteristicType.String;
+      } else {
+        throw new ArgumentException("Unknown characteristic type.", "source");
+      }
+    }
   }
 }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs	(revision 16692)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs	(revision 16692)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.Serialization;
+
+namespace HeuristicLab.Services.OKB.RunCreation {
+  [DataContract]
+  public class UnknownCharacteristicType {
+    [DataMember]
+    public string Message { get; set; }
+
+    public UnknownCharacteristicType(string message, params object[] c) {
+      Message = string.Format(message, c);
+    }
+  }
+}
