Index: branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Query/OKBClient.cs
===================================================================
--- branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Query/OKBClient.cs	(revision 5533)
+++ branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Query/OKBClient.cs	(revision 5533)
@@ -0,0 +1,812 @@
+﻿#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.IO;
+using System.Linq;
+using HeuristicLab.Clients.Common;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Clients.OKB {
+  [Item("OKBClient", "Client for accessing the OKB.")]
+  public sealed class OKBClient : IContent {
+    private static OKBClient instance;
+    public static OKBClient Instance {
+      get {
+        if (instance == null) instance = new OKBClient();
+        return instance;
+      }
+    }
+
+    #region Properties
+    private ItemCollection<Platform> platforms;
+    public ItemCollection<Platform> Platforms {
+      get { return platforms; }
+    }
+    private ItemCollection<DataType> dataTypes;
+    public ItemCollection<DataType> DataTypes {
+      get { return dataTypes; }
+    }
+    private IEnumerable<User> users;
+    public IEnumerable<User> Users {
+      get { return users; }
+    }
+    private ItemCollection<AlgorithmClass> algorithmClasses;
+    public ItemCollection<AlgorithmClass> AlgorithmClasses {
+      get { return algorithmClasses; }
+    }
+    private ItemCollection<Algorithm> algorithms;
+    public ItemCollection<Algorithm> Algorithms {
+      get { return algorithms; }
+    }
+    private ItemCollection<ProblemClass> problemClasses;
+    public ItemCollection<ProblemClass> ProblemClasses {
+      get { return problemClasses; }
+    }
+    private ItemCollection<Problem> problems;
+    public ItemCollection<Problem> Problems {
+      get { return problems; }
+    }
+    #endregion
+
+    private OKBClient() {
+      platforms = new ItemCollection<Platform>();
+      platforms.ItemsRemoved += new CollectionItemsChangedEventHandler<Platform>(platforms_ItemsRemoved);
+      dataTypes = new ItemCollection<DataType>();
+      dataTypes.ItemsRemoved += new CollectionItemsChangedEventHandler<DataType>(dataTypes_ItemsRemoved);
+      algorithmClasses = new ItemCollection<AlgorithmClass>();
+      algorithmClasses.ItemsRemoved += new CollectionItemsChangedEventHandler<AlgorithmClass>(algorithmClasses_ItemsRemoved);
+      algorithms = new ItemCollection<Algorithm>();
+      algorithms.ItemsRemoved += new CollectionItemsChangedEventHandler<Algorithm>(algorithms_ItemsRemoved);
+      problemClasses = new ItemCollection<ProblemClass>();
+      problemClasses.ItemsRemoved += new CollectionItemsChangedEventHandler<ProblemClass>(problemClasses_ItemsRemoved);
+      problems = new ItemCollection<Problem>();
+      problems.ItemsRemoved += new CollectionItemsChangedEventHandler<Problem>(problems_ItemsRemoved);
+    }
+
+    #region Refresh
+    public void Refresh() {
+      OnRefreshing();
+
+      platforms.Clear();
+      dataTypes.Clear();
+      algorithmClasses.Clear();
+      algorithms.Clear();
+      problemClasses.Clear();
+      problems.Clear();
+
+      var call = new Func<Exception>(delegate() {
+        try {
+          platforms.AddRange(CallAdministrationService<List<Platform>>(s => s.GetPlatforms()).OrderBy(x => x.Name));
+          dataTypes.AddRange(CallAdministrationService<List<DataType>>(s => s.GetDataTypes()).OrderBy(x => x.Name));
+          users = CallAuthenticationService<List<User>>(s => s.GetUsers()).OrderBy(x => x.Name);
+          algorithmClasses.AddRange(CallAdministrationService<List<AlgorithmClass>>(s => s.GetAlgorithmClasses()).OrderBy(x => x.Name));
+          algorithms.AddRange(CallAdministrationService<List<Algorithm>>(s => s.GetAlgorithms()).OrderBy(x => x.Name));
+          problemClasses.AddRange(CallAdministrationService<List<ProblemClass>>(s => s.GetProblemClasses()).OrderBy(x => x.Name));
+          problems.AddRange(CallAdministrationService<List<Problem>>(s => s.GetProblems()).OrderBy(x => x.Name));
+          return null;
+        }
+        catch (Exception ex) {
+          return ex;
+        }
+      });
+      call.BeginInvoke(delegate(IAsyncResult result) {
+        Exception ex = call.EndInvoke(result);
+        if (ex != null) ErrorHandling.ShowErrorDialog("Refresh failed.", ex);
+        OnRefreshed();
+      }, null);
+    }
+    #endregion
+
+    #region Store
+    public bool Store(IOKBItem item) {
+      try {
+        if (item.Id == 0) {
+          if (item is Platform)
+            item.Id = CallAdministrationService<long>(s => s.AddPlatform((Platform)item));
+          else if (item is DataType)
+            item.Id = CallAdministrationService<long>(s => s.AddDataType((DataType)item));
+          else if (item is AlgorithmClass)
+            item.Id = CallAdministrationService<long>(s => s.AddAlgorithmClass((AlgorithmClass)item));
+          else if (item is Algorithm)
+            item.Id = CallAdministrationService<long>(s => s.AddAlgorithm((Algorithm)item));
+          else if (item is AlgorithmParameter)
+            item.Id = CallAdministrationService<long>(s => s.AddAlgorithmParameter((AlgorithmParameter)item));
+          else if (item is ProblemClass)
+            item.Id = CallAdministrationService<long>(s => s.AddProblemClass((ProblemClass)item));
+          else if (item is Problem)
+            item.Id = CallAdministrationService<long>(s => s.AddProblem((Problem)item));
+          else if (item is ProblemParameter)
+            item.Id = CallAdministrationService<long>(s => s.AddProblemParameter((ProblemParameter)item));
+          else if (item is Result)
+            item.Id = CallAdministrationService<long>(s => s.AddResult((Result)item));
+          else if (item is Experiment)
+            item.Id = CallAdministrationService<long>(s => s.AddExperiment((Experiment)item));
+          else if (item is Run)
+            item.Id = CallAdministrationService<long>(s => s.AddRun((Run)item));
+        } else {
+          if (item is Platform)
+            CallAdministrationService(s => s.UpdatePlatform((Platform)item));
+          else if (item is DataType)
+            CallAdministrationService(s => s.UpdateDataType((DataType)item));
+          else if (item is AlgorithmClass)
+            CallAdministrationService(s => s.UpdateAlgorithmClass((AlgorithmClass)item));
+          else if (item is Algorithm)
+            CallAdministrationService(s => s.UpdateAlgorithm((Algorithm)item));
+          else if (item is AlgorithmParameter)
+            CallAdministrationService(s => s.UpdateAlgorithmParameter((AlgorithmParameter)item));
+          else if (item is ProblemClass)
+            CallAdministrationService(s => s.UpdateProblemClass((ProblemClass)item));
+          else if (item is Problem)
+            CallAdministrationService(s => s.UpdateProblem((Problem)item));
+          else if (item is ProblemParameter)
+            CallAdministrationService(s => s.UpdateProblemParameter((ProblemParameter)item));
+          else if (item is Result)
+            CallAdministrationService(s => s.UpdateResult((Result)item));
+          else if (item is Experiment)
+            item.Id = CallAdministrationService<long>(s => s.AddExperiment((Experiment)item));
+          else if (item is Run)
+            item.Id = CallAdministrationService<long>(s => s.AddRun((Run)item));
+        }
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Store failed.", ex);
+        return false;
+      }
+    }
+    #endregion
+
+    #region DataType Methods
+    public DataType ConvertToDataType(Type type) {
+      DataType dataType = DataTypes.FirstOrDefault(x => x.TypeName == type.AssemblyQualifiedName);
+      if (dataType == null) {
+        dataType = new DataType();
+        dataType.Name = type.Name;
+        dataType.TypeName = type.AssemblyQualifiedName;
+        dataType.PlatformId = Platforms.FirstOrDefault(x => x.Name == "HeuristicLab 3.3").Id;
+
+        if (typeof(BoolValue).IsAssignableFrom(type))
+          dataType.SqlName = "bit";
+        else if (typeof(IntValue).IsAssignableFrom(type))
+          dataType.SqlName = "bigint";
+        else if (typeof(DoubleValue).IsAssignableFrom(type))
+          dataType.SqlName = "float";
+        else if (typeof(StringValue).IsAssignableFrom(type) || typeof(IStringConvertibleValue).IsAssignableFrom(type))
+          dataType.SqlName = "nvarchar";
+        else
+          dataType.SqlName = "varbinary";
+
+        dataType.Store();
+        DataTypes.Add(dataType);
+      }
+      return dataType;
+    }
+    #endregion
+
+    #region Algorithm Methods
+    public List<Guid> GetAlgorithmUsers(long algorithmId) {
+      try {
+        return CallAdministrationService<List<Guid>>(s => s.GetAlgorithmUsers(algorithmId));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh authorized algorithm users failed.", ex);
+        return null;
+      }
+    }
+    public bool UpdateAlgorithmUsers(long algorithmId, List<Guid> users) {
+      try {
+        CallAdministrationService(s => s.UpdateAlgorithmUsers(algorithmId, users));
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Update authorized algorithm users failed.", ex);
+        return false;
+      }
+    }
+    public AlgorithmData GetAlgorithmData(long algorithmId) {
+      try {
+        return CallAdministrationService<AlgorithmData>(s => s.GetAlgorithmData(algorithmId));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh algorithm data failed.", ex);
+        return null;
+      }
+    }
+    public bool UpdateAlgorithmData(AlgorithmData algorithmData) {
+      try {
+        CallAdministrationService(s => s.UpdateAlgorithmData(algorithmData));
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Update algorithm data failed.", ex);
+        return false;
+      }
+    }
+    #endregion
+
+    #region Problem Methods
+    public List<Guid> GetProblemUsers(long problemId) {
+      try {
+        return CallAdministrationService<List<Guid>>(s => s.GetProblemUsers(problemId));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh authorized problem users failed.", ex);
+        return null;
+      }
+    }
+    public bool UpdateProblemUsers(long problemId, List<Guid> users) {
+      try {
+        CallAdministrationService(s => s.UpdateProblemUsers(problemId, users));
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Update authorized problem users failed.", ex);
+        return false;
+      }
+    }
+    public ProblemData GetProblemData(long problemId) {
+      try {
+        return CallAdministrationService<ProblemData>(s => s.GetProblemData(problemId));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh problem data failed.", ex);
+        return null;
+      }
+    }
+    public bool UpdateProblemData(ProblemData problemData) {
+      try {
+        CallAdministrationService(s => s.UpdateProblemData(problemData));
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Update problem data failed.", ex);
+        return false;
+      }
+    }
+    #endregion
+
+    #region AlgorithmParameter Methods
+    public AlgorithmParameter GetAlgorithmParameter(long id) {
+      try {
+        return CallAdministrationService<AlgorithmParameter>(s => s.GetAlgorithmParameter(id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh algorithm parameter failed.", ex);
+        return null;
+      }
+    }
+    public ItemCollection<AlgorithmParameter> GetAlgorithmParameters(long algorithmId) {
+      try {
+        ItemCollection<AlgorithmParameter> parameters = new ItemCollection<AlgorithmParameter>();
+        parameters.AddRange(CallAdministrationService<List<AlgorithmParameter>>(s => s.GetAlgorithmParameters(algorithmId)).OrderBy(x => x.Name));
+        return parameters;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh algorithm parameters failed.", ex);
+        return null;
+      }
+    }
+    #endregion
+
+    #region ProblemParameter Methods
+    public ProblemParameter GetProblemParameter(long id) {
+      try {
+        return CallAdministrationService<ProblemParameter>(s => s.GetProblemParameter(id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh problem parameter failed.", ex);
+        return null;
+      }
+    }
+    public ItemCollection<ProblemParameter> GetProblemParameters(long problemId) {
+      try {
+        ItemCollection<ProblemParameter> parameters = new ItemCollection<ProblemParameter>();
+        parameters.AddRange(CallAdministrationService<List<ProblemParameter>>(s => s.GetProblemParameters(problemId)).OrderBy(x => x.Name));
+        return parameters;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh problem parameters failed.", ex);
+        return null;
+      }
+    }
+    #endregion
+
+    #region Result Methods
+    public Result GetResult(long id) {
+      try {
+        return CallAdministrationService<Result>(s => s.GetResult(id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh result failed.", ex);
+        return null;
+      }
+    }
+    public ItemCollection<Result> GetResults(long algorithmId) {
+      try {
+        ItemCollection<Result> results = new ItemCollection<Result>();
+        results.AddRange(CallAdministrationService<List<Result>>(s => s.GetResults(algorithmId)).OrderBy(x => x.Name));
+        return results;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh results failed.", ex);
+        return null;
+      }
+    }
+    #endregion
+
+    #region Experiment Methods
+    public Experiment GetExperiment(long id) {
+      try {
+        return CallAdministrationService<Experiment>(s => s.GetExperiment(id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh experiment failed.", ex);
+        return null;
+      }
+    }
+    public ItemCollection<Experiment> GetExperiments(long algorithmId, long problemId) {
+      try {
+        ItemCollection<Experiment> experiments = new ItemCollection<Experiment>();
+        experiments.AddRange(CallAdministrationService<List<Experiment>>(s => s.GetExperiments(algorithmId, problemId)));
+        experiments.ItemsRemoved += new CollectionItemsChangedEventHandler<Experiment>(experiments_ItemsRemoved);
+        return experiments;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh experiments failed.", ex);
+        return null;
+      }
+    }
+    #endregion
+
+    #region Run Methods
+    public ItemCollection<Run> GetRuns(long experimentId) {
+      try {
+        ItemCollection<Run> runs = new ItemCollection<Run>();
+        runs.AddRange(CallAdministrationService<List<Run>>(s => s.GetRuns(experimentId)).OrderByDescending(x => x.CreatedDate));
+        runs.ItemsRemoved += new CollectionItemsChangedEventHandler<Run>(runs_ItemsRemoved);
+        return runs;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Refresh runs failed.", ex);
+        return null;
+      }
+    }
+    public bool AddRun(long algorithmId, long problemId, IAlgorithm algorithm) {
+      try {
+        IProblem problem = algorithm.Problem;
+
+        ItemCollection<AlgorithmParameter> algorithmParameters = GetAlgorithmParameters(algorithmId);
+        List<AlgorithmParameterValue> algorithmParameterValues = CollectAlgorithmParameterValues(algorithmId, algorithmParameters, algorithm, "");
+        ItemCollection<ProblemParameter> problemParameters = GetProblemParameters(problemId);
+        List<ProblemParameterValue> problemParameterValues = CollectProblemParamterValues(problemId, problemParameters, problem, "");
+        ItemCollection<Result> results = GetResults(algorithmId);
+        List<ResultValue> resultValues = CollectResultValues(algorithmId, results, algorithm);
+
+        Experiment exp = new Experiment();
+        exp.AlgorithmId = algorithmId;
+        exp.ProblemId = problemId;
+        exp.AlgorithmParameterValues = algorithmParameterValues;
+        exp.ProblemParameterValues = problemParameterValues;
+        exp.Store();
+
+        Run r = new Run();
+        r.ExperimentId = exp.Id;
+        r.ClientId = Guid.NewGuid();
+        r.CreatedDate = DateTime.Now;
+        r.RandomSeed = ((IntValue)((IValueParameter)algorithm.Parameters["Seed"]).Value).Value;
+        r.ResultValues = resultValues;
+        r.Store();
+
+        return true;
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Store run failed.", ex);
+        return false;
+      }
+    }
+
+    private List<AlgorithmParameterValue> CollectAlgorithmParameterValues(long algorithmId, ItemCollection<AlgorithmParameter> parameters, IParameterizedItem item, string prefix) {
+      List<AlgorithmParameterValue> values = new List<AlgorithmParameterValue>();
+      foreach (IValueParameter param in item.Parameters.OfType<IValueParameter>()) {
+        if (param.GetsCollected && (param.Value != null) && (param.Name != "Seed")) {
+          AlgorithmParameter p = parameters.FirstOrDefault(x => x.Name == prefix + param.Name);
+          if (p == null) {
+            p = new AlgorithmParameter();
+            p.Name = prefix + param.Name;
+            p.Alias = prefix + param.Name;
+            p.Description = param.Description;
+            p.AlgorithmId = algorithmId;
+            p.DataTypeId = ConvertToDataType(param.DataType).Id;
+            p.Store();
+            parameters.Add(p);
+          }
+          AlgorithmParameterValue value = CreateAlgorithmParameterValue(param.Value);
+          value.AlgorithmParameterId = p.Id;
+          value.DataTypeId = ConvertToDataType(param.Value.GetType()).Id;
+          values.Add(value);
+        }
+
+        if (param.Value is IParameterizedItem)
+          values.AddRange(CollectAlgorithmParameterValues(algorithmId, parameters, (IParameterizedItem)param.Value, (string.IsNullOrEmpty(prefix) ? param.Name : prefix + param.Name) + "."));
+      }
+      return values;
+    }
+    private AlgorithmParameterValue CreateAlgorithmParameterValue(IItem item) {
+      if (item is BoolValue) {
+        AlgorithmParameterBoolValue value = new AlgorithmParameterBoolValue();
+        value.Value = ((BoolValue)item).Value;
+        return value;
+      } else if (item is DoubleValue) {
+        AlgorithmParameterFloatValue value = new AlgorithmParameterFloatValue();
+        value.Value = ((DoubleValue)item).Value;
+        return value;
+      } else if (item is IntValue) {
+        AlgorithmParameterIntValue value = new AlgorithmParameterIntValue();
+        value.Value = ((IntValue)item).Value;
+        return value;
+      } else if (item is StringValue) {
+        AlgorithmParameterStringValue value = new AlgorithmParameterStringValue();
+        value.Value = ((StringValue)item).Value;
+        return value;
+      } else {
+        AlgorithmParameterBlobValue value = new AlgorithmParameterBlobValue();
+        try {
+          using (MemoryStream stream = new MemoryStream()) {
+            XmlGenerator.Serialize(item, stream);
+            stream.Close();
+            value.Value = stream.ToArray();
+          }
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(ex);
+        }
+        return value;
+      }
+    }
+    private List<ProblemParameterValue> CollectProblemParamterValues(long problemId, ItemCollection<ProblemParameter> parameters, IParameterizedItem item, string prefix) {
+      List<ProblemParameterValue> values = new List<ProblemParameterValue>();
+      foreach (IValueParameter param in item.Parameters.OfType<IValueParameter>()) {
+        if (param.GetsCollected && (param.Value != null)) {
+          ProblemParameter p = parameters.FirstOrDefault(x => x.Name == prefix + param.Name);
+          if (p == null) {
+            p = new ProblemParameter();
+            p.Name = prefix + param.Name;
+            p.Alias = prefix + param.Name;
+            p.Description = param.Description;
+            p.ProblemId = problemId;
+            p.DataTypeId = ConvertToDataType(param.DataType).Id;
+            p.Store();
+            parameters.Add(p);
+          }
+          ProblemParameterValue value = CreateProblemParameterValue(param.Value);
+          value.ProblemParameterId = p.Id;
+          value.DataTypeId = ConvertToDataType(param.Value.GetType()).Id;
+          values.Add(value);
+        }
+
+        if (param.Value is IParameterizedItem)
+          values.AddRange(CollectProblemParamterValues(problemId, parameters, (IParameterizedItem)param.Value, (string.IsNullOrEmpty(prefix) ? param.Name : prefix + param.Name) + "."));
+      }
+      return values;
+    }
+    private ProblemParameterValue CreateProblemParameterValue(IItem item) {
+      if (item is BoolValue) {
+        ProblemParameterBoolValue value = new ProblemParameterBoolValue();
+        value.Value = ((BoolValue)item).Value;
+        return value;
+      } else if (item is DoubleValue) {
+        ProblemParameterFloatValue value = new ProblemParameterFloatValue();
+        value.Value = ((DoubleValue)item).Value;
+        return value;
+      } else if (item is IntValue) {
+        ProblemParameterIntValue value = new ProblemParameterIntValue();
+        value.Value = ((IntValue)item).Value;
+        return value;
+      } else if (item is StringValue) {
+        ProblemParameterStringValue value = new ProblemParameterStringValue();
+        value.Value = ((StringValue)item).Value;
+        return value;
+      } else {
+        ProblemParameterBlobValue value = new ProblemParameterBlobValue();
+        try {
+          using (MemoryStream stream = new MemoryStream()) {
+            XmlGenerator.Serialize(item, stream);
+            stream.Close();
+            value.Value = stream.ToArray();
+          }
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(ex);
+        }
+        return value;
+      }
+    }
+    private List<ResultValue> CollectResultValues(long algorithmId, ItemCollection<Result> results, IAlgorithm algorithm) {
+      List<ResultValue> values = new List<ResultValue>();
+      foreach (IResult result in algorithm.Results) {
+        if (result.Value != null) {
+          Result r = results.FirstOrDefault(x => x.Name == result.Name);
+          if (r == null) {
+            r = new Result();
+            r.Name = result.Name;
+            r.Alias = result.Name;
+            r.Description = result.Description;
+            r.AlgorithmId = algorithmId;
+            r.DataTypeId = ConvertToDataType(result.DataType).Id;
+            r.Store();
+            results.Add(r);
+          }
+          ResultValue value = CreateResultValue(result.Value);
+          value.ResultId = r.Id;
+          value.DataTypeId = ConvertToDataType(result.Value.GetType()).Id;
+          values.Add(value);
+        }
+      }
+      return values;
+    }
+    private ResultValue CreateResultValue(IItem item) {
+      if (item is BoolValue) {
+        ResultBoolValue value = new ResultBoolValue();
+        value.Value = ((BoolValue)item).Value;
+        return value;
+      } else if (item is DoubleValue) {
+        ResultFloatValue value = new ResultFloatValue();
+        value.Value = ((DoubleValue)item).Value;
+        return value;
+      } else if (item is IntValue) {
+        ResultIntValue value = new ResultIntValue();
+        value.Value = ((IntValue)item).Value;
+        return value;
+      } else if (item is StringValue) {
+        ResultStringValue value = new ResultStringValue();
+        value.Value = ((StringValue)item).Value;
+        return value;
+      } else {
+        ResultBlobValue value = new ResultBlobValue();
+        try {
+          using (MemoryStream stream = new MemoryStream()) {
+            XmlGenerator.Serialize(item, stream);
+            stream.Close();
+            value.Value = stream.ToArray();
+          }
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(ex);
+        }
+        return value;
+      }
+    }
+    #endregion
+
+    #region Query Methods
+    private IEnumerable<Filter> filters;
+    public IEnumerable<Filter> GetFilters(bool refresh) {
+      if (refresh || (filters == null)) {
+        try {
+          filters = CallQueryService<List<Filter>>(s => s.GetFilters());
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog("Get filters failed.", ex);
+          return Enumerable.Empty<Filter>();
+        }
+      }
+      return filters;
+    }
+    public IEnumerable<Filter> GetFilters() {
+      return GetFilters(false);
+    }
+    public long GetNumberOfQueryResults(Filter filter) {
+      try {
+        return CallQueryService<long>(x => x.GetNumberOfQueryResults(filter));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Get number of query results failed.", ex);
+        return -1;
+      }
+    }
+    public IEnumerable<long> GetQueryResultIds(Filter filter) {
+      try {
+        return CallQueryService<IEnumerable<long>>(x => x.GetQueryResultIds(filter));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Get query result ids failed.", ex);
+        return Enumerable.Empty<long>();
+      }
+    }
+    public IEnumerable<QueryResult> GetQueryResults(IEnumerable<long> ids) {
+      try {
+        return CallQueryService<IEnumerable<QueryResult>>(s => s.GetQueryResults(ids.ToList()));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Get query results failed.", ex);
+        return null;
+      }
+    }
+    #endregion
+
+    #region Events
+    public event EventHandler Refreshing;
+    private void OnRefreshing() {
+      EventHandler handler = Refreshing;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Refreshed;
+    private void OnRefreshed() {
+      EventHandler handler = Refreshed;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void platforms_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<Platform> e) {
+      try {
+        foreach (Platform p in e.Items)
+          CallAdministrationService(s => s.DeletePlatform(p.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void dataTypes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataType> e) {
+      try {
+        foreach (DataType d in e.Items)
+          CallAdministrationService(s => s.DeleteDataType(d.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void algorithmClasses_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<AlgorithmClass> e) {
+      try {
+        foreach (AlgorithmClass a in e.Items)
+          CallAdministrationService(s => s.DeleteAlgorithmClass(a.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void algorithms_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<Algorithm> e) {
+      try {
+        foreach (Algorithm a in e.Items)
+          CallAdministrationService(s => s.DeleteAlgorithm(a.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void problemClasses_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ProblemClass> e) {
+      try {
+        foreach (ProblemClass p in e.Items)
+          CallAdministrationService(s => s.DeleteProblemClass(p.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void problems_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<Problem> e) {
+      try {
+        foreach (Problem p in e.Items)
+          CallAdministrationService(s => s.DeleteProblem(p.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void experiments_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<Experiment> e) {
+      try {
+        foreach (Experiment exp in e.Items)
+          CallAdministrationService(s => s.DeleteExperiment(exp.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    private void runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<Run> e) {
+      try {
+        foreach (Run r in e.Items)
+          CallAdministrationService(s => s.DeleteRun(r.Id));
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog("Delete failed.", ex);
+      }
+    }
+    #endregion
+
+    #region Helpers
+    private void CallAdministrationService(Action<IAdministrationService> call) {
+      AdministrationServiceClient client = ClientFactory.CreateClient<AdministrationServiceClient, IAdministrationService>();
+      try {
+        call(client);
+      }
+      finally {
+        try {
+          client.Close();
+        }
+        catch (Exception) {
+          client.Abort();
+        }
+      }
+    }
+    private T CallAdministrationService<T>(Func<IAdministrationService, T> call) {
+      AdministrationServiceClient client = ClientFactory.CreateClient<AdministrationServiceClient, IAdministrationService>();
+      try {
+        return call(client);
+      }
+      finally {
+        try {
+          client.Close();
+        }
+        catch (Exception) {
+          client.Abort();
+        }
+      }
+    }
+    private void CallQueryService(Action<IQueryService> call) {
+      QueryServiceClient client = ClientFactory.CreateClient<QueryServiceClient, IQueryService>();
+      try {
+        call(client);
+      }
+      finally {
+        try {
+          client.Close();
+        }
+        catch (Exception) {
+          client.Abort();
+        }
+      }
+    }
+    private T CallQueryService<T>(Func<IQueryService, T> call) {
+      QueryServiceClient client = ClientFactory.CreateClient<QueryServiceClient, IQueryService>();
+      try {
+        return call(client);
+      }
+      finally {
+        try {
+          client.Close();
+        }
+        catch (Exception) {
+          client.Abort();
+        }
+      }
+    }
+    private T CallAuthenticationService<T>(Func<IAuthenticationService, T> call) {
+      AuthenticationServiceClient client = ClientFactory.CreateClient<AuthenticationServiceClient, IAuthenticationService>();
+      try {
+        return call(client);
+      }
+      finally {
+        try {
+          client.Close();
+        }
+        catch (Exception) {
+          client.Abort();
+        }
+      }
+    }
+    #endregion
+  }
+}
