Index: /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/CharacteristicType.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/CharacteristicType.cs	(revision 13501)
+++ /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/CharacteristicType.cs	(revision 13501)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Services.OKB.DataAccess {
+  public enum CharacteristicType {
+    Bool = 0,
+    Int = 1,
+    Long = 2,
+    Float = 3,
+    Double = 4,
+    String = 5,
+    Percent = 6,
+    TimeSpan = 7
+  }
+}
Index: /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/HeuristicLab.Services.OKB.DataAccess-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/HeuristicLab.Services.OKB.DataAccess-3.3.csproj	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/HeuristicLab.Services.OKB.DataAccess-3.3.csproj	(revision 13501)
@@ -128,4 +128,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="CharacteristicType.cs" />
     <Compile Include="ValueNameType.cs" />
     <Compile Include="ValueNameCategory.cs" />
Index: /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml	(revision 13501)
@@ -141,5 +141,5 @@
       <Column Name="Id" Type="System.Int64" DbType="BigInt NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
       <Column Name="Name" Type="System.String" DbType="NVarChar(200) NOT NULL" CanBeNull="false" />
-      <Column Name="Type" Type="System.Byte" DbType="TinyInt NOT NULL" CanBeNull="false" />
+      <Column Name="Type" Type="CharacteristicType" DbType="TinyInt NOT NULL" CanBeNull="false" />
       <Association Name="Characteristic_CharacteristicValue" Member="CharacteristicValues" ThisKey="Id" OtherKey="CharacteristicId" Type="CharacteristicValue" />
     </Type>
Index: /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml.layout
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml.layout	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.dbml.layout	(revision 13501)
@@ -139,5 +139,5 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(3.24167093356531 : 2.65549967447917); (3.24167093356531 : 8.23159912109375); (5.75 : 8.23159912109375)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(3.24167093356531 : 2.65549967447917); (3.24167093356531 : 8.23159912109375); (5.75 : 8.23159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/OKBDataContext/Algorithm/Algorithm_Run" />
       <nodes>
@@ -146,5 +146,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(12.7565713753709 : 2.65549967447917); (12.7565713753709 : 8.23159912109375); (8.13243692318721 : 8.23159912109375 : JumpStart); (7.96577025652055 : 8.23159912109375 : JumpEnd); (7.75 : 8.23159912109375)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(12.7565713753709 : 2.65549967447917); (12.7565713753709 : 8.23159912109375); (8.13243692318721 : 8.23159912109375 : JumpStart); (7.96577025652055 : 8.23159912109375 : JumpEnd); (7.75 : 8.23159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/OKBDataContext/Problem/Problem_Run" />
       <nodes>
Index: /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.designer.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB.DataAccess/3.3/OKB.designer.cs	(revision 13501)
@@ -3,5 +3,5 @@
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
+//     Runtime Version:4.0.30319.34209
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
@@ -3140,5 +3140,5 @@
 		private string _Name;
 		
-		private byte _Type;
+		private CharacteristicType _Type;
 		
 		private EntitySet<CharacteristicValue> _CharacteristicValues;
@@ -3152,5 +3152,5 @@
     partial void OnNameChanging(string value);
     partial void OnNameChanged();
-    partial void OnTypeChanging(byte value);
+    partial void OnTypeChanging(CharacteristicType value);
     partial void OnTypeChanged();
     #endregion
@@ -3202,6 +3202,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Type", DbType="TinyInt NOT NULL")]
-		public byte Type
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Type", DbType="TinyInt NOT NULL", CanBeNull=false)]
+		public CharacteristicType Type
 		{
 			get
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/HeuristicLab.Services.OKB-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/HeuristicLab.Services.OKB-3.3.csproj	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/HeuristicLab.Services.OKB-3.3.csproj	(revision 13501)
@@ -295,6 +295,8 @@
     <Compile Include="RunCreation\DataTransfer\StringValue.cs" />
     <Compile Include="RunCreation\DataTransfer\Value.cs" />
+    <Compile Include="RunCreation\MissingProblem.cs" />
     <Compile Include="RunCreation\RunCreationService.cs" />
     <Compile Include="RunCreation\IRunCreationService.cs" />
+    <Compile Include="RunCreation\UnknownCharacteristicType.cs" />
   </ItemGroup>
   <ItemGroup>
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/Convert.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/Convert.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/Convert.cs	(revision 13501)
@@ -88,4 +88,27 @@
       return new DT.ValueName() { Id = source.Id, Category = source.Category, Name = source.Name };
     }
+
+    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");
+      }
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/IQueryService.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/IQueryService.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/IQueryService.cs	(revision 13501)
@@ -48,4 +48,7 @@
     [OperationContract]
     IEnumerable<ValueName> GetValueNames();
+
+    [OperationContract]
+    IEnumerable<Value> GetCharacteristics(long problemId);
   }
 }
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/QueryService.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/QueryService.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/Query/QueryService.cs	(revision 13501)
@@ -278,4 +278,13 @@
     }
 
