Index: branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Administration/Views/ProblemView.cs
===================================================================
--- branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Administration/Views/ProblemView.cs	(revision 5550)
+++ branches/OKB (trunk integration)/HeuristicLab.Clients.OKB/3.3/Administration/Views/ProblemView.cs	(revision 5587)
@@ -22,9 +22,15 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Windows.Forms;
 using HeuristicLab.Clients.OKB.Authentication;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Clients.OKB.Administration {
@@ -34,4 +40,6 @@
     private List<Platform> platformComboBoxValues;
     private List<ProblemClass> problemClassComboBoxValues;
+    private TypeSelectorDialog typeSelectorDialog;
+    private byte[] data;
 
     public new Problem Content {
@@ -44,22 +52,39 @@
     }
 
-    protected override void OnInitialized(System.EventArgs e) {
-      base.OnInitialized(e);
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      platformComboBox.SelectedValueChanged -= new EventHandler(platformComboBox_SelectedValueChanged);
       platformComboBoxValues = AdministrationClient.Instance.Platforms.ToList();
       platformComboBox.DataSource = platformComboBoxValues;
+      platformComboBox.SelectedValueChanged += new EventHandler(platformComboBox_SelectedValueChanged);
+
+      problemClassComboBox.SelectedValueChanged -= new EventHandler(problemClassComboBox_SelectedValueChanged);
       problemClassComboBoxValues = AdministrationClient.Instance.ProblemClasses.ToList();
       problemClassComboBox.DataSource = problemClassComboBoxValues;
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
+      problemClassComboBox.SelectedValueChanged += new EventHandler(problemClassComboBox_SelectedValueChanged);
+
+      usersListBox.DataSource = null;
+      data = null;
+      dataViewHost.Content = null;
       if (Content == null) {
         platformComboBox.SelectedIndex = -1;
         problemClassComboBox.SelectedIndex = -1;
+        dataTypeNameTextBox.Text = string.Empty;
+        dataTypeTypeNameTextBox.Text = string.Empty;
       } else {
         platformComboBox.SelectedItem = platformComboBoxValues.FirstOrDefault(p => p.Id == Content.PlatformId);
         problemClassComboBox.SelectedItem = problemClassComboBoxValues.FirstOrDefault(a => a.Id == Content.ProblemClassId);
-      }
-      usersListBox.DataSource = null;
+        dataTypeNameTextBox.Text = Content.DataTypeName;
+        dataTypeTypeNameTextBox.Text = Content.DataTypeTypeName;
+      }
     }
 
@@ -68,20 +93,44 @@
       platformComboBox.Enabled = (Content != null) && !ReadOnly;
       problemClassComboBox.Enabled = (Content != null) && !ReadOnly;
-      refreshUsersButton.Enabled = Content != null;
+      dataTypeGroupBox.Enabled = (Content != null) && !ReadOnly;
+      refreshUsersButton.Enabled = (Content != null) && (Content.Id != 0);
       storeUsersButton.Enabled = (usersListBox.DataSource != null) && !ReadOnly;
       usersListBox.Enabled = (usersListBox.DataSource != null) && !ReadOnly;
