Index: trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/GraphColoringProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/GraphColoringProblem.cs	(revision 15169)
+++ trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/GraphColoringProblem.cs	(revision 15172)
@@ -38,5 +38,5 @@
   [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 135)]
   [StorableClass]
-  public sealed class GraphColoringProblem : SingleObjectiveBasicProblem<LinearLinkageEncoding>, IProblemInstanceConsumer<GCPData> {
+  public sealed class GraphColoringProblem : SingleObjectiveBasicProblem<LinearLinkageEncoding>, IProblemInstanceConsumer<GCPData>, IProblemInstanceExporter<GCPData> {
 
     public override bool Maximization {
@@ -115,9 +115,16 @@
     private void FitnessFunctionParameterOnValueChanged(object sender, EventArgs eventArgs) {
       fitnessFunctionParameter.Value.ValueChanged += FitnessFunctionOnValueChanged;
-      OnReset();
+      FitnessFunctionOnValueChanged(sender, eventArgs);
     }
 
     private void FitnessFunctionOnValueChanged(object sender, EventArgs eventArgs) {
       BestKnownQualityParameter.Value = null;
+      if (FitnessFunction == FitnessFunction.Prioritized
+        && BestKnownColorsParameter.Value != null
+        && Encoding.Length > 0) {
+        var mag = Math.Pow(10, -(int)Math.Ceiling(Math.Log10(Encoding.Length)));
+        // the value is e.g. 0.051 for 0 conflicts with 51 colors (and less than 1000 nodes)
+        BestKnownQuality = BestKnownColorsParameter.Value.Value * mag;
+      } else BestKnownQualityParameter.Value = null;
       OnReset();
     }
@@ -242,4 +249,20 @@
       Description = data.Description;
       OnReset();
+    }
+
+    public GCPData Export() {
+      var instance = new GCPData();
+      instance.Name = Name;
+      instance.Description = Description;
+      instance.Nodes = Encoding.Length;
+      var adjList = AdjacencyListParameter.Value;
+      instance.Adjacencies = new int[adjList.Rows, 2];
+      for (var r = 0; r < adjList.Rows; r++) {
+        instance.Adjacencies[r, 0] = adjList[r, 0];
+        instance.Adjacencies[r, 1] = adjList[r, 1];
+      }
+      if (BestKnownColorsParameter.Value != null)
+        instance.BestKnownColors = BestKnownColorsParameter.Value.Value;
+      return instance;
     }
 
Index: trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/HeuristicLab.Problems.GraphColoring-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/HeuristicLab.Problems.GraphColoring-3.3.csproj	(revision 15169)
+++ trunk/sources/HeuristicLab.Problems.GraphColoring/3.3/HeuristicLab.Problems.GraphColoring-3.3.csproj	(revision 15172)
@@ -125,5 +125,5 @@
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Encodings.LinearLinkageEncoding\3.4\HeuristicLab.Encodings.LinearLinkageEncoding-3.4.csproj">
-      <Project>{166507c9-ef26-4370-bb80-699742a29d4f}</Project>
+      <Project>{be698769-975a-429e-828c-72bb2b6182c8}</Project>
       <Name>HeuristicLab.Encodings.LinearLinkageEncoding-3.4</Name>
       <Private>False</Private>
Index: trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolInstanceProvider.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolInstanceProvider.cs	(revision 15169)
+++ trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolInstanceProvider.cs	(revision 15172)
@@ -69,9 +69,9 @@
 
         using (var stream = entry.Open()) {
-          var parser = new Parser();
+          var parser = new GcolParser();
           parser.Parse(stream);
           var instance = Load(parser);
           instance.Name = id.Name;
-          instance.Description = id.Description;
+          instance.Description += Environment.NewLine + id.Description;
           int bestknown;
           if (bkq.TryGetValue(instance.Name, out bestknown))
@@ -86,24 +86,42 @@
     }
     public override GCPData ImportData(string path) {
-      var parser = new Parser();
+      var parser = new GcolParser();
       parser.Parse(path);
       var instance = Load(parser);
       instance.Name = Path.GetFileName(path);
-      instance.Description = "Loaded from file \"" + path + "\" on " + DateTime.Now.ToString();
+      instance.Description += Environment.NewLine + "Loaded from file \"" + path + "\" on " + DateTime.Now.ToString();
       return instance;
     }
 
-    private GCPData Load(Parser parser) {
+    private GCPData Load(GcolParser parser) {
       var instance = new GCPData();
+      instance.Description = parser.Comments;
       instance.Nodes = parser.Nodes;
       var adjacencies = new int[parser.Edges, 2];
       var i = 0;
       foreach (var a in parser.AdjacencyList) {
-        adjacencies[i, 0] = a.Item1 - 1;
-        adjacencies[i, 1] = a.Item2 - 1;
+        adjacencies[i, 0] = a.Item1;
+        adjacencies[i, 1] = a.Item2;
         i++;
       }
       instance.Adjacencies = adjacencies;
       return instance;
+    }
+    
+    public override bool CanExportData { get { return true; } }
+    public override void ExportData(GCPData instance, string path) {
+      using (var stream = new StreamWriter(File.Create(path)) { AutoFlush = true }) {
+        stream.WriteLine("c " + instance.Name);
+        foreach (var comment in instance.Description.Split(new[] { Environment.NewLine }, StringSplitOptions.None)) {
+          var c = comment;
+          if (!c.StartsWith("c ")) c = "c " + comment;
+          stream.WriteLine(c);
+        }
+        var edges = instance.Adjacencies.GetLength(0);
+        stream.WriteLine("p edge " + instance.Nodes + " " + edges);
+        for (var i = 0; i < edges; i++) {
+          stream.WriteLine("e " + (instance.Adjacencies[i, 0]+1) + " " + (instance.Adjacencies[i, 1]+1));
+        }
+      }
     }
 
Index: trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolParser.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolParser.cs	(revision 15172)
+++ trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolParser.cs	(revision 15172)
@@ -0,0 +1,169 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.Problems.Instances.DIMACS {
+  public class GcolParser {
+    private enum LineType { Unknown, Comment, Problem, Edge }
+
+    public string Comments { get; private set; }
+    public int Nodes { get; private set; }
+    public int Edges { get; private set; }
+    public IEnumerable<Tuple<int, int>> AdjacencyList {
+      get { return edges.Select(x => Tuple.Create(x.First.Id, x.Second.Id)); }
+    }
+
+    public int UnconnectedNodes { get; private set; }
+
+    private Node[] nodes;
+    private HashSet<Edge> edges;
+    
+    public GcolParser() {
+      Reset();
+    }
+
+    public void Reset() {
+      Nodes = 0;
+      Edges = 0;
+      nodes = new Node[0];
+      edges = new HashSet<Edge>();
+    }
+
+    public void Parse(string file) {
+      using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
+        Parse(stream);
+      }
+    }
+
+    /// <summary>
+    /// Reads from the given stream data which is expected to be in the GCOL format:
+    /// http://prolland.free.fr/works/research/dsat/dimacs.html
+    /// The number of nodes and edges are calculated from the actual edges defined.
+    /// The number of nodes stated must be a maximum number.
+    /// Nodes without edges are not considered.
+    /// </summary>
+    /// <remarks>
+    /// The stream is not closed or disposed. The caller has to take care of that.
+    /// </remarks>
+    /// <param name="stream">The stream to read data from.</param>
+    public void Parse(Stream stream) {
+      char[] delim = new char[] { ' ', '\t' };
+      var comments = new StringBuilder();
+      var reader = new StreamReader(stream);
+      while (!reader.EndOfStream) {
+        var line = reader.ReadLine().Trim();
+        switch (GetLineType(line)) {
+          case LineType.Comment:
+            comments.AppendLine(line);
+            break;
+          case LineType.Problem:
+            var pData = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
+            if (pData.Length < 3)
+              throw new InvalidOperationException("Invalid problem entry: " + line + Environment.NewLine + "Must be p FORMAT NODES [EDGES]");
+            if (!pData[1].Equals("edge", StringComparison.InvariantCultureIgnoreCase)
+              && !pData[1].Equals("edges", StringComparison.InvariantCultureIgnoreCase))
+              throw new InvalidOperationException("Unsupported problem format type " + pData[1]);
+            Nodes = int.Parse(pData[2], CultureInfo.InvariantCulture.NumberFormat);
+            nodes = new Node[Nodes];
+            break;
+          case LineType.Edge:
+            if (nodes == null) throw new InvalidOperationException("Missing \"p\" line before \"e\" lines.");
+            var eData = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
+            var src = int.Parse(eData[1], CultureInfo.InvariantCulture.NumberFormat);
+            var tgt = int.Parse(eData[2], CultureInfo.InvariantCulture.NumberFormat);
+            if (src > Nodes || tgt > Nodes)
+              throw new InvalidOperationException("An edge cannot be declared between " + src + " and " + tgt + " because only " + Nodes + " nodes were defined.");
+            src--; // node indices are given 1-based in the files
+            tgt--; // node indices are given 1-based in the files
+            if (src > tgt) {
+              var h = src;
+              src = tgt;
+              tgt = h;
+            }
+            if (nodes[src] == null) nodes[src] = new Node();
+            if (nodes[tgt] == null) nodes[tgt] = new Node();
+            if (edges.Add(new Edge(nodes[src], nodes[tgt]))) Edges++;
+            break;
+        }
+      }
+
+      if (nodes.Length == 0) throw new InvalidOperationException("There were no nodes defined.");
+
+      // Give identies to the nodes and filter nodes without edges
+      Nodes = 0; UnconnectedNodes = 0;
+      for (var n = 0; n < nodes.Length; n++) {
+        if (nodes[n] != null) {
+          nodes[n].Id = Nodes;
+          Nodes++;
+        } else UnconnectedNodes++;
+      }
+      if (UnconnectedNodes > 0) {
+        comments.AppendLine();
+        comments.Append("There were ");
+        comments.Append(UnconnectedNodes);
+        comments.AppendLine(" unconnected nodes that have been removed compared to the original file.");
+      }
+      Comments = comments.ToString();
+    }
+
+    private LineType GetLineType(string line) {
+      if (string.IsNullOrEmpty(line)) return LineType.Unknown;
+      var first = line[0];
+      switch (first) {
+        case 'c': return LineType.Comment;
+        case 'p': return LineType.Problem;
+        case 'e': return LineType.Edge;
+        default: throw new InvalidOperationException("This is not a valid .col file");
+      }
+    }
+
+    private class Node {
+      public int Id { get; set; }
+      public Node() { }
+    }
+
+    private class Edge {
+      public Node First { get; set; }
+      public Node Second { get; set; }
+      public Edge(Node first, Node second) {
+        First = first;
+        Second = second;
+      }
+
+      public override bool Equals(object obj) {
+        var other = (obj as Edge);
+        if (other == null) return false;
+        return First == other.First && Second == other.Second
+          || First == other.Second && Second == other.First;
+      }
+
+      public override int GetHashCode() {
+        return First.GetHashCode() ^ Second.GetHashCode();
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/HeuristicLab.Problems.Instances.DIMACS-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/HeuristicLab.Problems.Instances.DIMACS-3.3.csproj	(revision 15169)
+++ trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/HeuristicLab.Problems.Instances.DIMACS-3.3.csproj	(revision 15172)
@@ -87,5 +87,5 @@
     <Compile Include="GcolDataDescriptor.cs" />
     <Compile Include="GcolInstanceProvider.cs" />
-    <Compile Include="Parser.cs" />
+    <Compile Include="GcolParser.cs" />
     <EmbeddedResource Include="Data\col.zip" />
     <None Include="Plugin.cs.frame" />
Index: trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/Parser.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.Instances.DIMACS/3.3/Parser.cs	(revision 15169)
+++ 	(revision )
@@ -1,82 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2017 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;
-
-namespace HeuristicLab.Problems.Instances.DIMACS {
-  public class Parser {
-    public int Nodes { get; private set; }
-    public int Edges { get; private set; }
-    public ICollection<Tuple<int, int>> AdjacencyList { get { return edges; } }
-    private HashSet<Tuple<int, int>> edges;
-
-    public Parser() {
-      Reset();
-    }
-
-    public void Reset() {
-      Nodes = 0;
-      Edges = 0;
-      edges = new HashSet<Tuple<int, int>>();
-    }
-
-    public void Parse(string file) {
-      using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
-        Parse(stream);
-      }
-    }
-
-    /// <summary>
-    /// Reads from the given stream data which is expected to be in the QAPLIB format.
-    /// </summary>
-    /// <remarks>
-    /// The stream is not closed or disposed. The caller has to take care of that.
-    /// </remarks>
-    /// <param name="stream">The stream to read data from.</param>
-    /// <returns>True if the file was successfully read or false otherwise.</returns>
-    public void Parse(Stream stream) {
-      char[] delim = new char[] { ' ', '\t' };
-      var reader = new StreamReader(stream);
-      var line = reader.ReadLine().Trim();
-      // skip comments
-      while (line.StartsWith("c", StringComparison.InvariantCultureIgnoreCase)) line = reader.ReadLine().Trim();
-
-      // p edge NODES EDGES
-      var split = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
-      Nodes = int.Parse(split[2]);
-      do {
-        line = reader.ReadLine();
-        if (string.IsNullOrEmpty(line)) break;
-        // e XX YY
-        split = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
-        var src = int.Parse(split[1]);
-        var tgt = int.Parse(split[2]);
-        Tuple<int, int> e = null;
-        if (src < tgt) e = Tuple.Create(src, tgt);
-        else if (src > tgt) e = Tuple.Create(tgt, src);
-        else continue; // src == tgt
-        if (edges.Add(e)) Edges++;
-      } while (!reader.EndOfStream);
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.Instances-3.3/DIMACSGcolInstanceProviderTest.cs
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.Instances-3.3/DIMACSGcolInstanceProviderTest.cs	(revision 15172)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.Instances-3.3/DIMACSGcolInstanceProviderTest.cs	(revision 15172)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Text;
+using HeuristicLab.Problems.Instances.DIMACS;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace HeuristicLab.Problems.Instances.Tests {
+  [TestClass()]
+  public class DIMACSGcolInstanceProviderTest {
+
+    [TestMethod]
+    [TestCategory("Problems.Instances")]
+    [TestProperty("Time", "medium")]
+    public void GetDIMACSGcolInstancesTest() {
+      var target = new GcolInstanceProvider();
+      StringBuilder erroneousInstances = new StringBuilder();
+      int count = 0;
+      foreach (var id in target.GetDataDescriptors()) {
+        try {
+          target.LoadData(id);
+        } catch (Exception ex) {
+          erroneousInstances.AppendLine(id.Name + ": " + ex.Message);
+        }
+        count++;
+      }
+      Assert.IsTrue(count > 0, "No problem instances were found.");
+      Assert.IsTrue(erroneousInstances.Length == 0, "Some instances could not be parsed: " + Environment.NewLine + erroneousInstances.ToString());
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15169)
+++ trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15172)
@@ -332,4 +332,9 @@
     <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3">
       <HintPath>..\bin\HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.DIMACS-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\bin\HeuristicLab.Problems.Instances.DIMACS-3.3.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -586,4 +591,5 @@
     <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4\SymbolicDataAnalysisExpressionTreeInterpreterTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4\Util.cs" />
+    <Compile Include="HeuristicLab.Problems.Instances-3.3\DIMACSGcolInstanceProviderTest.cs" />
     <Compile Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3\RegressionInstanceProviderTest.cs" />
     <Compile Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3\TableFileParserTest.cs" />