+
+    public IEnumerable<DataTransfer.Value> GetCharacteristics(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();
+      }
+    }
+
     private List<DataAccess.Run> FilterRuns(IQueryable<DataAccess.Run> runs, Filter filter, OKBDataContext okb) {
       IFilter f = (IFilter)Activator.CreateInstance(Type.GetType(filter.FilterTypeName), filter);
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/Convert.cs	(revision 13501)
@@ -68,4 +68,38 @@
         entity.Values.Add(Convert.ToEntity(value, entity, DA.ValueNameCategory.Result, okb, binCache));
       return entity;
+    }
+
+    public static DA.CharacteristicValue ToEntity(DT.Value source, DA.OKBDataContext okb, DA.Problem problem, string characteristicName, DA.CharacteristicType type) {
+      if (okb == null || problem == null || string.IsNullOrEmpty(characteristicName) || source == null) throw new ArgumentNullException();
+      var entity = new DA.CharacteristicValue();
+      entity.Problem = problem;
+      entity.DataType = Convert.ToEntity(source.DataType, okb);
+      entity.Characteristic = Convert.ToEntity(characteristicName, 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 };
     }
 
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/IRunCreationService.cs	(revision 13501)
@@ -45,4 +45,9 @@
     [OperationContract]
     void AddRun(Run run);
+
+    [OperationContract]
+    [FaultContract(typeof(MissingProblem))]
+    [FaultContract(typeof(UnknownCharacteristicType))]
+    void SetCharacteristicValue(long problemId, string characteristicName, Value value);
   }
 }
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs	(revision 13501)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/MissingProblem.cs	(revision 13501)
@@ -0,0 +1,34 @@
+﻿#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.Runtime.Serialization;
+
+namespace HeuristicLab.Services.OKB.RunCreation {
+  [DataContract]
+  public class MissingProblem {
+    [DataMember]
+    public string Message { get; set; }
+
+    public MissingProblem(string message, params object[] c) {
+      Message = string.Format(message, c);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs	(revision 13500)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/RunCreationService.cs	(revision 13501)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Data.Linq;
@@ -135,4 +136,62 @@
       }
     }
+
+
+    public void SetCharacteristicValue(long problemId, string characteristicName, 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("Problem with id {0} cannot be found", problemId));
+        CharacteristicType characteristicType;
+        try {
+          characteristicType = GetCharacteristicType(value);
+        } catch (ArgumentException ex) {
+          throw new FaultException<UnknownCharacteristicType>(new UnknownCharacteristicType(ex.Message));
+        }
+
+        var entity = okb.CharacteristicValues.SingleOrDefault(x => x.Characteristic.Name == characteristicName && 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, characteristicName, characteristicType);
+          okb.CharacteristicValues.InsertOnSubmit(entity);
+        }
+        okb.SubmitChanges();
+      }
+    }
+
+    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: /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs	(revision 13501)
+++ /trunk/sources/HeuristicLab.Services.OKB/3.3/RunCreation/UnknownCharacteristicType.cs	(revision 13501)
@@ -0,0 +1,13 @@
+﻿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);
+    }
+  }
+}