-    }
-
+      refreshDataButton.Enabled = (Content != null) && (Content.Id != 0);
+      storeDataButton.Enabled = ((data != null) || (dataViewHost.Content != null)) && !ReadOnly;
+      openFileButton.Enabled = (Content != null) && (Content.Id != 0);
+      saveFileButton.Enabled = (data != null) || (dataViewHost.Content != null);
+      noViewAvailableLabel.Visible = dataViewHost.Content == null;
+
+      bool isHL33Platform = platformComboBox.Text == "HeuristicLab 3.3";
+      dataTypeNameTextBox.ReadOnly = isHL33Platform;
+      dataTypeTypeNameTextBox.ReadOnly = isHL33Platform;
+      newDataButton.Enabled = isHL33Platform && (Content.Id != 0) && !ReadOnly;
+    }
+
+    #region Content Events
     protected override void OnContentPropertyChanged(string propertyName) {
       switch (propertyName) {
+        case "Id":
+          SetEnabledStateOfControls();
+          break;
         case "PlatformId":
           platformComboBox.SelectedItem = platformComboBoxValues.FirstOrDefault(p => p.Id == Content.PlatformId);
+          SetEnabledStateOfControls();
           break;
         case "ProblemClassId":
           problemClassComboBox.SelectedItem = problemClassComboBoxValues.FirstOrDefault(a => a.Id == Content.ProblemClassId);
           break;
-      }
-    }
-
+        case "DataTypeName":
+          dataTypeNameTextBox.Text = Content.DataTypeName;
+          break;
+        case "DataTypeTypeName":
+          dataTypeTypeNameTextBox.Text = Content.DataTypeTypeName;
+          break;
+      }
+    }
+    #endregion
+
+    #region Control Events
     private void platformComboBox_SelectedValueChanged(object sender, System.EventArgs e) {
       if (Content != null) {
@@ -97,24 +146,181 @@
     }
 
+    private void dataTypeNameTextBox_TextChanged(object sender, EventArgs e) {
+      if (dataTypeNameTextBox.Text != Content.DataTypeName)
+        Content.DataTypeName = dataTypeNameTextBox.Text;
+    }
+    private void dataTypeTypeNameTextBox_TextChanged(object sender, EventArgs e) {
+      if (dataTypeTypeNameTextBox.Text != Content.DataTypeTypeName)
+        Content.DataTypeTypeName = dataTypeTypeNameTextBox.Text;
+    }
+
     private void refreshUsersButton_Click(object sender, System.EventArgs e) {
-      List<Guid> ids = AdministrationClient.GetProblemUsers(Content.Id);
-      if (ids != null) {
-        List<User> users = AuthenticationClient.Instance.Users.ToList();
-        usersListBox.DataSource = users;
-        usersListBox.DisplayMember = "Name";
-        usersListBox.SelectedItems.Clear();
-        foreach (Guid id in ids)
-          usersListBox.SelectedItems.Add(users.First(u => u.Id == id));
-        usersListBox.Enabled = !ReadOnly;
+      try {
+        List<Guid> ids = AdministrationClient.GetProblemUsers(Content.Id);
+        if (ids != null) {
+          if (AuthenticationClient.Instance.Users == null) AuthenticationClient.Instance.Refresh();
+          List<User> users = AuthenticationClient.Instance.Users.ToList();
+          usersListBox.DataSource = users;
+          usersListBox.DisplayMember = "Name";
+          for (int i = 0; i < users.Count; i++)
+            usersListBox.SetItemChecked(i, ids.Contains(users[i].Id));
+          usersListBox.Enabled = !ReadOnly;
+          storeUsersButton.Enabled = false;
+        }
+      }
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog(this, "Refresh authorized users and groups failed.", ex);
+      }
+    }
+    private void storeUsersButton_Click(object sender, System.EventArgs e) {
+      try {
+        AdministrationClient.UpdateProblemUsers(Content.Id, usersListBox.SelectedItems.Cast<User>().Select(u => u.Id).ToList());
         storeUsersButton.Enabled = false;
       }
-    }
-    private void storeUsersButton_Click(object sender, System.EventArgs e) {
-      AdministrationClient.UpdateProblemUsers(Content.Id, usersListBox.SelectedItems.Cast<User>().Select(u => u.Id).ToList());
-      storeUsersButton.Enabled = false;
-    }
-    private void usersListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      catch (Exception ex) {
+        ErrorHandling.ShowErrorDialog(this, "Store authorized users and groups failed.", ex);
+      }
+    }
+    private void usersListBox_ItemCheck(object sender, ItemCheckEventArgs e) {
       storeUsersButton.Enabled = !ReadOnly;
     }
