Index: /stable/HeuristicLab 3.3.sln
===================================================================
--- /stable/HeuristicLab 3.3.sln	(revision 17116)
+++ /stable/HeuristicLab 3.3.sln	(revision 17117)
@@ -50,4 +50,5 @@
 		{F98A1740-9AC9-4D36-A582-6A2D0D06978D} = {F98A1740-9AC9-4D36-A582-6A2D0D06978D}
 		{B03C4E41-1D01-4C60-B0F4-DBB257D98CA8} = {B03C4E41-1D01-4C60-B0F4-DBB257D98CA8}
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032} = {D1D69043-17E6-4B8C-BF41-0799C7E56032}
 		{73F29D43-5714-4069-8FAB-0D18FEB5F175} = {73F29D43-5714-4069-8FAB-0D18FEB5F175}
 		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198} = {3E9E8944-44FF-40BB-A622-3A4A7DD0F198}
@@ -86,4 +87,5 @@
 		{9D792B6D-836B-46DC-9D69-50B4B1E7B87F} = {9D792B6D-836B-46DC-9D69-50B4B1E7B87F}
 		{399EBB6E-37A1-4AE4-B8CD-0D461FF286A3} = {399EBB6E-37A1-4AE4-B8CD-0D461FF286A3}
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909} = {FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}
 		{3C906172-E044-4DF0-B4FD-AA21192D5D3E} = {3C906172-E044-4DF0-B4FD-AA21192D5D3E}
 		{DC3D7072-7999-4719-B65D-3997744D5DC1} = {DC3D7072-7999-4719-B65D-3997744D5DC1}
@@ -459,4 +461,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3", "HeuristicLab.Algorithms.MOCMAEvolutionStrategy\3.3\HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj", "{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.ExactOptimization-3.3", "HeuristicLab.ExactOptimization\3.3\HeuristicLab.ExactOptimization-3.3.csproj", "{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.ExactOptimization.Views-3.3", "HeuristicLab.ExactOptimization.Views\3.3\HeuristicLab.ExactOptimization.Views-3.3.csproj", "{D1D69043-17E6-4B8C-BF41-0799C7E56032}"
 EndProject
 Global
@@ -2234,4 +2240,24 @@
 		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.ActiveCfg = Release|x86
 		{0E2E224F-E9B2-41F3-B510-09183EEBA2AF}.Release|x86.Build.0 = Release|x86
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Debug|x64.ActiveCfg = Debug|x64
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Debug|x64.Build.0 = Debug|x64
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Release|x64.ActiveCfg = Release|x64
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Release|x64.Build.0 = Release|x64
+		{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}.Release|x86.ActiveCfg = Release|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Debug|x64.ActiveCfg = Debug|x64
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Debug|x64.Build.0 = Debug|x64
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Release|x64.ActiveCfg = Release|x64
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Release|x64.Build.0 = Release|x64
+		{D1D69043-17E6-4B8C-BF41-0799C7E56032}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /stable/HeuristicLab.Core/3.3/Attributes/CreatableAttribute.cs
===================================================================
--- /stable/HeuristicLab.Core/3.3/Attributes/CreatableAttribute.cs	(revision 17116)
+++ /stable/HeuristicLab.Core/3.3/Attributes/CreatableAttribute.cs	(revision 17117)
@@ -35,4 +35,5 @@
       public const string PopulationBasedAlgorithms = Algorithms + SplitToken + "1" + OrderToken + "Population Based";
       public const string SingleSolutionAlgorithms = Algorithms + SplitToken + "2" + OrderToken + "Single Solution";
+      public const string ExactAlgorithms = Algorithms + SplitToken + "3" + OrderToken + "Exact";
 
       public const string Problems = "2" + OrderToken + "Problems";
Index: /stable/HeuristicLab.Data.Views/3.3/HeuristicLab.Data.Views-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Data.Views/3.3/HeuristicLab.Data.Views-3.3.csproj	(revision 17116)
+++ /stable/HeuristicLab.Data.Views/3.3/HeuristicLab.Data.Views-3.3.csproj	(revision 17117)
@@ -221,4 +221,10 @@
       <DependentUpon>StringConvertibleMatrixView.cs</DependentUpon>
     </Compile>
+    <Compile Include="TextValueView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TextValueView.Designer.cs">
+      <DependentUpon>TextValueView.cs</DependentUpon>
+    </Compile>
     <Compile Include="StringConvertibleValueView.cs">
       <SubType>UserControl</SubType>
Index: /stable/HeuristicLab.Data.Views/3.3/TextValueView.Designer.cs
===================================================================
--- /stable/HeuristicLab.Data.Views/3.3/TextValueView.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.Data.Views/3.3/TextValueView.Designer.cs	(revision 17117)
@@ -0,0 +1,133 @@
+#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
+
+namespace HeuristicLab.Data.Views {
+  partial class TextValueView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.valueTextBox = new System.Windows.Forms.TextBox();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.valueLabel = new System.Windows.Forms.Label();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // valueTextBox
+      // 
+      this.valueTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.valueTextBox.Location = new System.Drawing.Point(0, 0);
+      this.valueTextBox.Multiline = true;
+      this.valueTextBox.Name = "valueTextBox";
+      this.valueTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal;
+      this.valueTextBox.Size = new System.Drawing.Size(194, 40);
+      this.valueTextBox.TabIndex = 2;
+      this.valueTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.valueTextBox_KeyDown);
+      this.valueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.valueTextBox_Validating);
+      this.valueTextBox.Validated += new System.EventHandler(this.valueTextBox_Validated);
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // valueLabel
+      // 
+      this.valueLabel.AutoSize = true;
+      this.valueLabel.Location = new System.Drawing.Point(3, 3);
+      this.valueLabel.Name = "valueLabel";
+      this.valueLabel.Size = new System.Drawing.Size(37, 13);
+      this.valueLabel.TabIndex = 1;
+      this.valueLabel.Text = "&Value:";
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.IsSplitterFixed = true;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.valueLabel);
+      this.splitContainer.Panel1MinSize = 19;
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.valueTextBox);
+      this.splitContainer.Size = new System.Drawing.Size(194, 60);
+      this.splitContainer.SplitterDistance = 19;
+      this.splitContainer.SplitterWidth = 1;
+      this.splitContainer.TabIndex = 0;
+      this.splitContainer.TabStop = false;
+      // 
+      // TextValueView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "TextValueView";
+      this.Size = new System.Drawing.Size(194, 60);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.Panel2.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.TextBox valueTextBox;
+    protected System.Windows.Forms.ErrorProvider errorProvider;
+    protected System.Windows.Forms.Label valueLabel;
+    protected System.Windows.Forms.SplitContainer splitContainer;
+  }
+}
Index: /stable/HeuristicLab.Data.Views/3.3/TextValueView.cs
===================================================================
--- /stable/HeuristicLab.Data.Views/3.3/TextValueView.cs	(revision 17117)
+++ /stable/HeuristicLab.Data.Views/3.3/TextValueView.cs	(revision 17117)
@@ -0,0 +1,112 @@
+#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.ComponentModel;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Data.Views {
+  [View("TextValue View")]
+  [Content(typeof(ITextValue), true)]
+  public partial class TextValueView : AsynchronousContentView {
+    public new IStringConvertibleValue Content {
+      get { return (IStringConvertibleValue)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool ReadOnly {
+      get {
+        if ((Content != null) && Content.ReadOnly) return true;
+        return base.ReadOnly;
+      }
+      set { base.ReadOnly = value; }
+    }
+
+    public bool LabelVisible {
+      get { return !splitContainer.Panel1Collapsed; }
+      set { splitContainer.Panel1Collapsed = !value; }
+    }
+
+    public TextValueView() {
+      InitializeComponent();
+      errorProvider.SetIconAlignment(valueTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconPadding(valueTextBox, 2);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ValueChanged -= new EventHandler(Content_ValueChanged);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ValueChanged += new EventHandler(Content_ValueChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        valueTextBox.Text = string.Empty;
+      } else
+        valueTextBox.Text = Content.GetValue();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      valueTextBox.Enabled = Content != null;
+      valueTextBox.ReadOnly = ReadOnly;
+    }
+
+    protected virtual void Content_ValueChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ValueChanged), sender, e);
+      else
+        valueTextBox.Text = Content.GetValue();
+    }
+
+    protected virtual void valueTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if (e.Shift && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return))
+        valueLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        valueTextBox.Text = Content.GetValue();
+        valueLabel.Select();  // select label to validate data
+      }
+    }
+    protected virtual void valueTextBox_Validating(object sender, CancelEventArgs e) {
+      if (ReadOnly) return;
+      string errorMessage;
+      if (!Content.Validate(valueTextBox.Text, out errorMessage)) {
+        e.Cancel = true;
+        errorProvider.SetError(valueTextBox, errorMessage);
+        valueTextBox.SelectAll();
+      }
+    }
+    protected virtual void valueTextBox_Validated(object sender, EventArgs e) {
+      if (ReadOnly) return;
+      if (!Content.ReadOnly) Content.SetValue(valueTextBox.Text);
+      errorProvider.SetError(valueTextBox, string.Empty);
+      valueTextBox.Text = Content.GetValue();
+    }
+  }
+}
Index: /stable/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj
===================================================================
--- /stable/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 17116)
+++ /stable/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 17117)
@@ -124,4 +124,5 @@
     <Compile Include="ComparisonType.cs" />
     <Compile Include="EnumValue.cs" />
+    <Compile Include="Interfaces\ITextValue.cs" />
     <Compile Include="Interfaces\IValueTypeArray.cs" />
     <Compile Include="Path Types\DirectoryValue.cs" />
@@ -151,4 +152,5 @@
     <Compile Include="StringConvertibleArray.cs" />
     <Compile Include="StringMatrix.cs" />
+    <Compile Include="TextValue.cs" />
     <Compile Include="StringValue.cs" />
     <Compile Include="TimeSpanValue.cs" />
Index: /stable/HeuristicLab.Data/3.3/Interfaces/ITextValue.cs
===================================================================
--- /stable/HeuristicLab.Data/3.3/Interfaces/ITextValue.cs	(revision 17117)
+++ /stable/HeuristicLab.Data/3.3/Interfaces/ITextValue.cs	(revision 17117)
@@ -0,0 +1,28 @@
+#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 HeuristicLab.Common;
+
+namespace HeuristicLab.Data {
+  public interface ITextValue : IStringConvertibleValue {
+  }
+}
Index: /stable/HeuristicLab.Data/3.3/TextValue.cs
===================================================================
--- /stable/HeuristicLab.Data/3.3/TextValue.cs	(revision 17117)
+++ /stable/HeuristicLab.Data/3.3/TextValue.cs	(revision 17117)
@@ -0,0 +1,54 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HEAL.Attic;
+
+namespace HeuristicLab.Data {
+  [Item("TextValue", "Represents a multiline string.")]
+  [StorableType("136E9CD4-D340-44B1-A7CE-CF1A70D1C032")]
+  public class TextValue : StringValue, ITextValue {
+
+    public TextValue() {
+      this.value = string.Empty;
+      this.readOnly = false;
+    }
+
+    public TextValue(string value) {
+      this.value = value ?? string.Empty;
+      this.readOnly = false;
+    }
+
+    [StorableConstructor]
+    protected TextValue(StorableConstructorFlag _) : base(_) { }
+
+    protected TextValue(TextValue original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value ?? string.Empty;
+      this.readOnly = original.readOnly;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TextValue(this, cloner);
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.Designer.cs	(revision 17117)
@@ -0,0 +1,95 @@
+﻿#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 HeuristicLab.Data.Views;
+
+namespace HeuristicLab.ExactOptimization.Views {
+  partial class FileBasedLinearProblemDefinitionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.openButton = new System.Windows.Forms.Button();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.stringConvertibleValueView = new HeuristicLab.Data.Views.StringConvertibleValueView();
+      this.SuspendLayout();
+      // 
+      // openButton
+      // 
+      this.openButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.openButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openButton.Location = new System.Drawing.Point(167, 0);
+      this.openButton.Name = "openButton";
+      this.openButton.Size = new System.Drawing.Size(24, 24);
+      this.openButton.TabIndex = 3;
+      this.openButton.UseVisualStyleBackColor = true;
+      this.openButton.Click += new System.EventHandler(this.openButton_Click);
+      // 
+      // stringConvertibleValueView
+      // 
+      this.stringConvertibleValueView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.stringConvertibleValueView.Caption = "StringConvertibleValue View";
+      this.stringConvertibleValueView.Content = null;
+      this.stringConvertibleValueView.LabelVisible = true;
+      this.stringConvertibleValueView.Location = new System.Drawing.Point(4, 2);
+      this.stringConvertibleValueView.Name = "stringConvertibleValueView";
+      this.stringConvertibleValueView.ReadOnly = false;
+      this.stringConvertibleValueView.Size = new System.Drawing.Size(157, 21);
+      this.stringConvertibleValueView.TabIndex = 0;
+      // 
+      // FileValueView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.stringConvertibleValueView);
+      this.Controls.Add(this.openButton);
+      this.Name = "FileValueView";
+      this.Size = new System.Drawing.Size(194, 24);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button openButton;
+    protected System.Windows.Forms.OpenFileDialog openFileDialog;
+    protected StringConvertibleValueView stringConvertibleValueView;
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/FileBasedLinearProblemDefinitionView.cs	(revision 17117)
@@ -0,0 +1,65 @@
+﻿#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.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.ExactOptimization.LinearProgramming;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.ExactOptimization.Views {
+  [View(nameof(FileBasedLinearProblemDefinitionView))]
+  [Content(typeof(FileBasedLinearProblemDefinition), IsDefaultView = true)]
+  public partial class FileBasedLinearProblemDefinitionView : ItemView {
+    public new FileBasedLinearProblemDefinition Content {
+      get => (FileBasedLinearProblemDefinition)base.Content;
+      set => base.Content = value;
+    }
+
+    public FileBasedLinearProblemDefinitionView() {
+      InitializeComponent();
+      stringConvertibleValueView.LabelVisible = false;
+      stringConvertibleValueView.ReadOnly = true;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      openButton.Enabled = !Locked && !ReadOnly && Content != null;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        stringConvertibleValueView.Content = null;
+        return;
+      }
+
+      stringConvertibleValueView.Content = Content.FileNameParam.Value.StringValue;
+      openFileDialog.Filter = Content.FileNameParam.Value.FileDialogFilter;
+    }
+
+    protected virtual void openButton_Click(object sender, EventArgs e) {
+      openFileDialog.Filter = Content.FileNameParam.Value.FileDialogFilter;
+      if (openFileDialog.ShowDialog(this) != DialogResult.OK) return;
+      Content.FileNameParam.Value.Value = openFileDialog.FileName;
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/HeuristicLab.ExactOptimization.Views-3.3.csproj
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/HeuristicLab.ExactOptimization.Views-3.3.csproj	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/HeuristicLab.ExactOptimization.Views-3.3.csproj	(revision 17117)
@@ -0,0 +1,208 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{D1D69043-17E6-4B8C-BF41-0799C7E56032}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.ExactOptimization.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.ExactOptimization.Views-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <LangVersion>default</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FileBasedLinearProblemDefinitionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FileBasedLinearProblemDefinitionView.Designer.cs">
+      <DependentUpon>FileBasedLinearProblemDefinitionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LinearProgrammingAlgorithmView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="LinearProgrammingAlgorithmView.Designer.cs">
+      <DependentUpon>LinearProgrammingAlgorithmView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LinearProgrammingProblemView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="LinearProgrammingProblemView.Designer.cs">
+      <DependentUpon>LinearProgrammingProblemView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ProgrammableLinearProblemDefinitionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ProgrammableLinearProblemDefinitionView.Designer.cs">
+      <DependentUpon>ProgrammableLinearProblemDefinitionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.CodeEditor\3.4\HeuristicLab.CodeEditor-3.4.csproj">
+      <Project>{C38691AE-ECB4-489A-A05D-B035554E0168}</Project>
+      <Name>HeuristicLab.CodeEditor-3.4</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
+      <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
+      <Name>HeuristicLab.Core.Views-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
+      <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
+      <Name>HeuristicLab.Data.Views-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
+      <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
+      <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
+      <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
+      <Name>HeuristicLab.MainForm-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.ExactOptimization\3.3\HeuristicLab.ExactOptimization-3.3.csproj">
+      <Project>{fa3b9270-48b7-4c77-9fea-2a6ede82e909}</Project>
+      <Name>HeuristicLab.ExactOptimization-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
+      <Project>{662b4b15-8f4d-4ae5-b3eb-d91c215f5af2}</Project>
+      <Name>HeuristicLab.Optimization.Views-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Programmable.Views\3.3\HeuristicLab.Problems.Programmable.Views-3.3.csproj">
+      <Project>{6F023B90-2091-40A9-8AC0-B0338DFF8E5F}</Project>
+      <Name>HeuristicLab.Problems.Programmable.Views-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Programmable\3.3\HeuristicLab.Problems.Programmable-3.3.csproj">
+      <Project>{EE07BFF8-B23D-41F5-8AD7-AC9598D7A2C9}</Project>
+      <Name>HeuristicLab.Problems.Programmable-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Scripting.Views\3.3\HeuristicLab.Scripting.Views-3.3.csproj">
+      <Project>{0C2917C8-7AA8-4E18-800A-C4D064F992ED}</Project>
+      <Name>HeuristicLab.Scripting.Views-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Scripting\3.3\HeuristicLab.Scripting-3.3.csproj">
+      <Project>{21977CC3-1757-4B3B-87BD-FF817AAA900F}</Project>
+      <Name>HeuristicLab.Scripting-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>copy /y "$(TargetPath)" "$(SolutionDir)\bin"</PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.Designer.cs	(revision 17117)
@@ -0,0 +1,159 @@
+﻿using HeuristicLab.Common.Resources;
+
+namespace HeuristicLab.ExactOptimization.Views {
+  partial class LinearProgrammingAlgorithmView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LinearProgrammingAlgorithmView));
+      this.exportModelButton = new System.Windows.Forms.Button();
+      this.saveFileDialog = new System.Windows.Forms.SaveFileDialog();
+      this.showInRunCheckBox = new System.Windows.Forms.CheckBox();
+      this.tabControl.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.problemTabPage.SuspendLayout();
+      this.resultsTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // parametersTabPage
+      // 
+      this.parametersTabPage.Size = new System.Drawing.Size(671, 404);
+      // 
+      // problemTabPage
+      // 
+      this.problemTabPage.Controls.Add(this.showInRunCheckBox);
+      this.problemTabPage.Controls.Add(this.exportModelButton);
+      this.problemTabPage.Controls.SetChildIndex(this.newProblemButton, 0);
+      this.problemTabPage.Controls.SetChildIndex(this.openProblemButton, 0);
+      this.problemTabPage.Controls.SetChildIndex(this.problemViewHost, 0);
+      this.problemTabPage.Controls.SetChildIndex(this.exportModelButton, 0);
+      this.problemTabPage.Controls.SetChildIndex(this.showInRunCheckBox, 0);
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.Size = new System.Drawing.Size(659, 392);
+      // 
+      // problemViewHost
+      // 
+      this.problemViewHost.TabIndex = 4;
+      // 
+      // newProblemButton
+      // 
+      this.toolTip.SetToolTip(this.newProblemButton, "New Programmable Model");
+      // 
+      // openProblemButton
+      // 
+      this.toolTip.SetToolTip(this.openProblemButton, "Import Model From File");
+      // 
+      // resultsTabPage
+      // 
+      this.resultsTabPage.Size = new System.Drawing.Size(671, 404);
+      // 
+      // resultsView
+      // 
+      this.resultsView.Size = new System.Drawing.Size(659, 392);
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Size = new System.Drawing.Size(671, 404);
+      // 
+      // runsView
+      // 
+      this.runsView.Size = new System.Drawing.Size(659, 392);
+      // 
+      // storeAlgorithmInEachRunCheckBox
+      // 
+      this.toolTip.SetToolTip(this.storeAlgorithmInEachRunCheckBox, "Check to store a copy of the algorithm in each run.");
+      // 
+      // startButton
+      // 
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Algorithm");
+      // 
+      // pauseButton
+      // 
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Algorithm");
+      // 
+      // stopButton
+      // 
+      this.toolTip.SetToolTip(this.stopButton, "Stop Algorithm");
+      // 
+      // resetButton
+      // 
+      this.toolTip.SetToolTip(this.resetButton, "Reset Algorithm");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // exportModelButton
+      // 
+      this.exportModelButton.Image = VSImageLibrary.SaveAs;
+      this.exportModelButton.Location = new System.Drawing.Point(66, 6);
+      this.exportModelButton.Name = "exportModelButton";
+      this.exportModelButton.Size = new System.Drawing.Size(24, 24);
+      this.exportModelButton.TabIndex = 2;
+      this.toolTip.SetToolTip(this.exportModelButton, "Export Model To File");
+      this.exportModelButton.UseVisualStyleBackColor = true;
+      this.exportModelButton.Click += new System.EventHandler(this.exportModelButton_Click);
+      // 
+      // showInRunCheckBox
+      // 
+      this.showInRunCheckBox.AutoSize = true;
+      this.showInRunCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.showInRunCheckBox.Location = new System.Drawing.Point(96, 11);
+      this.showInRunCheckBox.Name = "showInRunCheckBox";
+      this.showInRunCheckBox.Size = new System.Drawing.Size(90, 17);
+      this.showInRunCheckBox.TabIndex = 3;
+      this.showInRunCheckBox.Text = "&Show in Run:";
+      this.toolTip.SetToolTip(this.showInRunCheckBox, "Check to show the model in each run.");
+      this.showInRunCheckBox.UseVisualStyleBackColor = true;
+      this.showInRunCheckBox.CheckedChanged += new System.EventHandler(this.showInRunCheckBox_CheckedChanged);
+      // 
+      // LinearProgrammingAlgorithmView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "LinearProgrammingAlgorithmView";
+      this.tabControl.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.problemTabPage.ResumeLayout(false);
+      this.problemTabPage.PerformLayout();
+      this.resultsTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.runsTabPage.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button exportModelButton;
+    private System.Windows.Forms.SaveFileDialog saveFileDialog;
+    protected System.Windows.Forms.CheckBox showInRunCheckBox;
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingAlgorithmView.cs	(revision 17117)
@@ -0,0 +1,62 @@
+﻿using System;
+using System.Windows.Forms;
+using HeuristicLab.ExactOptimization.LinearProgramming;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization.Views;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.ExactOptimization.Views {
+
+  [View(nameof(LinearProgrammingAlgorithmView))]
+  [Content(typeof(LinearProgrammingAlgorithm), IsDefaultView = true)]
+  public partial class LinearProgrammingAlgorithmView : BasicAlgorithmView {
+    public LinearProgrammingAlgorithmView() {
+      InitializeComponent();
+    }
+
+    protected override void newProblemButton_Click(object sender, EventArgs e) {
+      ((LinearProblem)Content.Problem).ProblemDefinition = new ProgrammableLinearProblemDefinition();
+    }
+
+    protected override void openProblemButton_Click(object sender, EventArgs e) {
+      openFileDialog.Title = "Import Model";
+      openFileDialog.Filter = "All Supported Files (*.mps;*.bin;*.prototxt)|*.mps;*.bin;*.prototxt|" +
+                              "Mathematical Programming System Files (*.mps)|*.mps|" +
+                              "Google OR-Tools Protocol Buffers Files (*.bin;*.prototxt)|*.bin;*.prototxt|" +
+                              "All Files (*.*)|*.*";
+
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        newProblemButton.Enabled = openProblemButton.Enabled = false;
+        problemViewHost.Enabled = false;
+
+        try {
+          ((LinearProblem)Content.Problem).ProblemDefinition = new FileBasedLinearProblemDefinition {
+            FileName = openFileDialog.FileName
+          };
+        } catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        } finally {
+          problemViewHost.Enabled = true;
+          newProblemButton.Enabled = openProblemButton.Enabled = true;
+        }
+      }
+    }
+
+    private void exportModelButton_Click(object sender, EventArgs e) {
+      saveFileDialog.Title = "Export Model";
+      saveFileDialog.Filter = "CPLEX LP File (*.lp)|*.lp|" +
+                              "Mathematical Programming System File (*.mps)|*.mps|" +
+                              "Google OR-Tools Protocol Buffers Text File (*.prototxt)|*.prototxt|" +
+                              "Google OR-Tools Protocol Buffers Binary File (*.bin)|*.bin";
+
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        ((LinearProblem)Content.Problem).ExportModel(saveFileDialog.FileName);
+      }
+    }
+
+    private void showInRunCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (Content != null)
+        ((LinearProblem)Content.Problem).ProblemDefinitionParameter.GetsCollected = showInRunCheckBox.Checked;
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.Designer.cs	(revision 17117)
@@ -0,0 +1,97 @@
+﻿#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.ComponentModel;
+using HeuristicLab.Common.Resources;
+
+namespace HeuristicLab.ExactOptimization.Views {
+  partial class LinearProgrammingProblemView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.panel1 = new System.Windows.Forms.Panel();
+      this.ViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.panel1.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // panel1
+      // 
+      this.panel1.Controls.Add(this.ViewHost);
+      this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.panel1.Location = new System.Drawing.Point(0, 0);
+      this.panel1.Name = "panel1";
+      this.panel1.Size = new System.Drawing.Size(300, 150);
+      this.panel1.TabIndex = 7;
+      // 
+      // ViewHost
+      // 
+      this.ViewHost.Caption = "View";
+      this.ViewHost.Content = null;
+      this.ViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.ViewHost.Enabled = false;
+      this.ViewHost.Location = new System.Drawing.Point(0, 0);
+      this.ViewHost.Name = "ViewHost";
+      this.ViewHost.ReadOnly = false;
+      this.ViewHost.Size = new System.Drawing.Size(300, 150);
+      this.ViewHost.TabIndex = 6;
+      this.ViewHost.ViewsLabelVisible = false;
+      this.ViewHost.ViewType = null;
+      // 
+      // LinearProgrammingProblemView
+      // 
+      this.Controls.Add(this.panel1);
+      this.Name = "LinearProgrammingProblemView";
+      this.Size = new System.Drawing.Size(300, 150);
+      this.panel1.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Panel panel1;
+    private MainForm.WindowsForms.ViewHost ViewHost;
+    private System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.Button newProblemDefinitionButton;
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/LinearProgrammingProblemView.cs	(revision 17117)
@@ -0,0 +1,75 @@
+﻿#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 HeuristicLab.Core.Views;
+using HeuristicLab.ExactOptimization.LinearProgramming;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.ExactOptimization.Views {
+
+  [View(nameof(LinearProgrammingProblemView))]
+  [Content(typeof(LinearProblem), IsDefaultView = true)]
+  public partial class LinearProgrammingProblemView : ItemView {
+    protected ViewHost definitionView;
+
+    public LinearProgrammingProblemView() {
+      InitializeComponent();
+      definitionView = ViewHost;
+    }
+
+    public new LinearProblem Content {
+      get => (LinearProblem)base.Content;
+      set => base.Content = value;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.NameChanged -= ContentOnNameChanged;
+      Content.ProblemDefinitionChanged -= ContentOnProblemDefinitionChanged;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        definitionView.Content = null;
+      } else {
+        Caption = Content.Name;
+        ContentOnProblemDefinitionChanged(Content, EventArgs.Empty);
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      Content.ProblemDefinitionChanged += ContentOnProblemDefinitionChanged;
+      Content.NameChanged += ContentOnNameChanged;
+      base.RegisterContentEvents();
+    }
+
+    private void ContentOnNameChanged(object sender, EventArgs eventArgs) {
+      Caption = Content.Name;
+    }
+
+    private void ContentOnProblemDefinitionChanged(object sender, EventArgs eventArgs) {
+      definitionView.Content = ((LinearProblem)sender).ProblemDefinition;
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/Plugin.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/Plugin.cs.frame	(revision 17117)
@@ -0,0 +1,45 @@
+﻿#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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.ExactOptimization {
+
+  [Plugin("HeuristicLab.ExactOptimization.Views", "Views for exact optimization", "3.3.15.$WCREV$")]
+  [PluginFile("HeuristicLab.ExactOptimization.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.CodeEditor", "3.4")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Views", "3.3")]
+  [PluginDependency("HeuristicLab.ExactOptimization", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Programmable", "3.3")]
+  [PluginDependency("HeuristicLab.Scripting", "3.3")]
+  [PluginDependency("HeuristicLab.Scripting.Views", "3.3")]
+  public class HeuristicLabExactOptimizationViewsPlugin : PluginBase {
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.Designer.cs	(revision 17117)
@@ -0,0 +1,179 @@
+﻿#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
+
+
+
+namespace HeuristicLab.ExactOptimization.Views {
+  partial class ProgrammableLinearProblemDefinitionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProgrammableLinearProblemDefinitionView));
+      this.splitContainer2 = new System.Windows.Forms.SplitContainer();
+      this.variableStoreView = new HeuristicLab.Scripting.Views.VariableStoreView();
+      this.infoTabControl.SuspendLayout();
+      this.outputTabPage.SuspendLayout();
+      this.errorListTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+      this.splitContainer1.Panel1.SuspendLayout();
+      this.splitContainer1.Panel2.SuspendLayout();
+      this.splitContainer1.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
+      this.splitContainer2.Panel1.SuspendLayout();
+      this.splitContainer2.Panel2.SuspendLayout();
+      this.splitContainer2.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // compileButton
+      // 
+      this.toolTip.SetToolTip(this.compileButton, "Compile (F6)");
+      // 
+      // infoTabControl
+      // 
+      this.infoTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.infoTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.infoTabControl.Location = new System.Drawing.Point(0, 0);
+      this.infoTabControl.Size = new System.Drawing.Size(572, 113);
+      // 
+      // outputTabPage
+      // 
+      this.outputTabPage.Size = new System.Drawing.Size(564, 87);
+      // 
+      // outputTextBox
+      // 
+      this.outputTextBox.Size = new System.Drawing.Size(558, 81);
+      // 
+      // errorListTabPage
+      // 
+      this.errorListTabPage.Size = new System.Drawing.Size(0, 87);
+      // 
+      // errorListView
+      // 
+      this.errorListView.Size = new System.Drawing.Size(0, 81);
+      // 
+      // codeEditor
+      // 
+      this.codeEditor.Size = new System.Drawing.Size(572, 429);
+      // 
+      // splitContainer1
+      // 
+      this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+      this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer1.Size = new System.Drawing.Size(572, 546);
+      this.splitContainer1.SplitterDistance = 429;
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // splitContainer2
+      // 
+      this.splitContainer2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.splitContainer2.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+      this.splitContainer2.Location = new System.Drawing.Point(6, 56);
+      this.splitContainer2.MinimumSize = new System.Drawing.Size(300, 0);
+      this.splitContainer2.Name = "splitContainer2";
+      // 
+      // splitContainer2.Panel1
+      // 
+      this.splitContainer2.Panel1.Controls.Add(this.splitContainer1);
+      // 
+      // splitContainer2.Panel2
+      // 
+      this.splitContainer2.Panel2.Controls.Add(this.variableStoreView);
+      this.splitContainer2.Panel2MinSize = 250;
+      this.splitContainer2.Size = new System.Drawing.Size(826, 546);
+      this.splitContainer2.SplitterDistance = 572;
+      this.splitContainer2.TabIndex = 10;
+      // 
+      // variableStoreView
+      // 
+      this.variableStoreView.Caption = "ItemCollection View";
+      this.variableStoreView.Content = null;
+      this.variableStoreView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variableStoreView.Location = new System.Drawing.Point(0, 0);
+      this.variableStoreView.Name = "variableStoreView";
+      this.variableStoreView.ReadOnly = true;
+      this.variableStoreView.Size = new System.Drawing.Size(250, 546);
+      this.variableStoreView.TabIndex = 10;
+      // 
+      // ProgrammableLinearProblemDefinitionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer2);
+      this.Name = "ProgrammableLinearProblemDefinitionView";
+      this.Controls.SetChildIndex(this.infoTextLabel, 0);
+      this.Controls.SetChildIndex(this.compileButton, 0);
+      this.Controls.SetChildIndex(this.splitContainer2, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.infoTabControl.ResumeLayout(false);
+      this.outputTabPage.ResumeLayout(false);
+      this.outputTabPage.PerformLayout();
+      this.errorListTabPage.ResumeLayout(false);
+      this.splitContainer1.Panel1.ResumeLayout(false);
+      this.splitContainer1.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+      this.splitContainer1.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.splitContainer2.Panel1.ResumeLayout(false);
+      this.splitContainer2.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
+      this.splitContainer2.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.SplitContainer splitContainer2;
+    private Scripting.Views.VariableStoreView variableStoreView;
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProblemDefinitionView.cs	(revision 17117)
@@ -0,0 +1,71 @@
+﻿#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.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.ExactOptimization.LinearProgramming;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.Programmable;
+using HeuristicLab.Scripting.Views;
+
+namespace HeuristicLab.ExactOptimization.Views {
+
+  [View(nameof(ProgrammableLinearProblemDefinitionView))]
+  [Content(typeof(ProgrammableLinearProblemDefinition), IsDefaultView = true)]
+  public partial class ProgrammableLinearProblemDefinitionView : ScriptView {
+
+    public new ProgrammableLinearProblemDefinition Content {
+      get => (ProgrammableLinearProblemDefinition)base.Content;
+      set => base.Content = value;
+    }
+
+    public ProgrammableLinearProblemDefinitionView() {
+      InitializeComponent();
+      splitContainer2.Panel2MinSize = 25;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      variableStoreView.Content = Content?.VariableStore;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      variableStoreView.Enabled = Content != null && !Locked && !ReadOnly;
+    }
+
+    public override bool Compile() {
+      try {
+        base.Compile();
+      } catch (ProblemDefinitionScriptException e) {
+        PluginInfrastructure.ErrorHandling.ShowErrorDialog(e);
+        return false;
+      }
+      return true;
+    }
+
+    protected override void Content_CodeChanged(object sender, EventArgs e) {
+      base.Content_CodeChanged(sender, e);
+      UpdateInfoTextLabel("Code changed, compilation necessary!", Color.Red);
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProgrammingProblemDefinitionView.resx
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProgrammingProblemDefinitionView.resx	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/ProgrammableLinearProgrammingProblemDefinitionView.resx	(revision 17117)
@@ -0,0 +1,183 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>243, 17</value>
+  </metadata>
+  <metadata name="imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
+    <value>
+        AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+        LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+        ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACG
+        CQAAAk1TRnQBSQFMAgEBAgEAAQgBAAEQAQABEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo
+        AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
+        AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
+        AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
+        AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
+        AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
+        AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
+        ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
+        AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
+        AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
+        AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
+        AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
+        AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
+        AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
+        AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
+        AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
+        ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
+        Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
+        AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
+        AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
+        AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
+        ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
+        Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
+        AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
+        AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
+        AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
+        AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
+        AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
+        AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/0EAAXQHSwUqAikBmQQA
+        ARoBbwFFAUQCIwFLARokAAFLAqAB5QN6A1kBWAM3ATEBSwIAAfQBdAFFAUYEJQEkASMBbwH0IgABGgGZ
+        AqAB5QF6AXkBFAERAVgBWQFYAjcBMQGZAgABkwFMAUYCJgJNASYCJQEjAW8jAAF5A6AB5QF5ARIBFQFR
+        AlkBWAE3AUsCAAEaAW8BTAJNAeMC/wF1ASYCJQEjARoiAAH0AXkDoAF5AXMBUQF5AlkBWAExAfMCAAGZ
+        AUwDTQF1Av8B4wImASUBJAFLIwABeQGaAqABmgEUAUoBeQF6AVkBWAFzAwABdAVNAnUBTQMmASUBIyMA
+        Af8BeQKgARwBEgFDAXkCegFSAfYDAAGTBOMBdQL/Ak0CJgElASMkAAGZAXkBoALrARQBSgF6AVgBmQQA
+        AZMEdQGUAv8BdQFNAiYBJQFEJAAB/wF5AaABEgHsAW0BDgF6AVEB/wQAAZMEdQG9Av8BmgFNAiYBJQFF
+        JQABGwF5AesB7wHsAQ8BWAEaBQABmQGTA5QBvQL/Ab0CTQEmAUYBbyYAAXkBmQHrARIBeQFSBgABGgGT
+        AZQBmgGUAZoC/wGUAk0BRgFFARomAAHzAXkBoAF6AVgB9AcAARoBkwKUAnUB4wJNAkwBdCgAAXkBmQF5
+        ARwIAAH0ARoCkwJ1AeMBTQFMAW8BdAH0KAAB9gFSAUsB/woAARoEkwF0Am9kAAFCAU0BPgcAAT4DAAEo
+        AwABQAMAARADAAEBAQABAQUAAYAXAAP/AQAE/wYAAfABDwYAAcABAwYAAcABAwQAAYABAQGAAQEEAAGA
+        AQEBgAEBBAABwAEDAYABAQQAAcABAwGAAQEEAAHgAQcBgAEBBAAB4AEHAYABAQQAAfABDwGAAQEEAAH4
+        AR8BgAEBBAAB+AEfAcABAwQAAfwBPwHAAQMEAAH8AT8B8AEPBAAE/xoACw==
+</value>
+  </data>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>120, 17</value>
+  </metadata>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>120, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>243, 17</value>
+  </metadata>
+</root>
Index: /stable/HeuristicLab.ExactOptimization.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /stable/HeuristicLab.ExactOptimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristiclLab.ExactOptimization.Views")]
+[assembly: AssemblyDescription("Views for exact optimization")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2019 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("78D3CF45-1EDF-4AF1-B215-EA196A9EC7B1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: /stable/HeuristicLab.ExactOptimization/3.3/HeuristicLab.ExactOptimization-3.3.csproj
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/HeuristicLab.ExactOptimization-3.3.csproj	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/HeuristicLab.ExactOptimization-3.3.csproj	(revision 17117)
@@ -0,0 +1,230 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{FA3B9270-48B7-4C77-9FEA-2A6EDE82E909}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.ExactOptimization</RootNamespace>
+    <AssemblyName>HeuristicLab.ExactOptimization-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <LangVersion>default</LangVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.OrTools, Version=6.9.5866.0, Culture=neutral, PublicKeyToken=5d849a56a8afc8c7, processorArchitecture=AMD64">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\Google.OrTools.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\HEAL.Attic.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LinearProgramming\Algorithms\ResultStatus.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\BopSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\CoinOrSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\ExternalLinearSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\GlopSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\GlpkSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\IExternalLinearSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\IIncrementalLinearSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\ExternalIncrementalLinearSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\IncrementalLinearSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\ProblemType.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\ScipSolver.cs" />
+    <Compile Include="LinearProgramming\Problems\CompiledProblemDefinition.cs" />
+    <Compile Include="LinearProgramming\Problems\FileBasedLinearProblemDefinition.cs" />
+    <Compile Include="LinearProgramming\Problems\LinearProblem.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\CplexSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\GurobiSolver.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\ILinearSolver.cs" />
+    <Compile Include="LinearProgramming\Problems\ILinearProblemDefinition.cs" />
+    <Compile Include="LinearProgramming\Algorithms\LinearProgrammingAlgorithm.cs" />
+    <Compile Include="LinearProgramming\Algorithms\LinearSolverExtensions.cs" />
+    <Compile Include="LinearProgramming\Algorithms\Solvers\Base\LinearSolver.cs" />
+    <Compile Include="LinearProgramming\Problems\ProgrammableLinearProblemDefinition.cs" />
+    <Compile Include="LinearProgramming\Algorithms\ProtoWriteFormat.cs" />
+    <Compile Include="LinearProgramming\Algorithms\SolverResponseStatus.cs" />
+    <Resource Include="LinearProgramming\Templates\CompiledLinearProblemDefinition.cs" />
+    <Compile Include="LinearProgramming\Templates\ScriptTemplates.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>ScriptTemplates.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+    <None Include="app.config">
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <None Include="Properties\Settings.settings">
+      <Generator>PublicSettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="LinearProgramming\Templates\ScriptTemplates.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <SubType>Designer</SubType>
+      <LastGenOutput>ScriptTemplates.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.BinaryVectorEncoding\3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj">
+      <Project>{66D249C3-A01D-42A8-82A2-919BC8EC3D83}</Project>
+      <Name>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Knapsack\3.3\HeuristicLab.Problems.Knapsack-3.3.csproj">
+      <Project>{E10F395F-C8A6-48AD-B470-9AA7A1F43809}</Project>
+      <Name>HeuristicLab.Problems.Knapsack-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Programmable\3.3\HeuristicLab.Problems.Programmable-3.3.csproj">
+      <Project>{EE07BFF8-B23D-41F5-8AD7-AC9598D7A2C9}</Project>
+      <Name>HeuristicLab.Problems.Programmable-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.TravelingSalesman\3.3\HeuristicLab.Problems.TravelingSalesman-3.3.csproj">
+      <Project>{D767C38D-8014-46B0-9A32-03A3AECCE34A}</Project>
+      <Name>HeuristicLab.Problems.TravelingSalesman-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Scripting\3.3\HeuristicLab.Scripting-3.3.csproj">
+      <Project>{21977CC3-1757-4B3B-87BD-FF817AAA900F}</Project>
+      <Name>HeuristicLab.Scripting-3.3</Name>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>copy /y "$(TargetPath)" "$(SolutionDir)\bin"
+copy /y "$(TargetPath).config" "$(SolutionDir)\bin"</PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearProgrammingAlgorithm.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearProgrammingAlgorithm.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearProgrammingAlgorithm.cs	(revision 17117)
@@ -0,0 +1,203 @@
+﻿#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.Threading;
+using Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Mixed-Integer Linear Programming (LP, MIP)", "Linear/mixed integer programming implemented in several solvers. " +
+    "See also https://dev.heuristiclab.com/trac.fcgi/wiki/Documentation/Reference/ExactOptimization")]
+  [Creatable(CreatableAttribute.Categories.ExactAlgorithms)]
+  [StorableType("D6BAE020-6315-4C8A-928F-E47C67F3BE8F")]
+  public sealed class LinearProgrammingAlgorithm : BasicAlgorithm {
+
+    [Storable]
+    private readonly IFixedValueParameter<DoubleValue> dualToleranceParam;
+
+    [Storable]
+    private readonly IFixedValueParameter<BoolValue> presolveParam;
+
+    [Storable]
+    private readonly IFixedValueParameter<DoubleValue> primalToleranceParam;
+
+    [Storable]
+    private readonly IFixedValueParameter<PercentValue> relativeGapToleranceParam;
+
+    [Storable]
+    private readonly IFixedValueParameter<BoolValue> scalingParam;
+
+    [Storable]
+    private readonly IFixedValueParameter<TimeSpanValue> timeLimitParam;
+
+    [Storable]
+    private IConstrainedValueParameter<ILinearSolver> linearSolverParam;
+
+    #region Problem Properties
+
+    public new LinearProblem Problem {
+      get => (LinearProblem)base.Problem;
+      set => base.Problem = value;
+    }
+
+    public override Type ProblemType { get; } = typeof(LinearProblem);
+
+    #endregion
+    #region Parameter Properties
+
+    public IFixedValueParameter<DoubleValue> DualToleranceParameter => dualToleranceParam;
+    public IConstrainedValueParameter<ILinearSolver> LinearSolverParameter => linearSolverParam;
+    public IFixedValueParameter<BoolValue> PresolveParameter => presolveParam;
+    public IFixedValueParameter<DoubleValue> PrimalToleranceParameter => primalToleranceParam;
+    public IFixedValueParameter<PercentValue> RelativeGapToleranceParameter => relativeGapToleranceParam;
+    public IFixedValueParameter<BoolValue> ScalingParameter => scalingParam;
+    public IFixedValueParameter<TimeSpanValue> TimeLimitParameter => timeLimitParam;
+
+    #endregion
+    #region Properties
+
+    public double DualTolerance {
+      get => dualToleranceParam.Value.Value;
+      set => dualToleranceParam.Value.Value = value;
+    }
+
+    public ILinearSolver LinearSolver {
+      get => linearSolverParam.Value;
+      set => linearSolverParam.Value = value;
+    }
+
+    public bool Presolve {
+      get => presolveParam.Value.Value;
+      set => presolveParam.Value.Value = value;
+    }
+
+    public double PrimalTolerance {
+      get => primalToleranceParam.Value.Value;
+      set => primalToleranceParam.Value.Value = value;
+    }
+
+    public double RelativeGapTolerance {
+      get => relativeGapToleranceParam.Value.Value;
+      set => relativeGapToleranceParam.Value.Value = value;
+    }
+
+    public bool Scaling {
+      get => scalingParam.Value.Value;
+      set => scalingParam.Value.Value = value;
+    }
+
+    public override bool SupportsPause => LinearSolver.SupportsPause;
+    public override bool SupportsStop => LinearSolver.SupportsStop;
+
+    public TimeSpan TimeLimit {
+      get => timeLimitParam.Value.Value;
+      set => timeLimitParam.Value.Value = value;
+    }
+
+    #endregion
+
+    public LinearProgrammingAlgorithm() {
+      Parameters.Add(linearSolverParam =
+        new ConstrainedValueParameter<ILinearSolver>(nameof(LinearSolver), "The solver used to solve the model."));
+
+      ILinearSolver defaultSolver;
+      linearSolverParam.ValidValues.Add(defaultSolver = new CoinOrSolver());
+      linearSolverParam.ValidValues.Add(new CplexSolver());
+      linearSolverParam.ValidValues.Add(new GlopSolver());
+      linearSolverParam.ValidValues.Add(new GurobiSolver());
+      linearSolverParam.ValidValues.Add(new ScipSolver());
+      linearSolverParam.Value = defaultSolver;
+
+      Parameters.Add(relativeGapToleranceParam = new FixedValueParameter<PercentValue>(nameof(RelativeGapTolerance),
+        "Limit for relative MIP gap.", new PercentValue(SolverParameters.DefaultRelativeMipGap)));
+      Parameters.Add(timeLimitParam = new FixedValueParameter<TimeSpanValue>(nameof(TimeLimit),
+        "Limit for runtime. Set to zero for unlimited runtime.",
+        new TimeSpanValue(new TimeSpan(0, 1, 0))));
+      Parameters.Add(presolveParam =
+        new FixedValueParameter<BoolValue>(nameof(Presolve), "Advanced usage: presolve mode.",
+          new BoolValue(SolverParameters.DefaultPresolve == SolverParameters.PresolveValues.PresolveOn)) { Hidden = true });
+      Parameters.Add(dualToleranceParam = new FixedValueParameter<DoubleValue>(nameof(DualTolerance),
+        "Advanced usage: tolerance for dual feasibility of basic solutions.",
+        new DoubleValue(SolverParameters.DefaultDualTolerance)) { Hidden = true });
+      Parameters.Add(primalToleranceParam = new FixedValueParameter<DoubleValue>(nameof(PrimalTolerance),
+        "Advanced usage: tolerance for primal feasibility of basic solutions. " +
+        "This does not control the integer feasibility tolerance of integer " +
+        "solutions for MIP or the tolerance used during presolve.",
+        new DoubleValue(SolverParameters.DefaultPrimalTolerance)) { Hidden = true });
+      Parameters.Add(scalingParam = new FixedValueParameter<BoolValue>(nameof(Scaling),
+        "Advanced usage: enable or disable matrix scaling.", new BoolValue()) { Hidden = true });
+
+      Problem = new LinearProblem();
+    }
+
+    [StorableConstructor]
+    private LinearProgrammingAlgorithm(StorableConstructorFlag _) : base(_) { }
+
+    private LinearProgrammingAlgorithm(LinearProgrammingAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      linearSolverParam = cloner.Clone(original.linearSolverParam);
+      relativeGapToleranceParam = cloner.Clone(original.relativeGapToleranceParam);
+      timeLimitParam = cloner.Clone(original.timeLimitParam);
+      presolveParam = cloner.Clone(original.presolveParam);
+      dualToleranceParam = cloner.Clone(original.dualToleranceParam);
+      primalToleranceParam = cloner.Clone(original.primalToleranceParam);
+      scalingParam = cloner.Clone(original.scalingParam);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) => new LinearProgrammingAlgorithm(this, cloner);
+
+    public override void Pause() {
+      base.Pause();
+      LinearSolver.InterruptSolve();
+    }
+
+    public override void Prepare() {
+      base.Prepare();
+      Results.Clear();
+
+      foreach (var solver in linearSolverParam.ValidValues) {
+        solver.Reset();
+      }
+    }
+
+    public override void Stop() {
+      base.Stop();
+      LinearSolver.InterruptSolve();
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      LinearSolver.PrimalTolerance = PrimalTolerance;
+      LinearSolver.DualTolerance = DualTolerance;
+      LinearSolver.Presolve = Presolve;
+      LinearSolver.RelativeGapTolerance = RelativeGapTolerance;
+      LinearSolver.Scaling = Scaling;
+      LinearSolver.TimeLimit = TimeLimit;
+      LinearSolver.Solve(Problem.ProblemDefinition, Results, cancellationToken);
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearSolverExtensions.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearSolverExtensions.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/LinearSolverExtensions.cs	(revision 17117)
@@ -0,0 +1,901 @@
+﻿#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 Google.OrTools.LinearSolver;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public static class LinearSolverExtensions {
+
+    public static bool[] GetSolutionBoolVarArray(this Solver solver, int count, string name) {
+      var array = new bool[count];
+      for (var d1 = 0; d1 < count; d1++) {
+        var varName = $"{name}{d1}";
+        array[d1] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+      }
+
+      return array;
+    }
+
+    public static bool[,] GetSolutionBoolVarArray(this Solver solver, int rows, int cols, string name) {
+      var array = new bool[rows, cols];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          var varName = $"{name}[{d1}, {d2}]";
+          array[d1, d2] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+        }
+      }
+
+      return array;
+    }
+
+    public static bool[,,] GetSolutionBoolVarArray(this Solver solver, int rows, int cols, int dim3, string name) {
+      var array = new bool[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static bool[,,,] GetSolutionBoolVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, string name) {
+      var array = new bool[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static bool[,,,,] GetSolutionBoolVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, int dim5, string name) {
+      var array = new bool[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static bool[,,,,,] GetSolutionBoolVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, int dim5, int dim6, string name) {
+      var array = new bool[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = (int)solver.LookupVariableOrNull(varName).SolutionValue() != 0;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static bool[,] GetSolutionBoolVarMatrix(this Solver solver, int rows, int cols, string name) =>
+      solver.GetSolutionBoolVarArray(rows, cols, name);
+
+    public static int[] GetSolutionIntVarArray(this Solver solver, int count, string name) {
+      var array = new int[count];
+      for (var d1 = 0; d1 < count; d1++) {
+        var varName = $"{name}{d1}";
+        array[d1] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+      }
+
+      return array;
+    }
+
+    public static int[,] GetSolutionIntVarArray(this Solver solver, int rows, int cols, string name) {
+      var array = new int[rows, cols];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          var varName = $"{name}[{d1}, {d2}]";
+          array[d1, d2] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+        }
+      }
+
+      return array;
+    }
+
+    public static int[,,] GetSolutionIntVarArray(this Solver solver, int rows, int cols, int dim3, string name) {
+      var array = new int[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static int[,,,] GetSolutionIntVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, string name) {
+      var array = new int[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static int[,,,,] GetSolutionIntVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, int dim5, string name) {
+      var array = new int[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static int[,,,,,] GetSolutionIntVarArray(this Solver solver,
+        int rows, int cols, int dim3, int dim4, int dim5, int dim6, string name) {
+      var array = new int[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = (int)solver.LookupVariableOrNull(varName).SolutionValue();
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static int[,] GetSolutionIntVarMatrix(this Solver solver, int rows, int cols, string name) =>
+      solver.GetSolutionIntVarArray(rows, cols, name);
+
+    public static double[] GetSolutionNumVarArray(this Solver solver, int count, string name) {
+      var array = new double[count];
+      for (var d1 = 0; d1 < count; d1++) {
+        var varName = $"{name}{d1}";
+        array[d1] = solver.LookupVariableOrNull(varName).SolutionValue();
+      }
+
+      return array;
+    }
+
+    public static double[,] GetSolutionNumVarArray(this Solver solver, int rows, int cols, string name) {
+      var array = new double[rows, cols];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          var varName = $"{name}[{d1}, {d2}]";
+          array[d1, d2] = solver.LookupVariableOrNull(varName).SolutionValue();
+        }
+      }
+
+      return array;
+    }
+
+    public static double[,,] GetSolutionNumVarArray(this Solver solver, int rows, int cols, int dim3, string name) {
+      var array = new double[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = solver.LookupVariableOrNull(varName).SolutionValue();
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static double[,,,] GetSolutionNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, string name) {
+      var array = new double[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = solver.LookupVariableOrNull(varName).SolutionValue();
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static double[,,,,] GetSolutionNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, string name) {
+      var array = new double[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = solver.LookupVariableOrNull(varName).SolutionValue();
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static double[,,,,,] GetSolutionNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, string name) {
+      var array = new double[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = solver.LookupVariableOrNull(varName).SolutionValue();
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static double[,] GetSolutionNumVarMatrix(this Solver solver, int rows, int cols, string name) =>
+      solver.GetSolutionNumVarArray(rows, cols, name);
+
+    public static Variable[,] MakeBoolVarArray(this Solver solver, int rows, int cols) =>
+      solver.MakeBoolVarMatrix(rows, cols);
+
+    public static Variable[,] MakeBoolVarArray(this Solver solver, int rows, int cols, string name) =>
+      solver.MakeBoolVarMatrix(rows, cols, name);
+
+    public static Variable[,,] MakeBoolVarArray(this Solver solver, int rows, int cols, int dim3) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            array[d1, d2, d3] = solver.MakeBoolVar("");
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,] MakeBoolVarArray(this Solver solver, int rows, int cols, int dim3, string name) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = solver.MakeBoolVar(varName);
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              array[d1, d2, d3, d4] = solver.MakeBoolVar("");
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, string name) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = solver.MakeBoolVar(varName);
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                array[d1, d2, d3, d4, d5] = solver.MakeBoolVar("");
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = solver.MakeBoolVar(varName);
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeBoolVar("");
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeBoolVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeBoolVar(varName);
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub) => solver.MakeIntVarMatrix(rows, cols, lb, ub);
+
+    public static Variable[,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub, string name) => solver.MakeIntVarMatrix(rows, cols, lb, ub, name);
+
+    public static Variable[,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            array[d1, d2, d3] = solver.MakeIntVar(lb, ub, "");
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = solver.MakeIntVar(lb, ub, varName);
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              array[d1, d2, d3, d4] = solver.MakeIntVar(lb, ub, "");
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = solver.MakeIntVar(lb, ub, varName);
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                array[d1, d2, d3, d4, d5] = solver.MakeIntVar(lb, ub, "");
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = solver.MakeIntVar(lb, ub, varName);
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeIntVar(lb, ub, "");
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeIntVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeIntVar(lb, ub, varName);
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub) => solver.MakeNumVarMatrix(rows, cols, lb, ub);
+
+    public static Variable[,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub, string name) =>
+      solver.MakeNumVarMatrix(rows, cols, lb, ub, name);
+
+    public static Variable[,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            array[d1, d2, d3] = solver.MakeNumVar(lb, ub, "");
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = solver.MakeNumVar(lb, ub, varName);
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              array[d1, d2, d3, d4] = solver.MakeNumVar(lb, ub, "");
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = solver.MakeNumVar(lb, ub, varName);
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                array[d1, d2, d3, d4, d5] = solver.MakeNumVar(lb, ub, "");
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = solver.MakeNumVar(lb, ub, varName);
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeNumVar(lb, ub, "");
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeNumVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeNumVar(lb, ub, varName);
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,] MakeVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub, bool integer) =>
+      solver.MakeVarMatrix(rows, cols, lb, ub, integer);
+
+    public static Variable[,] MakeVarArray(this Solver solver,
+      int rows, int cols, double lb, double ub, bool integer, string name) =>
+      solver.MakeVarMatrix(rows, cols, lb, ub, integer, name);
+
+    public static Variable[,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub, bool integer) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            array[d1, d2, d3] = solver.MakeVar(lb, ub, integer, "");
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, double lb, double ub, bool integer, string name) {
+      var array = new Variable[rows, cols, dim3];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            var varName = $"{name}[{d1}, {d2}, {d3}]";
+            array[d1, d2, d3] = solver.MakeVar(lb, ub, integer, varName);
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub, bool integer) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              array[d1, d2, d3, d4] = solver.MakeVar(lb, ub, integer, "");
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, double lb, double ub, bool integer, string name) {
+      var array = new Variable[rows, cols, dim3, dim4];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              var varName = $"{name}[{d1}, {d2}, {d3}, {d4}]";
+              array[d1, d2, d3, d4] = solver.MakeVar(lb, ub, integer, varName);
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub, bool integer) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                array[d1, d2, d3, d4, d5] = solver.MakeVar(lb, ub, integer, "");
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, double lb, double ub, bool integer, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}]";
+                array[d1, d2, d3, d4, d5] = solver.MakeVar(lb, ub, integer, varName);
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub, bool integer) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeVar(lb, ub, integer, "");
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+
+    public static Variable[,,,,,] MakeVarArray(this Solver solver,
+      int rows, int cols, int dim3, int dim4, int dim5, int dim6, double lb, double ub, bool integer, string name) {
+      var array = new Variable[rows, cols, dim3, dim4, dim5, dim6];
+      for (var d1 = 0; d1 < rows; d1++) {
+        for (var d2 = 0; d2 < cols; d2++) {
+          for (var d3 = 0; d3 < cols; d3++) {
+            for (var d4 = 0; d4 < cols; d4++) {
+              for (var d5 = 0; d5 < cols; d5++) {
+                for (var d6 = 0; d6 < cols; d6++) {
+                  var varName = $"{name}[{d1}, {d2}, {d3}, {d4}, {d5}, {d6}]";
+                  array[d1, d2, d3, d4, d5, d6] = solver.MakeVar(lb, ub, integer, varName);
+                }
+              }
+            }
+          }
+        }
+      }
+
+      return array;
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProblemType.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProblemType.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProblemType.cs	(revision 17117)
@@ -0,0 +1,28 @@
+﻿#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
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public enum ProblemType {
+    LinearProgramming,
+    MixedIntegerProgramming
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProtoWriteFormat.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProtoWriteFormat.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ProtoWriteFormat.cs	(revision 17117)
@@ -0,0 +1,29 @@
+﻿#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
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public enum ProtoWriteFormat {
+    ProtoText,
+    ProtoBinary,
+    Json
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ResultStatus.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ResultStatus.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/ResultStatus.cs	(revision 17117)
@@ -0,0 +1,13 @@
+﻿namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public enum ResultStatus {
+    Optimal,        // optimal.
+    Feasible,       // feasible, or stopped by limit.
+    Infeasible,     // proven infeasible.
+    Unbounded,      // proven unbounded.
+    Abnormal,       // abnormal, i.e., error of some kind.
+    ModelInvalid,   // the model is trivially invalid (NaN coefficients, etc).
+    NotSolved = 6,  // not been solved yet.
+    OptimalWithinTolerance = int.MaxValue  // optimal within gap tolerance but objective != bound
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/SolverResponseStatus.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/SolverResponseStatus.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/SolverResponseStatus.cs	(revision 17117)
@@ -0,0 +1,40 @@
+﻿#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 Google.OrTools.LinearSolver;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public enum SolverResponseStatus {
+    Optimal = 0,
+    Feasible = 1,
+    Infeasible = 2,
+    Unbounded = 3,
+    Abnormal = 4,
+    ModelInvalid = 5,
+    NotSolved = 6,
+    SolverTypeUnavailable = 7,
+    ModelInvalidSolutionHint = 84,
+    ModelInvalidSolverParameters = 85,
+    ModelIsValid = 97,
+    UnknownStatus = 99
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalIncrementalLinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalIncrementalLinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalIncrementalLinearSolver.cs	(revision 17117)
@@ -0,0 +1,58 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [StorableType("CF3FC8B1-37DF-4A08-9DE5-AB578E1132DD")]
+  public class ExternalIncrementalLinearSolver : IncrementalLinearSolver, IExternalLinearSolver {
+    protected const string FileDialogFilter = "Dynamic-Link Library (*.dll)|*.dll|All Files (*.*)|*.*";
+
+    [Storable]
+    protected IFixedValueParameter<FileValue> libraryNameParam;
+
+    public ExternalIncrementalLinearSolver() {
+    }
+
+    [StorableConstructor]
+    protected ExternalIncrementalLinearSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected ExternalIncrementalLinearSolver(ExternalIncrementalLinearSolver original, Cloner cloner)
+      : base(original, cloner) {
+      libraryNameParam = cloner.Clone(original.libraryNameParam);
+    }
+
+    public string LibraryName {
+      get => libraryNameParam?.Value.Value;
+      set => libraryNameParam.Value.Value = value;
+    }
+
+    public IFixedValueParameter<FileValue> LibraryNameParameter => libraryNameParam;
+
+    protected override Solver CreateSolver(Solver.OptimizationProblemType optimizationProblemType,
+      string libraryName = null) => base.CreateSolver(optimizationProblemType, LibraryName);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalLinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalLinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ExternalLinearSolver.cs	(revision 17117)
@@ -0,0 +1,58 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [StorableType("612FCAEF-ABB9-48CC-9041-2B871B831C3C")]
+  public class ExternalLinearSolver : LinearSolver, IExternalLinearSolver {
+    protected const string FileDialogFilter = "Dynamic-Link Library (*.dll)|*.dll|All Files (*.*)|*.*";
+
+    [Storable]
+    protected IFixedValueParameter<FileValue> libraryNameParam;
+
+    public ExternalLinearSolver() {
+    }
+
+    [StorableConstructor]
+    protected ExternalLinearSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected ExternalLinearSolver(ExternalLinearSolver original, Cloner cloner)
+      : base(original, cloner) {
+      libraryNameParam = cloner.Clone(original.libraryNameParam);
+    }
+
+    public string LibraryName {
+      get => libraryNameParam?.Value.Value;
+      set => libraryNameParam.Value.Value = value;
+    }
+
+    public IFixedValueParameter<FileValue> LibraryNameParameter => libraryNameParam;
+
+    protected override Solver CreateSolver(Solver.OptimizationProblemType optimizationProblemType,
+      string libraryName = null) => base.CreateSolver(optimizationProblemType, LibraryName);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IExternalLinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IExternalLinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IExternalLinearSolver.cs	(revision 17117)
@@ -0,0 +1,27 @@
+﻿#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
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public interface IExternalLinearSolver : ILinearSolver {
+    string LibraryName { get; set; }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IIncrementalLinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IIncrementalLinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IIncrementalLinearSolver.cs	(revision 17117)
@@ -0,0 +1,30 @@
+﻿#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;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public interface IIncrementalLinearSolver : ILinearSolver {
+    TimeSpan QualityUpdateInterval { get; set; }
+    bool SupportsQualityUpdate { get; }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ILinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ILinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/ILinearSolver.cs	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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.Threading;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public interface ILinearSolver : IParameterizedNamedItem {
+    double DualTolerance { get; set; }
+
+    bool Presolve { get; set; }
+
+    double PrimalTolerance { get; set; }
+
+    ProblemType ProblemType { get; }
+
+    double RelativeGapTolerance { get; set; }
+
+    bool Scaling { get; set; }
+
+    bool SupportsPause { get; }
+
+    bool SupportsStop { get; }
+
+    TimeSpan TimeLimit { get; set; }
+
+    bool InterruptSolve();
+
+    void Reset();
+
+    void Solve(ILinearProblemDefinition problemDefintion, ResultCollection results);
+
+    void Solve(ILinearProblemDefinition problemDefintion,
+      ResultCollection results, CancellationToken cancellationToken);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalLinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalLinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/IncrementalLinearSolver.cs	(revision 17117)
@@ -0,0 +1,192 @@
+﻿#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.Diagnostics;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [StorableType("8730ECDD-8F38-47C2-B0D9-2B1F38FC0A27")]
+  public class IncrementalLinearSolver : LinearSolver, IIncrementalLinearSolver {
+
+    [Storable]
+    protected readonly IValueParameter<TimeSpanValue> qualityUpdateIntervalParam;
+
+    private readonly Stopwatch stopwatch = new Stopwatch();
+
+    [Storable]
+    private TimeSpan executionTime = TimeSpan.Zero;
+
+    [Storable]
+    private IndexedDataTable<double> qualityPerClock;
+
+    public IncrementalLinearSolver() {
+      Parameters.Add(qualityUpdateIntervalParam =
+        new ValueParameter<TimeSpanValue>(nameof(QualityUpdateInterval),
+          "Time interval before solver is paused, results are retrieved and solver is resumed. " +
+          "Set to zero for no intermediate results and faster solving.", new TimeSpanValue(new TimeSpan(0, 0, 10))));
+      problemTypeParam.Value.ValueChanged += (sender, args) => {
+        if (SupportsQualityUpdate) {
+          if (!Parameters.Contains(qualityUpdateIntervalParam)) {
+            Parameters.Add(qualityUpdateIntervalParam);
+          }
+        } else {
+          Parameters.Remove(qualityUpdateIntervalParam);
+        }
+      };
+    }
+
+    [StorableConstructor]
+    protected IncrementalLinearSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected IncrementalLinearSolver(IncrementalLinearSolver original, Cloner cloner)
+      : base(original, cloner) {
+      problemTypeParam = cloner.Clone(original.problemTypeParam);
+      qualityUpdateIntervalParam = cloner.Clone(original.qualityUpdateIntervalParam);
+      if (original.qualityPerClock != null)
+        qualityPerClock = cloner.Clone(original.qualityPerClock);
+    }
+
+    public TimeSpan QualityUpdateInterval {
+      get => qualityUpdateIntervalParam.Value.Value;
+      set => qualityUpdateIntervalParam.Value.Value = value;
+    }
+
+    public IValueParameter<TimeSpanValue> QualityUpdateIntervalParameter => qualityUpdateIntervalParam;
+
+    public virtual bool SupportsQualityUpdate => true;
+
+    protected virtual TimeSpan IntermediateTimeLimit => QualityUpdateInterval;
+
+    public override void Reset() {
+      base.Reset();
+      executionTime = TimeSpan.Zero;
+    }
+
+    public override void Solve(ILinearProblemDefinition problemDefinition,
+      ResultCollection results, CancellationToken cancellationToken) {
+      if (!SupportsQualityUpdate || QualityUpdateInterval == TimeSpan.Zero) {
+        base.Solve(problemDefinition, results, cancellationToken);
+        return;
+      }
+
+      var timeLimit = TimeLimit;
+      var unlimitedRuntime = timeLimit == TimeSpan.Zero;
+
+      if (!unlimitedRuntime) {
+        timeLimit -= executionTime;
+      }
+
+      var iterations = (long)timeLimit.TotalMilliseconds / (long)QualityUpdateInterval.TotalMilliseconds;
+      var remaining = timeLimit - TimeSpan.FromMilliseconds(iterations * QualityUpdateInterval.TotalMilliseconds);
+      var validResultStatuses = new[] { ResultStatus.NotSolved, ResultStatus.Feasible };
+
+      while (unlimitedRuntime || iterations > 0) {
+        if (cancellationToken.IsCancellationRequested)
+          return;
+
+        stopwatch.Restart();
+        Solve(problemDefinition, results, IntermediateTimeLimit);
+        stopwatch.Stop();
+        executionTime += stopwatch.Elapsed;
+        UpdateQuality(results, executionTime);
+
+        var resultStatus = ((EnumValue<ResultStatus>)results["ResultStatus"].Value).Value;
+        if (!validResultStatuses.Contains(resultStatus))
+          return;
+
+        if (!unlimitedRuntime)
+          iterations--;
+      }
+
+      if (remaining > TimeSpan.Zero) {
+        Solve(problemDefinition, results, remaining);
+        UpdateQuality(results, executionTime);
+      }
+    }
+
+    private void UpdateQuality(ResultCollection results, TimeSpan executionTime) {
+      IndexedDataRow<double> qpcRow;
+      IndexedDataRow<double> bpcRow;
+
+      if (!results.Exists(r => r.Name == "QualityPerClock")) {
+        qualityPerClock = new IndexedDataTable<double>("Quality per Clock");
+        qpcRow = new IndexedDataRow<double>("Objective Value");
+        bpcRow = new IndexedDataRow<double>("Bound");
+        qualityPerClock.Rows.Add(qpcRow);
+        qualityPerClock.Rows.Add(bpcRow);
+        results.AddOrUpdateResult("QualityPerClock", qualityPerClock);
+      } else {
+        qpcRow = qualityPerClock.Rows["Objective Value"];
+        bpcRow = qualityPerClock.Rows["Bound"];
+      }
+
+      var resultStatus = ((EnumValue<ResultStatus>)results["ResultStatus"].Value).Value;
+
+      if (new[] { ResultStatus.Abnormal, ResultStatus.NotSolved, ResultStatus.Unbounded }.Contains(resultStatus))
+        return;
+
+      var objective = ((DoubleValue)results["BestObjectiveValue"].Value).Value;
+      var bound = solver.IsMip() ? ((DoubleValue)results["BestObjectiveBound"].Value).Value : double.NaN;
+      var time = executionTime.TotalSeconds;
+
+      if (!qpcRow.Values.Any()) {
+        if (!double.IsInfinity(objective) && !double.IsNaN(objective)) {
+          qpcRow.Values.Add(Tuple.Create(time, objective));
+          qpcRow.Values.Add(Tuple.Create(time, objective));
+          results.AddOrUpdateResult("BestObjectiveValueFoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));
+        }
+      } else {
+        var previousBest = qpcRow.Values.Last().Item2;
+        qpcRow.Values[qpcRow.Values.Count - 1] = Tuple.Create(time, objective);
+        if (!objective.IsAlmost(previousBest)) {
+          qpcRow.Values.Add(Tuple.Create(time, objective));
+          results.AddOrUpdateResult("BestObjectiveValueFoundAt", new TimeSpanValue(TimeSpan.FromSeconds(time)));
+        }
+      }
+
+      if (!solver.IsMip())
+        return;
+
+      if (!bpcRow.Values.Any()) {
+        if (!double.IsInfinity(bound) && !double.IsNaN(bound)) {
+          bpcRow.Values.Add(Tuple.Create(time, bound));
+          bpcRow.Values.Add(Tuple.Create(time, bound));
+        }
+      } else {
+        var previousBest = bpcRow.Values.Last().Item2;
+        bpcRow.Values[bpcRow.Values.Count - 1] = Tuple.Create(time, bound);
+        if (!bound.IsAlmost(previousBest)) {
+          bpcRow.Values.Add(Tuple.Create(time, bound));
+        }
+      }
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/LinearSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/LinearSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/Base/LinearSolver.cs	(revision 17117)
@@ -0,0 +1,248 @@
+﻿#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.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [StorableType("D0657902-BE8B-4826-B832-FDA84E9B24C3")]
+  public class LinearSolver : ParameterizedNamedItem, ILinearSolver, IDisposable {
+
+    [Storable]
+    protected IValueParameter<EnumValue<ProblemType>> problemTypeParam;
+
+    protected Solver solver;
+
+    [Storable]
+    protected IFixedValueParameter<TextValue> solverSpecificParametersParam;
+
+    public static string LogDirectory { get; }
+
+    static LinearSolver() {
+      var solver = new Solver("", Solver.OptimizationProblemType.CbcMixedIntegerProgramming);
+      LogDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
+      Directory.CreateDirectory(LogDirectory);
+      solver.InitLogging(Assembly.GetExecutingAssembly().Location, LogDirectory);
+    }
+
+    public LinearSolver() {
+      Parameters.Add(problemTypeParam =
+        new ValueParameter<EnumValue<ProblemType>>(nameof(ProblemType),
+          new EnumValue<ProblemType>(ProblemType.MixedIntegerProgramming)));
+      Parameters.Add(solverSpecificParametersParam =
+        new FixedValueParameter<TextValue>(nameof(SolverSpecificParameters), new TextValue()));
+    }
+
+    [StorableConstructor]
+    protected LinearSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected LinearSolver(LinearSolver original, Cloner cloner)
+      : base(original, cloner) {
+      problemTypeParam = cloner.Clone(original.problemTypeParam);
+      solverSpecificParametersParam = cloner.Clone(original.solverSpecificParametersParam);
+    }
+
+    public double DualTolerance { get; set; } = SolverParameters.DefaultDualTolerance;
+
+    public bool Incrementality { get; set; } =
+      SolverParameters.DefaultIncrementality == SolverParameters.IncrementalityValues.IncrementalityOn;
+
+    public SolverParameters.LpAlgorithmValues LpAlgorithm { get; set; }
+    protected virtual Solver.OptimizationProblemType OptimizationProblemType { get; }
+    public bool Presolve { get; set; } = SolverParameters.DefaultPresolve == SolverParameters.PresolveValues.PresolveOn;
+    public double PrimalTolerance { get; set; } = SolverParameters.DefaultPrimalTolerance;
+
+    public ProblemType ProblemType {
+      get => problemTypeParam.Value.Value;
+      set => problemTypeParam.Value.Value = value;
+    }
+
+    public IValueParameter<EnumValue<ProblemType>> ProblemTypeParameter => problemTypeParam;
+    public double RelativeGapTolerance { get; set; } = SolverParameters.DefaultRelativeMipGap;
+    public bool Scaling { get; set; }
+
+    public string SolverSpecificParameters {
+      get => solverSpecificParametersParam.Value.Value;
+      set => solverSpecificParametersParam.Value.Value = value;
+    }
+
+    public IFixedValueParameter<TextValue> SolverSpecificParametersParameter => solverSpecificParametersParam;
+    public virtual bool SupportsPause => true;
+    public virtual bool SupportsStop => true;
+    public virtual TimeSpan TimeLimit { get; set; } = TimeSpan.Zero;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new LinearSolver(this, cloner);
+
+    public void Dispose() => solver?.Dispose();
+
+    public bool ExportAsLp(string fileName, bool obfuscated = false) {
+      var lpFormat = solver?.ExportModelAsLpFormat(obfuscated);
+      if (string.IsNullOrEmpty(lpFormat))
+        return false;
+      File.WriteAllText(fileName, lpFormat);
+      return true;
+    }
+
+    public bool ExportAsMps(string fileName, bool fixedFormat = false, bool obfuscated = false) {
+      var mpsFormat = solver?.ExportModelAsMpsFormat(fixedFormat, obfuscated);
+      if (string.IsNullOrEmpty(mpsFormat))
+        return false;
+      File.WriteAllText(fileName, mpsFormat);
+      return true;
+    }
+
+    public bool ExportAsProto(string fileName, ProtoWriteFormat writeFormat = ProtoWriteFormat.ProtoBinary) =>
+      solver != null && solver.ExportModelAsProtoFormat(fileName, (Google.OrTools.LinearSolver.ProtoWriteFormat)writeFormat);
+
+    public MPSolverResponseStatus ImportFromMps(string fileName, bool? fixedFormat) =>
+      solver?.ImportModelFromMpsFormat(fileName, fixedFormat.HasValue, fixedFormat ?? false) ??
+      (MPSolverResponseStatus)SolverResponseStatus.Abnormal;
+
+    public MPSolverResponseStatus ImportFromProto(string fileName) =>
+      solver?.ImportModelFromProtoFormat(fileName) ?? (MPSolverResponseStatus)SolverResponseStatus.Abnormal;
+
+    public bool InterruptSolve() => solver?.InterruptSolve() ?? false;
+
+    public virtual void Reset() {
+      solver?.Dispose();
+      solver = null;
+    }
+
+    public virtual void Solve(ILinearProblemDefinition problemDefintion,
+      ResultCollection results, CancellationToken cancellationToken) =>
+      Solve(problemDefintion, results);
+
+    public virtual void Solve(ILinearProblemDefinition problemDefinition,
+      ResultCollection results) =>
+      Solve(problemDefinition, results, TimeLimit);
+
+    public virtual void Solve(ILinearProblemDefinition problemDefinition, ResultCollection results,
+      TimeSpan timeLimit) {
+      if (solver == null) {
+        solver = CreateSolver(OptimizationProblemType);
+        problemDefinition.BuildModel(solver);
+      }
+
+      if (timeLimit > TimeSpan.Zero) {
+        solver.SetTimeLimit((long)timeLimit.TotalMilliseconds);
+      } else {
+        solver.SetTimeLimit(0);
+      }
+
+      ResultStatus resultStatus;
+
+      using (var parameters = new SolverParameters()) {
+        parameters.SetDoubleParam(SolverParameters.DoubleParam.RelativeMipGap, RelativeGapTolerance);
+        parameters.SetDoubleParam(SolverParameters.DoubleParam.PrimalTolerance, PrimalTolerance);
+        parameters.SetDoubleParam(SolverParameters.DoubleParam.DualTolerance, DualTolerance);
+        parameters.SetIntegerParam(SolverParameters.IntegerParam.Presolve,
+          (int)(Presolve ? SolverParameters.PresolveValues.PresolveOn : SolverParameters.PresolveValues.PresolveOff));
+        parameters.SetIntegerParam(SolverParameters.IntegerParam.Incrementality,
+          (int)(Incrementality ? SolverParameters.IncrementalityValues.IncrementalityOn : SolverParameters.IncrementalityValues.IncrementalityOff));
+        parameters.SetIntegerParam(SolverParameters.IntegerParam.Scaling,
+          (int)(Scaling ? SolverParameters.ScalingValues.ScalingOn : SolverParameters.ScalingValues.ScalingOff));
+
+        if (!solver.SetSolverSpecificParametersAsString(SolverSpecificParameters))
+          throw new ArgumentException("Solver specific parameters could not be set. " +
+            $"For details, see the log files in '{LogDirectory}'.");
+
+        resultStatus = (ResultStatus)solver.Solve(parameters);
+      }
+
+      var objectiveValue = solver.Objective()?.Value();
+
+      problemDefinition.Analyze(solver, results);
+
+      if (solver.IsMip()) {
+        var objectiveBound = solver.Objective()?.BestBound();
+        var absoluteGap = objectiveValue.HasValue && objectiveBound.HasValue
+          ? Math.Abs(objectiveBound.Value - objectiveValue.Value)
+          : (double?)null;
+        // https://www.ibm.com/support/knowledgecenter/SSSA5P_12.7.1/ilog.odms.cplex.help/CPLEX/Parameters/topics/EpGap.html
+        var relativeGap = absoluteGap.HasValue && objectiveValue.HasValue
+          ? absoluteGap.Value / (1e-10 + Math.Abs(objectiveValue.Value))
+          : (double?)null;
+
+        if (resultStatus == ResultStatus.Optimal && absoluteGap.HasValue && !absoluteGap.Value.IsAlmost(0)) {
+          resultStatus = ResultStatus.OptimalWithinTolerance;
+        }
+
+        results.AddOrUpdateResult("BestObjectiveBound", new DoubleValue(objectiveBound ?? double.NaN));
+        results.AddOrUpdateResult("AbsoluteGap", new DoubleValue(absoluteGap ?? double.NaN));
+        results.AddOrUpdateResult("RelativeGap", new PercentValue(relativeGap ?? double.NaN));
+      }
+
+      results.AddOrUpdateResult("ResultStatus", new EnumValue<ResultStatus>(resultStatus));
+      results.AddOrUpdateResult("BestObjectiveValue", new DoubleValue(objectiveValue ?? double.NaN));
+
+      results.AddOrUpdateResult("NumberOfConstraints", new IntValue(solver.NumConstraints()));
+      results.AddOrUpdateResult("NumberOfVariables", new IntValue(solver.NumVariables()));
+
+      if (solver.IsMip() && solver.Nodes() >= 0) {
+        results.AddOrUpdateResult(nameof(solver.Nodes), new DoubleValue(solver.Nodes()));
+      }
+
+      if (solver.Iterations() >= 0) {
+        results.AddOrUpdateResult(nameof(solver.Iterations), new DoubleValue(solver.Iterations()));
+      }
+
+      results.AddOrUpdateResult(nameof(solver.SolverVersion), new StringValue(solver.SolverVersion()));
+    }
+
+    protected virtual Solver CreateSolver(Solver.OptimizationProblemType optimizationProblemType, string libraryName = null) {
+      if (!string.IsNullOrEmpty(libraryName) && !File.Exists(libraryName)) {
+        var paths = new List<string> {
+          Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath)
+        };
+        var path = Environment.GetEnvironmentVariable("PATH");
+        if (path != null)
+          paths.AddRange(path.Split(';'));
+        if (!paths.Any(p => File.Exists(Path.Combine(p, libraryName))))
+          throw new FileNotFoundException($"Could not find library {libraryName} in PATH.", libraryName);
+      }
+
+      try {
+        solver = new Solver(Name, optimizationProblemType, libraryName ?? string.Empty);
+      } catch {
+        solver = null;
+      }
+
+      if (solver == null)
+        throw new InvalidOperationException($"Could not create {optimizationProblemType}. " +
+          $"For details, see the log files in '{LogDirectory}'.");
+
+      solver.SuppressOutput();
+      return solver;
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/BopSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/BopSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/BopSolver.cs	(revision 17117)
@@ -0,0 +1,58 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("BOP", "BOP (https://developers.google.com/optimization/reference/bop/bop_solver/) can be used out of the box.")]
+  [StorableType("6AE85366-34FC-42C3-B1A3-BFC976CCE830")]
+  public class BopSolver : IncrementalLinearSolver {
+
+    public BopSolver() {
+      Parameters.Remove(problemTypeParam);
+      Parameters.Add(new FixedValueParameter<StringValue>(nameof(ProblemType), new StringValue("ZeroOneProgramming").AsReadOnly()));
+      SolverSpecificParameters =
+        "# for file format, see Protocol Buffers text format (https://developers.google.com/protocol-buffers/docs/overview#whynotxml)" + Environment.NewLine +
+        "# for parameters, see https://github.com/google/or-tools/blob/v6.10/ortools/bop/bop_parameters.proto" + Environment.NewLine +
+        "# example:" + Environment.NewLine +
+        "# random_seed: 10" + Environment.NewLine;
+    }
+
+    protected BopSolver(BopSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected BopSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      Solver.OptimizationProblemType.BopIntegerProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new BopSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CoinOrSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CoinOrSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CoinOrSolver.cs	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Clp/Cbc", "Clp (https://projects.coin-or.org/Clp) and Cbc (https://projects.coin-or.org/Cbc) can be used out of the box.")]
+  [StorableType("53148A15-C754-4CCA-AFAA-200916CDB7F5")]
+  public class CoinOrSolver : IncrementalLinearSolver {
+
+    public CoinOrSolver() {
+      Parameters.Remove(solverSpecificParametersParam);
+    }
+
+    protected CoinOrSolver(CoinOrSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected CoinOrSolver(StorableConstructorFlag _) : base(_) { }
+
+    public override bool SupportsPause => false;
+
+    public override bool SupportsQualityUpdate => ProblemType == ProblemType.LinearProgramming;
+
+    public override bool SupportsStop => false;
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      ProblemType == ProblemType.LinearProgramming
+        ? Solver.OptimizationProblemType.ClpLinearProgramming
+        : Solver.OptimizationProblemType.CbcMixedIntegerProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new CoinOrSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CplexSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CplexSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/CplexSolver.cs	(revision 17117)
@@ -0,0 +1,64 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("CPLEX", "CPLEX (https://www.ibm.com/analytics/cplex-optimizer) must be installed and licensed.")]
+  [StorableType("E3478254-F3A8-4085-A9DA-DB79D0A50347")]
+  public class CplexSolver : ExternalIncrementalLinearSolver {
+
+    public CplexSolver() {
+      Parameters.Add(libraryNameParam = new FixedValueParameter<FileValue>(nameof(LibraryName),
+        new FileValue { FileDialogFilter = FileDialogFilter, Value = Properties.Settings.Default.CplexLibraryName }));
+      SolverSpecificParameters =
+        "CPLEX Parameter File Version 12.8.0" + Environment.NewLine +
+        "# for file format, see https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.cplex.help/CPLEX/FileFormats/topics/PRM.html" + Environment.NewLine +
+        "# for parameters, see https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.cplex.help/CPLEX/Parameters/topics/introListTopical.html" + Environment.NewLine +
+        "# examples:" + Environment.NewLine +
+        "# CPXPARAM_RandomSeed 10" + Environment.NewLine +
+        "# CPXPARAM_LPMethod 4 # Barrier (LP)" + Environment.NewLine +
+        "# CPXPARAM_MIP_Strategy_SubAlgorithm 4 # Barrier (MIP)" + Environment.NewLine +
+        "# CPXPARAM_MIP_Strategy_Search 2 # Apply dynamic search (MIP)" + Environment.NewLine;
+    }
+
+    [StorableConstructor]
+    protected CplexSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected CplexSolver(CplexSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      ProblemType == ProblemType.LinearProgramming
+        ? Solver.OptimizationProblemType.CplexLinearProgramming
+        : Solver.OptimizationProblemType.CplexMixedIntegerProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new CplexSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlopSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlopSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlopSolver.cs	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Glop", "Glop (https://developers.google.com/optimization/lp/glop) can be used out of the box.")]
+  [StorableType("A05DA123-2779-4175-991E-C4790C5C2E00")]
+  public class GlopSolver : IncrementalLinearSolver {
+
+    public GlopSolver() {
+      problemTypeParam.Value = (EnumValue<ProblemType>)new EnumValue<ProblemType>(ProblemType.LinearProgramming).AsReadOnly();
+      SolverSpecificParameters =
+        "# for file format, see Protocol Buffers text format (https://developers.google.com/protocol-buffers/docs/overview#whynotxml)" + Environment.NewLine +
+        "# for parameters, see https://github.com/google/or-tools/blob/v6.10/ortools/glop/parameters.proto" + Environment.NewLine +
+        "# examples:" + Environment.NewLine +
+        "# random_seed: 10" + Environment.NewLine +
+        "# use_dual_simplex: true # Dual Simplex (LP)" + Environment.NewLine;
+    }
+
+    [StorableConstructor]
+    protected GlopSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected GlopSolver(GlopSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      Solver.OptimizationProblemType.GlopLinearProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new GlopSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlpkSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlpkSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GlpkSolver.cs	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("GLPK", "GLPK (https://www.gnu.org/software/glpk/) can be used out of the box.")]
+  [StorableType("CD1F0577-D68A-483B-8811-17E04573B3F2")]
+  public class GlpkSolver : ExternalLinearSolver {
+
+    public GlpkSolver() {
+      Parameters.Remove(solverSpecificParametersParam);
+      Parameters.Add(libraryNameParam = new FixedValueParameter<FileValue>(nameof(LibraryName),
+        new FileValue { FileDialogFilter = FileDialogFilter, Value = Properties.Settings.Default.GlpkLibraryName }));
+    }
+
+    protected GlpkSolver(GlpkSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected GlpkSolver(StorableConstructorFlag _) : base(_) { }
+
+    public override bool SupportsPause => false;
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      ProblemType == ProblemType.LinearProgramming
+        ? Solver.OptimizationProblemType.GlpkLinearProgramming
+        : Solver.OptimizationProblemType.GlpkMixedIntegerProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new GlpkSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GurobiSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GurobiSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/GurobiSolver.cs	(revision 17117)
@@ -0,0 +1,63 @@
+﻿#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 Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Gurobi", "Gurobi (http://www.gurobi.com/) must be installed and licensed.")]
+  [StorableType("2C567159-8C09-4B5F-BFF8-D72561686C6B")]
+  public class GurobiSolver : ExternalIncrementalLinearSolver {
+
+    public GurobiSolver() {
+      Parameters.Add(libraryNameParam = new FixedValueParameter<FileValue>(nameof(LibraryName),
+        new FileValue { FileDialogFilter = FileDialogFilter, Value = Properties.Settings.Default.GurobiLibraryName }));
+      SolverSpecificParameters =
+        "# for file format, see http://www.gurobi.com/documentation/8.1/refman/prm_format.html" + Environment.NewLine +
+        "# for parameters, see http://www.gurobi.com/documentation/8.1/refman/parameters.html" + Environment.NewLine +
+        "# examples:" + Environment.NewLine +
+        "# Seed 10" + Environment.NewLine +
+        "# Method 2 # Barrier (LP, root node of MIP)" + Environment.NewLine +
+        "# NodeMethod 2 # Barrier (MIP)" + Environment.NewLine;
+    }
+
+    protected GurobiSolver(GurobiSolver original, Cloner cloner)
+          : base(original, cloner) {
+      problemTypeParam = cloner.Clone(original.problemTypeParam);
+    }
+
+    [StorableConstructor]
+    protected GurobiSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      ProblemType == ProblemType.LinearProgramming
+        ? Solver.OptimizationProblemType.GurobiLinearProgramming
+        : Solver.OptimizationProblemType.GurobiMixedIntegerProgramming;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new GurobiSolver(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/ScipSolver.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/ScipSolver.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Algorithms/Solvers/ScipSolver.cs	(revision 17117)
@@ -0,0 +1,71 @@
+﻿#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.Threading;
+using Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("SCIP", "SCIP (http://scip.zib.de/) must be installed and licensed.")]
+  [StorableType("A4185E0D-25AE-48C4-8136-A764780683D5")]
+  public class ScipSolver : ExternalIncrementalLinearSolver {
+    private TimeSpan timeLimit = TimeSpan.Zero;
+
+    public ScipSolver() {
+      Parameters.Add(libraryNameParam = new FixedValueParameter<FileValue>(nameof(LibraryName),
+        new FileValue { FileDialogFilter = FileDialogFilter, Value = Properties.Settings.Default.ScipLibraryName }));
+      problemTypeParam.Value =
+        (EnumValue<ProblemType>)new EnumValue<ProblemType>(ProblemType.MixedIntegerProgramming).AsReadOnly();
+      SolverSpecificParameters =
+        "# for file format and parameters, see https://scip.zib.de/doc/html/PARAMETERS.php" + Environment.NewLine +
+        "# examples:" + Environment.NewLine +
+        "# branching/random/seed = 10" + Environment.NewLine +
+        "# lp/initalgorithm = b # Barrier (root node of MIP)" + Environment.NewLine +
+        "# lp/resolvealgorithm = b # Barrier (MIP)" + Environment.NewLine;
+    }
+
+    [StorableConstructor]
+    protected ScipSolver(StorableConstructorFlag _) : base(_) { }
+
+    protected ScipSolver(ScipSolver original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected override Solver.OptimizationProblemType OptimizationProblemType =>
+      Solver.OptimizationProblemType.ScipMixedIntegerProgramming;
+
+    protected override TimeSpan IntermediateTimeLimit => timeLimit += QualityUpdateInterval;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new ScipSolver(this, cloner);
+
+    public override void Solve(ILinearProblemDefinition problemDefintion, ResultCollection results, CancellationToken cancellationToken) {
+      timeLimit = TimeSpan.Zero;
+      base.Solve(problemDefintion, results, cancellationToken);
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/CompiledProblemDefinition.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/CompiledProblemDefinition.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/CompiledProblemDefinition.cs	(revision 17117)
@@ -0,0 +1,43 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public class CompiledProblemDefinition : Item {
+
+    public CompiledProblemDefinition() {
+    }
+
+    protected CompiledProblemDefinition(CompiledProblemDefinition original, Cloner cloner) : base(original, cloner) {
+    }
+
+    public dynamic vars { get; set; }
+
+    public override IDeepCloneable Clone(Cloner cloner) =>
+      new CompiledProblemDefinition(this, cloner);
+
+    public virtual void Initialize() {
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/FileBasedLinearProblemDefinition.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/FileBasedLinearProblemDefinition.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/FileBasedLinearProblemDefinition.cs	(revision 17117)
@@ -0,0 +1,99 @@
+﻿#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.Drawing;
+using System.IO;
+using Google.OrTools.LinearSolver;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Linear Problem Definition File (MPS, OR-Tools Protocol Buffers Files)", "File that defines the model for linear/mixed integer programming problem.")]
+  [StorableType("8779D26D-37DB-4595-A4E9-C7F29B870802")]
+  public sealed class FileBasedLinearProblemDefinition : ParameterizedNamedItem, ILinearProblemDefinition {
+
+    [Storable]
+    private readonly IFixedValueParameter<FileValue> fileNameParam;
+
+    [Storable]
+    private byte[] fileContent;
+
+    public FileBasedLinearProblemDefinition() {
+      Parameters.Add(fileNameParam = new FixedValueParameter<FileValue>(nameof(FileName), new FileValue()));
+      fileNameParam.Value.FileDialogFilter =
+        "All Supported Files (*.mps;*.bin;*.prototxt)|*.mps;*.bin;*.prototxt|" +
+        "Mathematical Programming System Files (*.mps)|*.mps|" +
+        "Google OR-Tools Protocol Buffers Files (*.bin;*.prototxt)|*.bin;*.prototxt|" +
+        "All Files (*.*)|*.*";
+      fileNameParam.Value.StringValue.ValueChanged += (o, e) => {
+        if (File.Exists(FileName)) {
+          fileContent = File.ReadAllBytes(FileName);
+        }
+      };
+    }
+
+    private FileBasedLinearProblemDefinition(FileBasedLinearProblemDefinition original, Cloner cloner)
+      : base(original, cloner) {
+      fileNameParam = cloner.Clone(original.fileNameParam);
+    }
+
+    [StorableConstructor]
+    private FileBasedLinearProblemDefinition(StorableConstructorFlag _) : base(_) { }
+
+    public new static Image StaticItemImage => VSImageLibrary.File;
+
+    public string FileName {
+      get => fileNameParam.Value.Value;
+      set => fileNameParam.Value.Value = value;
+    }
+
+    public IFixedValueParameter<FileValue> FileNameParam => fileNameParam;
+
+    public void Analyze(Solver solver, ResultCollection results) {
+    }
+
+    public void BuildModel(Solver solver) {
+      var fileInfo = new FileInfo(FileName);
+      var tempFileName = Path.GetTempFileName();
+
+      try {
+        File.WriteAllBytes(tempFileName, fileContent);
+
+        var status = (SolverResponseStatus)(fileInfo.Extension == ".mps"
+          ? solver.ImportModelFromMpsFormat(tempFileName)
+          : solver.ImportModelFromProtoFormat(tempFileName));
+
+        if (status == SolverResponseStatus.Abnormal)
+          throw new FileFormatException($"'{FileName}' is not a valid MPS or Google OR-Tools Protocol Buffers file.");
+      } finally {
+        File.Delete(tempFileName);
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) => new FileBasedLinearProblemDefinition(this, cloner);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ILinearProblemDefinition.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ILinearProblemDefinition.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ILinearProblemDefinition.cs	(revision 17117)
@@ -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 Google.OrTools.LinearSolver;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  public interface ILinearProblemDefinition : IItem {
+
+    void Analyze(Solver solver, ResultCollection results);
+
+    void BuildModel(Solver solver);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/LinearProblem.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/LinearProblem.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/LinearProblem.cs	(revision 17117)
@@ -0,0 +1,147 @@
+﻿#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.IO;
+using System.Linq;
+using System.Reflection;
+using Google.OrTools.LinearSolver;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Mixed-Integer Linear Programming Problem (LP, MIP)", "Represents a linear/mixed integer problem.")]
+  [StorableType("0F6BD4A4-8C70-4922-9BA1-1F372820DD76")]
+  public sealed class LinearProblem : Problem, IStorableContent {
+
+    [Storable]
+    private readonly IValueParameter<ILinearProblemDefinition> problemDefinitionParam;
+
+    public LinearProblem() {
+      Parameters.Remove(Parameters["Operators"]);
+      Parameters.Add(problemDefinitionParam = new ValueParameter<ILinearProblemDefinition>("Model", "The linear programming problem",
+        new ProgrammableLinearProblemDefinition()) { GetsCollected = false });
+    }
+
+    private LinearProblem(LinearProblem original, Cloner cloner)
+      : base(original, cloner) {
+      problemDefinitionParam = cloner.Clone(original.problemDefinitionParam);
+    }
+
+    [StorableConstructor]
+    private LinearProblem(StorableConstructorFlag _) : base(_) { }
+
+    public event EventHandler ProblemDefinitionChanged;
+
+    public string Filename { get; set; }
+
+    public ILinearProblemDefinition ProblemDefinition {
+      get => problemDefinitionParam.Value;
+      set {
+        if (problemDefinitionParam.Value == value)
+          return;
+        problemDefinitionParam.Value = value;
+        ProblemDefinitionChanged?.Invoke(this, EventArgs.Empty);
+      }
+    }
+
+    public IValueParameter<ILinearProblemDefinition> ProblemDefinitionParameter => problemDefinitionParam;
+
+    public override IDeepCloneable Clone(Cloner cloner) => new LinearProblem(this, cloner);
+
+    public override void CollectParameterValues(IDictionary<string, IItem> values) {
+      base.CollectParameterValues(values);
+
+      if (ProblemDefinition == null) return;
+
+      values.Add("Model Type", new StringValue(
+        (ProblemDefinition.GetType().GetCustomAttributes().Single(a => a is ItemAttribute) as ItemAttribute).Name));
+
+      if (ProblemDefinition is ProgrammableLinearProblemDefinition model) {
+        values.Add("Model Name", new StringValue(model.Name));
+      }
+    }
+
+    public void ExportModel(string fileName) {
+      if (string.IsNullOrWhiteSpace(fileName))
+        throw new ArgumentNullException(nameof(fileName));
+      if (ProblemDefinition == null)
+        throw new ArgumentNullException(nameof(ProblemDefinition));
+
+      var fileInfo = new FileInfo(fileName);
+
+      if (!fileInfo.Directory?.Exists ?? false) {
+        Directory.CreateDirectory(fileInfo.Directory.FullName);
+      }
+
+      var solver = new Solver(ProblemDefinition.ItemName, Solver.OptimizationProblemType.CbcMixedIntegerProgramming);
+
+      ProblemDefinition.BuildModel(solver);
+
+      var exportSuccessful = false;
+      switch (fileInfo.Extension) {
+        case ".lp":
+          var lpFormat = solver.ExportModelAsLpFormat(false);
+          if (!string.IsNullOrEmpty(lpFormat)) {
+            File.WriteAllText(fileName, lpFormat);
+            exportSuccessful = true;
+          }
+          break;
+
+        case ".mps":
+          var mpsFormat = solver.ExportModelAsMpsFormat(false, false);
+          if (!string.IsNullOrEmpty(mpsFormat)) {
+            File.WriteAllText(fileName, mpsFormat);
+            exportSuccessful = true;
+          }
+          break;
+
+        case ".prototxt":
+          exportSuccessful = solver.ExportModelAsProtoFormat(fileName,
+            (Google.OrTools.LinearSolver.ProtoWriteFormat)ProtoWriteFormat.ProtoText);
+          break;
+
+        case ".bin": // remove file extension as it is added by OR-Tools
+          fileName = Path.ChangeExtension(fileName, null);
+          exportSuccessful = solver.ExportModelAsProtoFormat(fileName,
+            (Google.OrTools.LinearSolver.ProtoWriteFormat)ProtoWriteFormat.ProtoBinary);
+          break;
+
+        default:
+          throw new NotSupportedException($"File format {fileInfo.Extension} to export model is not supported.");
+      }
+
+      if (!exportSuccessful)
+        throw new InvalidOperationException($"Model could not be exported. " +
+          $"For details, see the log files in '{LinearSolver.LogDirectory}'.");
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ProgrammableLinearProblemDefinition.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ProgrammableLinearProblemDefinition.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Problems/ProgrammableLinearProblemDefinition.cs	(revision 17117)
@@ -0,0 +1,150 @@
+﻿#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.Linq;
+using System.Reflection;
+using Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.ExactOptimization.LinearProgramming.Templates;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.Programmable;
+using HeuristicLab.Scripting;
+using HEAL.Attic;
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming {
+
+  [Item("Programmable Linear Problem Definition (LP, MIP)",
+    "Script that defines the model for a linear/mixed integer programming problem.")]
+  [StorableType("830F82CF-9FF1-4619-A75E-E43E208565F0")]
+  public sealed class ProgrammableLinearProblemDefinition : Script, ILinearProblemDefinition,
+    IStorableContent {
+    private readonly object compileLock = new object();
+
+    [Storable]
+    private readonly VariableStore variableStore;
+
+    [Storable]
+    private bool codeChanged;
+
+    private volatile ILinearProblemDefinition compiledProblemDefinition;
+
+    public ProgrammableLinearProblemDefinition()
+      : base(ScriptTemplates.CompiledLinearProblemDefinition) {
+      Name = "Programmable Linear Problem Definition";
+      variableStore = new VariableStore();
+    }
+
+    [StorableConstructor]
+    private ProgrammableLinearProblemDefinition(StorableConstructorFlag _) : base(_) { }
+
+    private ProgrammableLinearProblemDefinition(ProgrammableLinearProblemDefinition original,
+      Cloner cloner) : base(original, cloner) {
+      variableStore = cloner.Clone(original.variableStore);
+      codeChanged = original.codeChanged;
+    }
+
+    public event EventHandler ProblemDefinitionChanged;
+
+    public string Filename { get; set; }
+    public dynamic Instance => compiledProblemDefinition;
+    public VariableStore VariableStore => variableStore;
+
+    private ILinearProblemDefinition CompiledProblemDefinition {
+      get {
+        // double checked locking pattern
+        if (compiledProblemDefinition == null) {
+          lock (compileLock) {
+            if (compiledProblemDefinition == null) {
+              if (codeChanged)
+                throw new ProblemDefinitionScriptException("The code has been changed, but was not recompiled.");
+              Compile(false);
+            }
+          }
+        }
+
+        return compiledProblemDefinition;
+      }
+    }
+
+    public void Analyze(Solver solver, ResultCollection results) => CompiledProblemDefinition.Analyze(solver, results);
+
+    public void BuildModel(Solver solver) => CompiledProblemDefinition.BuildModel(solver);
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ProgrammableLinearProblemDefinition(this, cloner);
+    }
+
+    public override Assembly Compile() => Compile(true);
+
+    protected override void OnCodeChanged() {
+      base.OnCodeChanged();
+      compiledProblemDefinition = null;
+      codeChanged = true;
+    }
+
+    private Assembly Compile(bool fireChanged) {
+      var assembly = base.Compile();
+      var types = assembly.GetTypes();
+      if (!types.Any(x => typeof(CompiledProblemDefinition).IsAssignableFrom(x)))
+        throw new ProblemDefinitionScriptException("The compiled code doesn't contain a problem definition." + Environment.NewLine +
+                                                   $"The problem definition must be a subclass of {nameof(CompiledProblemDefinition)} and implement {nameof(ILinearProblemDefinition)}.");
+      if (types.Count(x => typeof(CompiledProblemDefinition).IsAssignableFrom(x)) > 1)
+        throw new ProblemDefinitionScriptException("The compiled code contains multiple problem definitions." + Environment.NewLine +
+                                                   $"Only one subclass of {nameof(CompiledProblemDefinition)} is allowed.");
+
+      CompiledProblemDefinition inst;
+      try {
+        inst = (CompiledProblemDefinition)Activator.CreateInstance(types.Single(x =>
+         typeof(CompiledProblemDefinition).IsAssignableFrom(x)));
+      } catch (Exception e) {
+        compiledProblemDefinition = null;
+        throw new ProblemDefinitionScriptException(
+          "Instantiating the problem definition failed." + Environment.NewLine + "Check your default constructor.", e);
+      }
+
+      try {
+        inst.vars = new Variables(VariableStore);
+        inst.Initialize();
+      } catch (Exception e) {
+        compiledProblemDefinition = null;
+        throw new ProblemDefinitionScriptException(
+          "Initializing the problem definition failed." + Environment.NewLine + "Check your Initialize() method.", e);
+      }
+
+      try {
+        compiledProblemDefinition = (ILinearProblemDefinition)inst;
+        if (fireChanged) OnProblemDefinitionChanged();
+      } catch (Exception e) {
+        compiledProblemDefinition = null;
+        throw new ProblemDefinitionScriptException(
+          "Using the problem definition in the problem failed." + Environment.NewLine +
+          "Examine this error message carefully.", e);
+      }
+
+      codeChanged = false;
+      return assembly;
+    }
+
+    private void OnProblemDefinitionChanged() => ProblemDefinitionChanged?.Invoke(this, EventArgs.Empty);
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/CompiledLinearProblemDefinition.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/CompiledLinearProblemDefinition.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/CompiledLinearProblemDefinition.cs	(revision 17117)
@@ -0,0 +1,46 @@
+﻿using System;
+using System.Linq;
+using System.Collections.Generic;
+using Google.OrTools.LinearSolver;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.ExactOptimization.LinearProgramming;
+using HeuristicLab.Optimization;
+using Variable = Google.OrTools.LinearSolver.Variable;
+
+public class CompiledLinearProblemDefinition : CompiledProblemDefinition, ILinearProblemDefinition {
+  private Variable x;
+  private Variable y;
+
+  public override void Initialize() {
+    // Use vars.yourVariable to access variables in the variable store i.e. yourVariable
+    // Add additional initialization code e.g. private variables that you need for evaluating
+  }
+
+  public void BuildModel(Solver solver) {
+    // Use vars.yourVariable to access variables in the variable store i.e. yourVariable
+    // How to define a model using Google OR-Tools: https://developers.google.com/optimization/introduction/cs
+    // Example model taken from https://developers.google.com/optimization/mip/integer_opt
+    // Define the decision variables
+    x = solver.MakeIntVar(0, 3.5, "x");
+    y = solver.MakeIntVar(0, double.PositiveInfinity, "y");
+    // Define the constraints
+    solver.Add(x + 7 * y <= 17.5);
+    // Define the objective
+    solver.Maximize(x + 10 * y);
+  }
+
+  public void Analyze(Solver solver, ResultCollection results) {
+    // Use vars.yourVariable to access variables in the variable store i.e. yourVariable
+    // Write or update results given the solution values of the decision variables
+    results.AddOrUpdateResult("x", new DoubleValue(x.SolutionValue()));
+    results.AddOrUpdateResult("y", new DoubleValue(y.SolutionValue()));
+    // The decision variables can also be retrieved from the solver
+    //results.AddOrUpdateResult("x", new DoubleValue(solver.LookupVariableOrNull("x").SolutionValue()));
+    //results.AddOrUpdateResult("y", new DoubleValue(solver.LookupVariableOrNull("y").SolutionValue()));
+  }
+
+  // Implement further classes and methods
+}
+
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.Designer.cs	(revision 17117)
@@ -0,0 +1,87 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.ExactOptimization.LinearProgramming.Templates {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class ScriptTemplates {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal ScriptTemplates() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeuristicLab.ExactOptimization.LinearProgramming.Templates.ScriptTemplates", typeof(ScriptTemplates).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to using System;
+        ///using System.Linq;
+        ///using System.Collections.Generic;
+        ///using Google.OrTools.LinearSolver;
+        ///using HeuristicLab.Common;
+        ///using HeuristicLab.Core;
+        ///using HeuristicLab.Data;
+        ///using HeuristicLab.ExactOptimization.LinearProgramming;
+        ///using HeuristicLab.Optimization;
+        ///using Variable = Google.OrTools.LinearSolver.Variable;
+        ///
+        ///public class CompiledLinearProblemDefinition : CompiledProblemDefinition, ILinearProblemDefinition {
+        ///  private Variable x;
+        ///  private Variable y;
+        ///
+        ///  public override void Init [rest of string was truncated]&quot;;.
+        /// </summary>
+        internal static string CompiledLinearProblemDefinition {
+            get {
+                return ResourceManager.GetString("CompiledLinearProblemDefinition", resourceCulture);
+            }
+        }
+    }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.resx
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.resx	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/LinearProgramming/Templates/ScriptTemplates.resx	(revision 17117)
@@ -0,0 +1,124 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="CompiledLinearProblemDefinition" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>compiledlinearproblemdefinition.cs;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
+  </data>
+</root>
Index: /stable/HeuristicLab.ExactOptimization/3.3/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/Plugin.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/Plugin.cs.frame	(revision 17117)
@@ -0,0 +1,43 @@
+﻿#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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.ExactOptimization {
+
+  [Plugin("HeuristicLab.ExactOptimization", "Provides support for exact optimization based on Google OR-Tools. " +
+    "Requires the Microsoft Visual C++ 2017 Redistributable (x64) - 14.16.27012: https://aka.ms/vs/15/release/vc_redist.x64.exe", "3.3.15.$WCREV$")]
+  [PluginFile("HeuristicLab.ExactOptimization-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Attic", "1.0")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.OrTools", "7.0")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Programmable", "3.3")]
+  [PluginDependency("HeuristicLab.Scripting", "3.3")]
+  public class HeuristicLabExactOptimizationPlugin : PluginBase {
+  }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/Properties/AssemblyInfo.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/Properties/AssemblyInfo.cs.frame	(revision 17117)
@@ -0,0 +1,57 @@
+﻿#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.ExactOptimization")]
+[assembly: AssemblyDescription("Provides support for exact optimization based on Google OR-Tools")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2019 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("78D3CF45-1EDF-4AF1-B215-EA196A9EC7B1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.Designer.cs
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.Designer.cs	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.Designer.cs	(revision 17117)
@@ -0,0 +1,74 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.ExactOptimization.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
+    public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("scip.dll")]
+        public string ScipLibraryName {
+            get {
+                return ((string)(this["ScipLibraryName"]));
+            }
+            set {
+                this["ScipLibraryName"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("cplex1280.dll")]
+        public string CplexLibraryName {
+            get {
+                return ((string)(this["CplexLibraryName"]));
+            }
+            set {
+                this["CplexLibraryName"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("glpk_4_65.dll")]
+        public string GlpkLibraryName {
+            get {
+                return ((string)(this["GlpkLibraryName"]));
+            }
+            set {
+                this["GlpkLibraryName"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("gurobi81.dll")]
+        public string GurobiLibraryName {
+            get {
+                return ((string)(this["GurobiLibraryName"]));
+            }
+            set {
+                this["GurobiLibraryName"] = value;
+            }
+        }
+    }
+}
Index: /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.settings
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.settings	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/Properties/Settings.settings	(revision 17117)
@@ -0,0 +1,18 @@
+﻿<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="HeuristicLab.ExactOptimization.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="ScipLibraryName" Type="System.String" Scope="User">
+      <Value Profile="(Default)">scip.dll</Value>
+    </Setting>
+    <Setting Name="CplexLibraryName" Type="System.String" Scope="User">
+      <Value Profile="(Default)">cplex1280.dll</Value>
+    </Setting>
+    <Setting Name="GlpkLibraryName" Type="System.String" Scope="User">
+      <Value Profile="(Default)">glpk_4_65.dll</Value>
+    </Setting>
+    <Setting Name="GurobiLibraryName" Type="System.String" Scope="User">
+      <Value Profile="(Default)">gurobi81.dll</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>
Index: /stable/HeuristicLab.ExactOptimization/3.3/app.config
===================================================================
--- /stable/HeuristicLab.ExactOptimization/3.3/app.config	(revision 17117)
+++ /stable/HeuristicLab.ExactOptimization/3.3/app.config	(revision 17117)
@@ -0,0 +1,24 @@
+﻿<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <configSections>
+    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+      <section name="HeuristicLab.ExactOptimization.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+    </sectionGroup>
+  </configSections>
+  <userSettings>
+    <HeuristicLab.ExactOptimization.Properties.Settings>
+      <setting name="ScipLibraryName" serializeAs="String">
+        <value>scip.dll</value>
+      </setting>
+      <setting name="CplexLibraryName" serializeAs="String">
+        <value>cplex1280.dll</value>
+      </setting>
+      <setting name="GlpkLibraryName" serializeAs="String">
+        <value>glpk_4_65.dll</value>
+      </setting>
+      <setting name="GurobiLibraryName" serializeAs="String">
+        <value>gurobi81.dll</value>
+      </setting>
+    </HeuristicLab.ExactOptimization.Properties.Settings>
+  </userSettings>
+</configuration>
Index: /stable/HeuristicLab.ExtLibs.sln
===================================================================
--- /stable/HeuristicLab.ExtLibs.sln	(revision 17116)
+++ /stable/HeuristicLab.ExtLibs.sln	(revision 17117)
@@ -78,4 +78,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Attic", "HeuristicLab.ExtLibs\HeuristicLab.Attic\1.0.0\HeuristicLab.Attic.csproj", "{44A10478-D290-43C2-9757-F08F5292FEA5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.OrTools-7.0.0", "HeuristicLab.ExtLibs\HeuristicLab.OrTools\7.0.0\HeuristicLab.OrTools-7.0.0\HeuristicLab.OrTools-7.0.0.csproj", "{AEC895BC-C519-49D3-9A94-6B1C71AD6671}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Protobuf", "HeuristicLab.ExtLibs\HeuristicLab.Protobuf\3.6.1\HeuristicLab.Protobuf.csproj", "{44B10478-D290-43D3-9757-C08F5292FEA5}"
@@ -507,4 +509,16 @@
 		{44A10478-D290-43C2-9757-F08F5292FEA5}.Release|x86.ActiveCfg = Release|Any CPU
 		{44A10478-D290-43C2-9757-F08F5292FEA5}.Release|x86.Build.0 = Release|Any CPU
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|x64.ActiveCfg = Debug|x64
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|x64.Build.0 = Debug|x64
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|x86.ActiveCfg = Debug|x86
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Debug|x86.Build.0 = Debug|x86
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|Any CPU.Build.0 = Release|Any CPU
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|x64.ActiveCfg = Release|x64
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|x64.Build.0 = Release|x64
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|x86.ActiveCfg = Release|x86
+		{AEC895BC-C519-49D3-9A94-6B1C71AD6671}.Release|x86.Build.0 = Release|x86
 		{44B10478-D290-43D3-9757-C08F5292FEA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{44B10478-D290-43D3-9757-C08F5292FEA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
Index: /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools-license.txt
===================================================================
--- /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools-license.txt	(revision 17117)
+++ /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools-license.txt	(revision 17117)
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2010 Google Inc
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
Index: /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools_version.txt
===================================================================
--- /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools_version.txt	(revision 17117)
+++ /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Google.OrTools_version.txt	(revision 17117)
@@ -0,0 +1,6 @@
+﻿This version of Google OR-Tools is a custom build of a commit [1] in the
+runtimelinking branch of the Google OR-Tools C++ library available at
+GitHub [2]. The library was compiled with Visual Studio 2017 for x64.
+
+[1]: https://github.com/ddorfmeister/or-tools/commit/eb3d72b09219e1aef48182b77cf26b153e9fc9a1
+[2]: https://github.com/google/or-tools
Index: /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/HeuristicLab.OrTools-7.0.0.csproj
===================================================================
--- /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/HeuristicLab.OrTools-7.0.0.csproj	(revision 17117)
+++ /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/HeuristicLab.OrTools-7.0.0.csproj	(revision 17117)
@@ -0,0 +1,138 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{AEC895BC-C519-49D3-9A94-6B1C71AD6671}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.OrTools</RootNamespace>
+    <AssemblyName>HeuristicLab.OrTools-7.0.0</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Google.OrTools-license.txt">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Google.OrTools.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Google.OrTools.pdb">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Google.OrTools.runtime.win-x64.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="Google.OrTools_version.txt">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Plugin.cs.frame
===================================================================
--- /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Plugin.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Plugin.cs.frame	(revision 17117)
@@ -0,0 +1,72 @@
+﻿#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.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.OrTools {
+
+  [Plugin("HeuristicLab.OrTools", "Provides functionality of Google OR-Tools in HeuristicLab. Requires Windows 64-bit", "7.0.0.$WCREV$")]
+  [PluginFile("HeuristicLab.OrTools-7.0.0.dll", PluginFileType.Assembly)]
+  [PluginFile("Google.OrTools.dll", PluginFileType.Assembly)]
+  [PluginFile("Google.OrTools-license.txt", PluginFileType.License)]
+  [PluginFile("Google.OrTools.runtime.win-x64.dll", PluginFileType.NativeDll)]
+  [PluginFile("Google.OrTools_version.txt", PluginFileType.Data)]
+  [PluginDependency("HeuristicLab.Protobuf", "3.6.1")]
+  public class HeuristicLabOrToolsPlugin : PluginBase {
+
+    public override void OnUnload() {
+      // HACK: free handle to native DLL used temporarily by the Hive Slave
+      // should be solved for all native DLLs used by the Hive Slave
+      var dllDir = new FileInfo(GetType().Assembly.Location).Directory;
+      if (dllDir == null || !dllDir.FullName.Contains(Path.DirectorySeparatorChar + "PluginTemp" + Path.DirectorySeparatorChar))
+        return;
+
+      var nativeDlls = GetType().GetCustomAttributes(typeof(PluginFileAttribute), true)
+        .Cast<PluginFileAttribute>()
+        .Where(pf => pf.FileType == PluginFileType.NativeDll)
+        .Select(pf => pf.FileName);
+
+      foreach (var nativeDll in dllDir.EnumerateFiles().Where(f => nativeDlls.Contains(f.Name))) {
+        if (Process.GetCurrentProcess().Modules.Cast<ProcessModule>().All(m => m.ModuleName != nativeDll.Name))
+          continue;
+
+        var handle = LoadLibrary(nativeDll.FullName);
+        if (handle == IntPtr.Zero)
+          continue;
+
+        FreeLibrary(handle); // close handle obtained above
+        FreeLibrary(handle); // close implicitly obtained handle
+      }
+    }
+
+    [DllImport("kernel32.dll", SetLastError = true)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    private static extern bool FreeLibrary(IntPtr hModule);
+
+    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
+    private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
+  }
+}
Index: /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Properties/AssemblyInfo.cs.frame
===================================================================
--- /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Properties/AssemblyInfo.cs.frame	(revision 17117)
+++ /stable/HeuristicLab.ExtLibs/HeuristicLab.OrTools/7.0.0/HeuristicLab.OrTools-7.0.0/Properties/AssemblyInfo.cs.frame	(revision 17117)
@@ -0,0 +1,56 @@
+﻿#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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.OrTools")]
+[assembly: AssemblyDescription("Plugin for providing Google OR-Tools functionality in HeuristicLab")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2018 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("D7426305-B35E-47AF-8B19-7081C4AB76D3")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("7.0.0.0")]
+[assembly: AssemblyFileVersion("7.0.0.$WCREV$")]
Index: /stable/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs
===================================================================
--- /stable/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 17116)
+++ /stable/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 17117)
@@ -37,4 +37,5 @@
       base.SetEnabledStateOfControls();
       pauseButton.Enabled &= Content != null && Content.SupportsPause;
+      stopButton.Enabled &= Content != null && Content.SupportsStop;
     }
 
@@ -42,4 +43,5 @@
       base.SetEnabledStateOfExecutableButtons();
       pauseButton.Enabled &= Content != null && Content.SupportsPause;
+      stopButton.Enabled &= Content != null && Content.SupportsStop;
     }
   }
Index: /stable/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs
===================================================================
--- /stable/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 17116)
+++ /stable/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 17117)
@@ -36,4 +36,7 @@
 
     public abstract bool SupportsPause { get; }
+    public virtual bool SupportsStop {
+      get { return true; }
+    }
 
     [Storable]
@@ -106,4 +109,7 @@
       // CancellationToken.ThrowIfCancellationRequested() must be called from within the Run method, otherwise stop does nothing
       // alternatively check the IsCancellationRequested property of the cancellation token
+      if (!SupportsStop)
+        throw new NotSupportedException("Stop is not supported by this algorithm.");
+
       base.Stop();
       if (ExecutionState == ExecutionState.Paused) OnStopped();