+
+    private void refreshDataButton_Click(object sender, EventArgs e) {
+      CallAsync(
+        () => {
+          data = null;
+          dataViewHost.Content = null;
+          data = AdministrationClient.GetProblemData(Content.Id);
+          if (data != null) {
+            using (MemoryStream stream = new MemoryStream(data)) {
+              try {
+                dataViewHost.Content = XmlParser.Deserialize<IContent>(stream);
+              }
+              catch (Exception) { }
+              stream.Close();
+            }
+          }
+        },
+        "Refresh problem data failed.",
+        () => SetEnabledStateOfControls()
+      );
+    }
+    private void storeDataButton_Click(object sender, EventArgs e) {
+      CallAsync(
+        () => {
+          if (dataViewHost.Content != null) {
+            using (MemoryStream stream = new MemoryStream()) {
+              XmlGenerator.Serialize(dataViewHost.Content, stream);
+              stream.Close();
+              data = stream.ToArray();
+            }
+          }
+          AdministrationClient.UpdateProblemData(Content.Id, data);
+        },
+        "Store problem data failed.",
+        null
+      );
+    }
+    private void newDataButton_Click(object sender, EventArgs e) {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select Problem";
+        typeSelectorDialog.TypeSelector.Caption = "Available Problems";
+        typeSelectorDialog.TypeSelector.Configure(typeof(IProblem), false, true);
+      }
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          Content.DataTypeName = typeSelectorDialog.TypeSelector.SelectedType.Name;
+          Content.DataTypeTypeName = typeSelectorDialog.TypeSelector.SelectedType.AssemblyQualifiedName;
+          data = null;
+          dataViewHost.Content = (IContent)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, "Create new problem data failed.", ex);
+        }
+        SetEnabledStateOfControls();
+      }
+    }
+    private void openFileButton_Click(object sender, EventArgs e) {
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        CallAsync(
+          () => {
+            IContent problem = null;
+            try {
+              problem = XmlParser.Deserialize<IContent>(openFileDialog.FileName);
+            }
+            catch (Exception) { }
+
+            if (problem != null) {
+              Content.DataTypeName = problem.GetType().Name;
+              Content.DataTypeTypeName = problem.GetType().AssemblyQualifiedName;
+              data = null;
+            } else {
+              using (FileStream stream = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read)) {
+                data = new byte[stream.Length];
+                stream.Read(data, 0, data.Length);
+                stream.Close();
+              }
+            }
+            dataViewHost.Content = problem;
+          },
+          "Save problem data into file failed.",
+          () => SetEnabledStateOfControls()
+        );
+      }
+    }
+    private void saveFileButton_Click(object sender, EventArgs e) {
+      if (saveFileDialog.ShowDialog(this) == DialogResult.OK) {
+        CallAsync(
+          () => {
+            if (dataViewHost.Content != null) {
+              XmlGenerator.Serialize(dataViewHost.Content, saveFileDialog.FileName);
+            } else {
+              using (FileStream stream = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write)) {
+                stream.Write(data, 0, data.Length);
+                stream.Close();
+              }
+            }
+          },
+          "Save problem data into file failed.",
+          null
+        );
+      }
+    }
+    #endregion
+
+    #region Helpers
+    private void CallAsync(Action call, string errorMessage, Action continueWith) {
+      BeginAsyncCall();
+      call.BeginInvoke(delegate(IAsyncResult result) {
+        Exception exception = null;
+        try {
+          call.EndInvoke(result);
+        }
+        catch (Exception ex) {
+          exception = ex;
+        }
+        EndAsyncCall(errorMessage, exception, continueWith);
+      }, null);
+    }
+    private void BeginAsyncCall() {
+      if (InvokeRequired)
+        Invoke(new Action(BeginAsyncCall));
+      else {
+        Cursor = Cursors.AppStarting;
+        Enabled = false;
+      }
+    }
+    private void EndAsyncCall(string errorMessage, Exception exception, Action continueWith) {
+      if (InvokeRequired)
+        Invoke(new Action<string, Exception, Action>(EndAsyncCall), errorMessage, exception, continueWith);
+      else {
+        Cursor = Cursors.Default;
+        Enabled = true;
+        if (exception != null) ErrorHandling.ShowErrorDialog(this, errorMessage, exception);
+        if (continueWith != null) continueWith();
+      }
+    }
+    #endregion
   }
 }
