diff --git a/GraphDrawer/Program.cs b/GraphDrawer/Program.cs
index 31d4120c3dac63b66ce60cbf9fe7228d6b832814..9cde53c0c72c3d218dc9ac49047fb55b564140b4 100644
--- a/GraphDrawer/Program.cs
+++ b/GraphDrawer/Program.cs
@@ -9,11 +9,36 @@ using System.Windows.Forms.DataVisualization.Charting;
 
 namespace GraphDrawer
 {
-	internal class Program
-	{
-		private static void Main(string[] args)
-		{
-			GraphWriter.Write(args[0], args[1]);
-		}
-	}
+    internal class Program
+    {
+        private const string HELP = @"
+Tool for plotting graphs comparing Vecto 2.2 and Vecto 3
+
+--split <leng> ... split input into parts of length <len> (in m), only distance output
+
+";
+
+        private static void Main(string[] args)
+        {
+            if (args.Contains("--split")) {
+                Console.WriteLine("plotting graphs splitted by distance");
+                var idx = Array.FindIndex(args, x => x == "--split");
+                var lenght = int.Parse(args[idx + 1]);
+                var success = true;
+                var start = 0;
+                do {
+                    Console.WriteLine("plotting {0} - {1}", start / 1000, (start + lenght) / 1000);
+                    success = GraphWriter.WriteDistanceSlice(args[0], args[1], start, start + lenght);
+                    start += lenght;
+                } while (success);
+                Console.WriteLine("plotting full cycle");
+                GraphWriter.Write(args[0], args[1]);
+                Console.WriteLine("done");
+                return;
+            }
+            Console.WriteLine("plotting graphs...");
+            GraphWriter.Write(args[0], args[1]);
+            Console.WriteLine("done");
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs
index 64ddb2f4503283ee3338aa7ef2135420bee889d3..6172449a69ea5186b5b1fb14962949a5e7991e47 100644
--- a/VectoConsole/Program.cs
+++ b/VectoConsole/Program.cs
@@ -14,14 +14,14 @@ using TUGraz.VectoCore.Models.Simulation.Impl;
 
 namespace VectoConsole
 {
-	internal static class Program
-	{
-		private static int NumLines;
-		private static int ProgessCounter { get; set; }
+    internal static class Program
+    {
+        private static int NumLines;
+        private static int ProgessCounter { get; set; }
 
-		private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]";
+        private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]";
 
-		private const string HELP = @"
+        private const string HELP = @"
 Commandline Interface for Vecto.
 
 Synopsis:
@@ -50,173 +50,180 @@ Examples:
 	vecto.exe -h
 ";
 
-		private static int Main(string[] args)
-		{
-			try {
-				// on -h display help and terminate.
-				if (args.Contains("-h")) {
-					ShowVersionInformation();
-					Console.Write(HELP);
-					return 0;
-				}
-
-				// on -v: activate verbose console logger
-				var logLevel = LogLevel.Fatal;
-
-				// Fatal > Error > Warn > Info > Debug > Trace
-				var debugEnabled = false;
-
-				if (args.Contains("-v")) {
-					// display errors, warnings
-					logLevel = LogLevel.Warn;
-					debugEnabled = true;
-				} else if (args.Contains("-vv")) {
-					// also display info
-					logLevel = LogLevel.Info;
-					debugEnabled = true;
-				} else if (args.Contains("-vvv")) {
-					// display debug messages
-					logLevel = LogLevel.Debug;
-					debugEnabled = true;
-				} else if (args.Contains("-vvvv")) {
-					// display everything!
-					logLevel = LogLevel.Trace;
-					debugEnabled = true;
-				}
-
-				var config = LogManager.Configuration;
-				//config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger")));
-				config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile")));
-				LogManager.Configuration = config;
-				Trace.Listeners.Add(new ConsoleTraceListener(true));
-
-				if (args.Contains("-V") || debugEnabled) {
-					ShowVersionInformation();
-				}
-
-				args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray();
-
-				// if no other arguments given: display usage and terminate
-				if (!args.Any()) {
-					Console.Write(USAGE);
-					return 1;
-				}
-
-				var stopWatch = new Stopwatch();
-				var timings = new Dictionary<string, double>();
-
-				// process the file list and start simulation
-				var fileList = args;
-
-				var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "",
-					Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile);
-				var sumWriter = new SummaryFileWriter(sumFileName);
-				var jobContainer = new JobContainer(sumWriter);
-
-				var mode = SimulatorFactory.FactoryMode.DeclarationMode;
-				if (args.Contains("-eng")) {
-					mode = SimulatorFactory.FactoryMode.EngineeringMode;
-					Console.ForegroundColor = ConsoleColor.White;
-					Console.WriteLine("Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!");
-					Console.ResetColor();
-				}
-
-				Console.WriteLine("Reading Job Files");
-				stopWatch.Start();
-				foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) {
-					var runsFactory = new SimulatorFactory(mode, file);
-					if (args.Contains("-mod")) {
-						runsFactory.WriteModalResults = true;
-					}
-					jobContainer.AddRuns(runsFactory);
-				}
-				stopWatch.Stop();
-				timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds);
-				stopWatch.Reset();
-
-				Console.WriteLine("Starting simulation runs");
-				if (debugEnabled) {
-					Console.ForegroundColor = ConsoleColor.White;
-					Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially");
-					Console.ResetColor();
-				}
-				Console.WriteLine();
-				stopWatch.Start();
-				jobContainer.Execute(!debugEnabled);
-
-				Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => {
-					var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC;
-					var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak;
-
-					if (isCtrlC) {
-						Console.WriteLine("Canceling simulation!");
-					}
-				};
-
-				//var x = Console.CursorLeft;
-				while (!jobContainer.AllCompleted) {
-					PrintProgress(jobContainer.GetProgress());
-					Thread.Sleep(250);
-				}
-				stopWatch.Stop();
-				timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds);
-
-				PrintProgress(jobContainer.GetProgress(), args.Contains("-t"));
-				if (args.Contains("-t")) {
-					PrintTimings(timings);
-				}
-			} catch (Exception e) {
-				Console.Error.WriteLine(e.Message);
-				//Trace.TraceError(e.ToString());
-				Console.ForegroundColor = ConsoleColor.Red;
-				Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)");
-				Console.ResetColor();
-				Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1;
-			}
-			return Environment.ExitCode;
-		}
-
-		private static void ShowVersionInformation()
-		{
-			var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll");
-			Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version);
-			Console.WriteLine("VectoCore: {0}", vectodll.Version);
-		}
-
-		private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData, bool showTiming = true)
-		{
-			Console.SetCursorPosition(0, Console.CursorTop - NumLines);
-			NumLines = 0;
-			var sumProgress = 0.0;
-			foreach (var progressEntry in progessData) {
-				if (progressEntry.Value.Success) {
-					Console.ForegroundColor = ConsoleColor.Green;
-				} else if (progressEntry.Value.Error != null) {
-					Console.ForegroundColor = ConsoleColor.Red;
-				}
-				var timingString = "";
-				if (showTiming && progressEntry.Value.ExecTime > 0) {
-					timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0);
-				}
-				Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString);
-				Console.ResetColor();
-				sumProgress += progressEntry.Value.Progress;
-				NumLines++;
-			}
-			sumProgress /= NumLines;
-			var spinner = "/-\\|"[ProgessCounter++ % 4];
-			var bar = new string('#', (int)(sumProgress * 100.0 / 2));
-			Console.WriteLine(string.Format("   {2}   [{1,-50}]  [{0,7:P}]", sumProgress, bar, spinner));
-			NumLines++;
-		}
-
-		private static void PrintTimings(Dictionary<string, double> timings)
-		{
-			Console.WriteLine();
-			Console.WriteLine("---- timing information ----");
-			foreach (var timing in timings) {
-				Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000);
-			}
-		}
-	}
+        private static JobContainer jobContainer;
+
+        private static int Main(string[] args)
+        {
+            try {
+                // on -h display help and terminate.
+                if (args.Contains("-h")) {
+                    ShowVersionInformation();
+                    Console.Write(HELP);
+                    return 0;
+                }
+
+                // on -v: activate verbose console logger
+                var logLevel = LogLevel.Fatal;
+
+                // Fatal > Error > Warn > Info > Debug > Trace
+                var debugEnabled = false;
+
+                if (args.Contains("-v")) {
+                    // display errors, warnings
+                    logLevel = LogLevel.Warn;
+                    debugEnabled = true;
+                } else if (args.Contains("-vv")) {
+                    // also display info
+                    logLevel = LogLevel.Info;
+                    debugEnabled = true;
+                } else if (args.Contains("-vvv")) {
+                    // display debug messages
+                    logLevel = LogLevel.Debug;
+                    debugEnabled = true;
+                } else if (args.Contains("-vvvv")) {
+                    // display everything!
+                    logLevel = LogLevel.Trace;
+                    debugEnabled = true;
+                }
+
+                var config = LogManager.Configuration;
+                //config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger")));
+                config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile")));
+                LogManager.Configuration = config;
+                Trace.Listeners.Add(new ConsoleTraceListener(true));
+
+                if (args.Contains("-V") || debugEnabled) {
+                    ShowVersionInformation();
+                }
+
+                args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray();
+
+                // if no other arguments given: display usage and terminate
+                if (!args.Any()) {
+                    Console.Write(USAGE);
+                    return 1;
+                }
+
+                var stopWatch = new Stopwatch();
+                var timings = new Dictionary<string, double>();
+
+                // process the file list and start simulation
+                var fileList = args;
+
+                var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "",
+                    Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile);
+                var sumWriter = new SummaryFileWriter(sumFileName);
+                jobContainer = new JobContainer(sumWriter);
+
+                var mode = SimulatorFactory.FactoryMode.DeclarationMode;
+                if (args.Contains("-eng")) {
+                    mode = SimulatorFactory.FactoryMode.EngineeringMode;
+                    Console.ForegroundColor = ConsoleColor.White;
+                    Console.WriteLine(
+                        "Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!");
+                    Console.ResetColor();
+                }
+
+                Console.WriteLine("Reading Job Files");
+                stopWatch.Start();
+                foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) {
+                    var runsFactory = new SimulatorFactory(mode, file);
+                    if (args.Contains("-mod")) {
+                        runsFactory.WriteModalResults = true;
+                    }
+                    jobContainer.AddRuns(runsFactory);
+                }
+                stopWatch.Stop();
+                timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds);
+                stopWatch.Reset();
+
+                Console.WriteLine("Starting simulation runs");
+                if (debugEnabled) {
+                    Console.ForegroundColor = ConsoleColor.White;
+                    Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially");
+                    Console.ResetColor();
+                }
+                Console.WriteLine();
+                stopWatch.Start();
+                jobContainer.Execute(!debugEnabled);
+
+                Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => {
+                    var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC;
+                    var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak;
+
+                    if (!isCtrlC) {
+                        return;
+                    }
+                    //Console.WriteLine("Canceling simulation!");
+                    e.Cancel = true;
+                    Program.jobContainer.CancelCurrent();
+                };
+
+                //var x = Console.CursorLeft;
+                while (!jobContainer.AllCompleted) {
+                    PrintProgress(jobContainer.GetProgress());
+                    Thread.Sleep(250);
+                }
+                stopWatch.Stop();
+                timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds);
+
+                PrintProgress(jobContainer.GetProgress(), args.Contains("-t"));
+                if (args.Contains("-t")) {
+                    PrintTimings(timings);
+                }
+            } catch (Exception e) {
+                Console.Error.WriteLine(e.Message);
+                //Trace.TraceError(e.ToString());
+                Console.ForegroundColor = ConsoleColor.Red;
+                Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)");
+                Console.ResetColor();
+                Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1;
+            }
+            return Environment.ExitCode;
+        }
+
+        private static void ShowVersionInformation()
+        {
+            var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll");
+            Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version);
+            Console.WriteLine("VectoCore: {0}", vectodll.Version);
+        }
+
+        private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData,
+            bool showTiming = true)
+        {
+            Console.SetCursorPosition(0, Console.CursorTop - NumLines);
+            NumLines = 0;
+            var sumProgress = 0.0;
+            foreach (var progressEntry in progessData) {
+                if (progressEntry.Value.Success) {
+                    Console.ForegroundColor = ConsoleColor.Green;
+                } else if (progressEntry.Value.Error != null) {
+                    Console.ForegroundColor = ConsoleColor.Red;
+                }
+                var timingString = "";
+                if (showTiming && progressEntry.Value.ExecTime > 0) {
+                    timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0);
+                }
+                Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString);
+                Console.ResetColor();
+                sumProgress += progressEntry.Value.Progress;
+                NumLines++;
+            }
+            sumProgress /= NumLines;
+            var spinner = "/-\\|"[ProgessCounter++ % 4];
+            var bar = new string('#', (int)(sumProgress * 100.0 / 2));
+            Console.WriteLine(string.Format("   {2}   [{1,-50}]  [{0,7:P}]", sumProgress, bar, spinner));
+            NumLines++;
+        }
+
+        private static void PrintTimings(Dictionary<string, double> timings)
+        {
+            Console.WriteLine();
+            Console.WriteLine("---- timing information ----");
+            foreach (var timing in timings) {
+                Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/Models/Simulation/Impl/JobContainer.cs
index e6e7c135834f5c656e46aa04d5264e5ab001da43..8d7c748dbe18a2e1e4b6aeb5ecb651b009a37c0e 100644
--- a/VectoCore/Models/Simulation/Impl/JobContainer.cs
+++ b/VectoCore/Models/Simulation/Impl/JobContainer.cs
@@ -8,182 +8,191 @@ using TUGraz.VectoCore.Models.Simulation.Data;
 
 namespace TUGraz.VectoCore.Models.Simulation.Impl
 {
-	/// <summary>
-	/// Container for simulation jobs.
-	/// </summary>
-	public class JobContainer : LoggingObject
-	{
-		internal readonly List<JobEntry> Runs = new List<JobEntry>();
-		private readonly SummaryFileWriter _sumWriter;
-
-		private static int _jobNumber;
-
-		/// <summary>
-		/// Initializes a new empty instance of the <see cref="JobContainer"/> class.
-		/// </summary>
-		/// <param name="sumWriter">The sum writer.</param>
-		public JobContainer(SummaryFileWriter sumWriter)
-		{
-			_sumWriter = sumWriter;
-		}
-
-		public void AddRun(IVectoRun run)
-		{
-			_jobNumber++;
-			Runs.Add(new JobEntry() {
-				Run = run,
-				Container = this,
-			});
-		}
-
-		public void AddRuns(IEnumerable<IVectoRun> runs)
-		{
-			_jobNumber++;
-			//Runs.AddRange(runs);
-			foreach (var run in runs) {
-				Runs.Add(new JobEntry() {
-					Run = run,
-					Container = this,
-				});
-			}
-		}
-
-		public void AddRuns(SimulatorFactory factory)
-		{
-			factory.SumWriter = _sumWriter;
-			factory.JobNumber = _jobNumber++;
-			AddRuns(factory.SimulationRuns());
-		}
-
-		/// <summary>
-		/// Execute all runs, waits until finished.
-		/// </summary>
-		public void Execute(bool multithreaded = true)
-		{
-			Log.Info("VectoRun started running. Executing Runs.");
-
-			foreach (var job in Runs) {
-				job.Worker = new BackgroundWorker() {
-					WorkerSupportsCancellation = true,
-					WorkerReportsProgress = true,
-				};
-				job.Worker.DoWork += job.DoWork;
-				job.Worker.ProgressChanged += job.ProgressChanged;
-				job.Worker.RunWorkerCompleted += job.RunWorkerCompleted;
-				if (multithreaded) {
-					job.Started = true;
-					job.Worker.RunWorkerAsync();
-				}
-			}
-			if (!multithreaded) {
-				var entry = Runs.First();
-				entry.Started = true;
-				entry.Worker.RunWorkerAsync();
-			}
-			//Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray());
+    /// <summary>
+    /// Container for simulation jobs.
+    /// </summary>
+    public class JobContainer : LoggingObject
+    {
+        internal readonly List<JobEntry> Runs = new List<JobEntry>();
+        private readonly SummaryFileWriter _sumWriter;
+
+        private static int _jobNumber;
+
+        /// <summary>
+        /// Initializes a new empty instance of the <see cref="JobContainer"/> class.
+        /// </summary>
+        /// <param name="sumWriter">The sum writer.</param>
+        public JobContainer(SummaryFileWriter sumWriter)
+        {
+            _sumWriter = sumWriter;
+        }
+
+        public void AddRun(IVectoRun run)
+        {
+            _jobNumber++;
+            Runs.Add(new JobEntry() {
+                Run = run,
+                Container = this,
+            });
+        }
+
+        public void AddRuns(IEnumerable<IVectoRun> runs)
+        {
+            _jobNumber++;
+            //Runs.AddRange(runs);
+            foreach (var run in runs) {
+                Runs.Add(new JobEntry() {
+                    Run = run,
+                    Container = this,
+                });
+            }
+        }
+
+        public void AddRuns(SimulatorFactory factory)
+        {
+            factory.SumWriter = _sumWriter;
+            factory.JobNumber = _jobNumber++;
+            AddRuns(factory.SimulationRuns());
+        }
+
+        /// <summary>
+        /// Execute all runs, waits until finished.
+        /// </summary>
+        public void Execute(bool multithreaded = true)
+        {
+            Log.Info("VectoRun started running. Executing Runs.");
+
+            foreach (var job in Runs) {
+                job.Worker = new BackgroundWorker() {
+                    WorkerSupportsCancellation = true,
+                    WorkerReportsProgress = true,
+                };
+                job.Worker.DoWork += job.DoWork;
+                job.Worker.ProgressChanged += job.ProgressChanged;
+                job.Worker.RunWorkerCompleted += job.RunWorkerCompleted;
+                if (multithreaded) {
+                    job.Started = true;
+                    job.Worker.RunWorkerAsync();
+                }
+            }
+            if (!multithreaded) {
+                var entry = Runs.First();
+                entry.Started = true;
+                entry.Worker.RunWorkerAsync();
+            }
+            //Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray());
 
 			//_sumWriter.Finish();
-		}
-
-		public void Cancel()
-		{
-			foreach (var job in Runs) {
-				if (job.Worker != null && job.Worker.WorkerSupportsCancellation) {
-					job.Worker.CancelAsync();
-				}
-			}
-		}
-
-		private static AutoResetEvent resetEvent = new AutoResetEvent(false);
-
-		public void WaitFinished()
-		{
-			resetEvent.WaitOne();
-		}
-
-
-		private void JobCompleted(JobEntry jobEntry)
-		{
-			var next = Runs.FirstOrDefault(x => x.Started == false);
-			if (next != null) {
-				next.Started = true;
-				next.Worker.RunWorkerAsync();
-			}
-			if (Runs.Count(x => x.Done == true) == Runs.Count()) {
-				_sumWriter.Finish();
-				resetEvent.Set();
-			}
-		}
-
-		public Dictionary<string, ProgressEntry> GetProgress()
-		{
-			return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() {
-				Progress = entry.Progress,
-				Done = entry.Done,
-				ExecTime = entry.ExecTime,
-				Success = entry.Success,
-				Canceled = entry.Canceled,
-				Error = entry.ExecException
-			});
-		}
-
-		public bool AllCompleted
-		{
-			get { return (Runs.Count(x => x.Done == true) == Runs.Count()); }
-		}
-
-		public class ProgressEntry
-		{
-			public double Progress;
-			public double ExecTime;
-			public Exception Error;
-			public bool Canceled;
-			public bool Success;
-			public bool Done;
-		}
-
-		internal class JobEntry : LoggingObject
-		{
-			public IVectoRun Run;
-			public JobContainer Container;
-			public double Progress;
-			public bool Done;
-			public bool Started;
-			public bool Success;
-			public bool Canceled;
-			public double ExecTime;
-			public Exception ExecException;
-
-			public BackgroundWorker Worker;
-
-			public void DoWork(object sender, DoWorkEventArgs e)
-			{
-				var stopWatch = new Stopwatch();
-				stopWatch.Start();
-				var worker = sender as BackgroundWorker;
-				try {
-					Run.Run(worker);
-				} catch (Exception ex) {
-					Log.Error(ex, "Error during simulation run!");
-					ExecException = ex;
-				}
-				if (worker != null && worker.CancellationPending) {
-					e.Cancel = true;
-					Canceled = true;
-				}
-				stopWatch.Stop();
-				Success = Run.FinishedWithoutErrors;
-				Done = true;
-				ExecTime = stopWatch.Elapsed.TotalMilliseconds;
-				Container.JobCompleted(this);
-			}
-
-			public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {}
-
-			public void ProgressChanged(object sender, ProgressChangedEventArgs e)
-			{
-				Progress = e.ProgressPercentage / 10000.0;
-			}
-		}
-	}
+        }
+
+        public void Cancel()
+        {
+            foreach (var job in Runs) {
+                if (job.Worker != null && job.Worker.WorkerSupportsCancellation) {
+                    job.Worker.CancelAsync();
+                }
+            }
+        }
+
+        public void CancelCurrent()
+        {
+            foreach (var job in Runs) {
+                if (job.Worker != null && job.Worker.IsBusy && job.Worker.WorkerSupportsCancellation) {
+                    job.Worker.CancelAsync();
+                }
+            }
+        }
+
+        private static AutoResetEvent resetEvent = new AutoResetEvent(false);
+
+        public void WaitFinished()
+        {
+            resetEvent.WaitOne();
+        }
+
+
+        private void JobCompleted(JobEntry jobEntry)
+        {
+            var next = Runs.FirstOrDefault(x => x.Started == false);
+            if (next != null) {
+                next.Started = true;
+                next.Worker.RunWorkerAsync();
+            }
+            if (Runs.Count(x => x.Done == true) == Runs.Count()) {
+                _sumWriter.Finish();
+                resetEvent.Set();
+            }
+        }
+
+        public Dictionary<string, ProgressEntry> GetProgress()
+        {
+            return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() {
+                Progress = entry.Progress,
+                Done = entry.Done,
+                ExecTime = entry.ExecTime,
+                Success = entry.Success,
+                Canceled = entry.Canceled,
+                Error = entry.ExecException
+            });
+        }
+
+        public bool AllCompleted
+        {
+            get { return (Runs.Count(x => x.Done == true) == Runs.Count()); }
+        }
+
+        public class ProgressEntry
+        {
+            public double Progress;
+            public double ExecTime;
+            public Exception Error;
+            public bool Canceled;
+            public bool Success;
+            public bool Done;
+        }
+
+        internal class JobEntry : LoggingObject
+        {
+            public IVectoRun Run;
+            public JobContainer Container;
+            public double Progress;
+            public bool Done;
+            public bool Started;
+            public bool Success;
+            public bool Canceled;
+            public double ExecTime;
+            public Exception ExecException;
+
+            public BackgroundWorker Worker;
+
+            public void DoWork(object sender, DoWorkEventArgs e)
+            {
+                var stopWatch = new Stopwatch();
+                stopWatch.Start();
+                var worker = sender as BackgroundWorker;
+                try {
+                    Run.Run(worker);
+                } catch (Exception ex) {
+                    Log.Error(ex, "Error during simulation run!");
+                    ExecException = ex;
+                }
+                if (worker != null && worker.CancellationPending) {
+                    e.Cancel = true;
+                    Canceled = true;
+                }
+                stopWatch.Stop();
+                Success = Run.FinishedWithoutErrors;
+                Done = true;
+                ExecTime = stopWatch.Elapsed.TotalMilliseconds;
+                Container.JobCompleted(this);
+            }
+
+            public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {}
+
+            public void ProgressChanged(object sender, ProgressChangedEventArgs e)
+            {
+                Progress = e.ProgressPercentage / 10000.0;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Utils/GraphWriter.cs b/VectoCoreTest/Utils/GraphWriter.cs
index 4522ac47f39fdbeda5073b5ca75cb3d6b1ac79cb..4c62b9881a821257d457bbd8fe5f7b4050de78b4 100644
--- a/VectoCoreTest/Utils/GraphWriter.cs
+++ b/VectoCoreTest/Utils/GraphWriter.cs
@@ -18,248 +18,403 @@ using Point = System.Drawing.Point;
 
 namespace TUGraz.VectoCore.Tests.Utils
 {
-	public static class GraphWriter
-	{
-		private static bool _enabled = true;
+    public static class GraphWriter
+    {
+        private static bool _enabled = true;
 
-		private static Size _diagramSize = new Size(2000, 440);
+        private static Size _diagramSize = new Size(2000, 440);
 
         private static readonly Font AxisLabelFont = new Font("Consolas", 10);
-	    private static readonly Font AxisTitleFont = new Font("Verdana", 12);
+        private static readonly Font AxisTitleFont = new Font("Verdana", 12);
         private static readonly Font LegendFont = new Font("Verdana", 14);
 
-	    public static void Enabled()
-		{
-			_enabled = true;
-		}
-
-		public static void Disable()
-		{
-			_enabled = false;
-		}
-
-		public static void Write(string fileNameV3, string fileNameV22 = null)
-		{
-			if (!_enabled) {
-				return;
-			}
-
-			var modDataV3 = VectoCSVFile.Read(fileNameV3);
-			if (!File.Exists(fileNameV22)) {
-				LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22);
-				//Write(fileNameV3);
-				//return;
-			}
-		    DataTable modDataV22 = null;
-		    if (fileNameV22 != null) {
-		        modDataV22 = VectoCSVFile.Read(fileNameV22);
-		    }
-		    var xfields = new[] { ModalResultField.time, ModalResultField.dist };
-
-			var yfields = new[] { ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap };
-
-			var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count());
-
-			foreach (var xfield in xfields) {
-				var fileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileNameV3), xfield.GetName());
-
-			    var x = LoadData(modDataV3, xfield.GetName());
-			    var x2 = new double[]{ double.NegativeInfinity};
-			    if (fileNameV22 != null && modDataV22 != null) {
-			             x2 = LoadData(modDataV22, xfield.GetName());
-			    }
-			    var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count());
-				var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0);
-				var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0);
-				var chart = new Chart { Size = plotSize };
-
-
-				for (var i = 0; i < yfields.Length; i++) {
-					var yfield = yfields[i];
+        public static void Enabled()
+        {
+            _enabled = true;
+        }
+
+        public static void Disable()
+        {
+            _enabled = false;
+        }
+
+        public static void Write(string fileNameV3, string fileNameV22 = null)
+        {
+            if (!_enabled) {
+                return;
+            }
+
+            var modDataV3 = VectoCSVFile.Read(fileNameV3);
+            if (!File.Exists(fileNameV22)) {
+                LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22);
+                //Write(fileNameV3);
+                //return;
+            }
+            DataTable modDataV22 = null;
+            if (fileNameV22 != null) {
+                modDataV22 = VectoCSVFile.Read(fileNameV22);
+            }
+            var xfields = new[] { ModalResultField.time, ModalResultField.dist };
+
+            var yfields = new[] {
+                ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear,
+                ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap
+            };
+
+            var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count());
+
+            foreach (var xfield in xfields) {
+                var fileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileNameV3),
+                    xfield.GetName());
+
+                var x = LoadData(modDataV3, xfield.GetName());
+                var x2 = new double[] { double.NegativeInfinity };
+                if (fileNameV22 != null && modDataV22 != null) {
+                    x2 = LoadData(modDataV22, xfield.GetName());
+                }
+                var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count());
+                var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0);
+                var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0);
+                var chart = new Chart { Size = plotSize };
+
+
+                for (var i = 0; i < yfields.Length; i++) {
+                    var yfield = yfields[i];
                     var y = LoadData(modDataV3, yfield.GetName());
 
 
-                    var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX, yfield.GetCaption(), yfield == ModalResultField.Gear);
+                    var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX,
+                        yfield.GetCaption(), yfield == ModalResultField.Gear);
 
-				    var legend = CreateLegend(chart, yfield.ToString());
+                    var legend = CreateLegend(chart, yfield.ToString());
 
-				    if (yfield == ModalResultField.v_act) {
-				        var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName());
+                    if (yfield == ModalResultField.v_act) {
+                        var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName());
                         var series3 = CreateSeries("v_target", legend, chartArea, chart, Color.Green, x, y3);
-					}
 
-				    var series1 = CreateSeries( string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart,Color.Blue, x, y);
-
-				    if (fileNameV22 != null) {
-				        var y2 = LoadData(modDataV22, yfield.GetName());
-				        var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart, Color.Red, x2,
-				            y2);
-				    }
+                        var grad = LoadData(modDataV3, ModalResultField.grad.GetName());
+
+                        chartArea.AxisY2.Enabled = AxisEnabled.True;
+                        chartArea.AxisY2.Title = "gradient [%]";
+                        chartArea.AxisY2.TitleFont = AxisTitleFont;
+                        chartArea.AxisY2.LabelStyle.Font = AxisLabelFont;
+                        chartArea.AxisY2.LabelAutoFitStyle = LabelAutoFitStyles.None;
+                        chartArea.AxisY2.MinorGrid.Enabled = false;
+                        chartArea.AxisY2.MajorGrid.Enabled = false;
+                        var max = Math.Max(-Math.Round(grad.Min() * 2), Math.Round(grad.Max() * 2));
+                        //chartArea.AxisY2.si
+                        //chartArea.AxisY2.Minimum = -max;
+                        //chartArea.AxisY2.Maximum = max;
+                        chartArea.AxisY2.RoundAxisValues();
+                        chartArea.AxisY2.Interval = Math.Round(max / 5);
+
+                        var seriesGrad = CreateSeries("Gradient", legend, chartArea, chart, Color.Coral, x, grad);
+                        seriesGrad.YAxisType = AxisType.Secondary;
+                    }
+
+                    var series1 = CreateSeries(string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart,
+                        Color.Blue, x, y);
+
+                    if (fileNameV22 != null) {
+                        var y2 = LoadData(modDataV22, yfield.GetName());
+                        var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart,
+                            Color.Red, x2,
+                            y2);
+                    }
+
+                    PositionChartArea(chartArea, titleHeight, i, yfields.Count());
+
+                    if (i > 0) {
+                        AlignChart(chart, yfield.ToString(), yfields[0].ToString());
+                    }
+                }
 
-				    PositionChartArea(chartArea, titleHeight, i, yfields.Count());
+                AddTitle(chart, Path.GetFileNameWithoutExtension(fileName), yfields[0].ToString());
 
-				    if (i > 0) {
-                        AlignChart(chart, yfield.ToString(), yfields[0].ToString());
-				    }
-				}
+                chart.Invalidate();
+                chart.SaveImage(fileName, ChartImageFormat.Png);
+            }
+        }
+
+        public static bool WriteDistanceSlice(string fileNameV3, string fileNameV22, double start, double end)
+        {
+            if (!_enabled) {
+                return true;
+            }
+
+            var modDataV3Iput = VectoCSVFile.Read(fileNameV3);
+            //var modDataV3View = new DataView(modDataV3Iput) {
+            //    RowFilter = string.Format(@"dist > {0} AND dist < {1}", start, end)
+            //};
+            //var modDataV3 = modDataV3View.ToTable();
+            var modDataV3tmp = modDataV3Iput.AsEnumerable().Where(row => {
+                var s = row.ParseDouble("dist");
+                return s >= start && s <= end;
+            });
+
+
+            if (!File.Exists(fileNameV22)) {
+                //LogManager.GetCurrentClassLogger().Error("Modfile V2.2 not found: " + fileNameV22);
+                //Write(fileNameV3);
+                //return;
+            }
+            DataTable modDataV22 = null;
+            if (fileNameV22 != null) {
+                var modDataV22Input = VectoCSVFile.Read(fileNameV22);
+                //var modDataV22View = new DataView(modDataV22Input) {
+                //    RowFilter = string.Format(@"dist > {0} AND dist < {1}", start, end)
+                //};
+                var modDataV22tmp = modDataV22Input.AsEnumerable().Where(row => {
+                    var s = row.ParseDouble("dist");
+                    return s >= start && s <= end;
+                });
+                if (!(modDataV3tmp.Any() || modDataV22tmp.Any())) {
+                    return false;
+                }
+                modDataV22 = modDataV22tmp.CopyToDataTable();
+            } else {
+                if (!modDataV3tmp.Any()) {
+                    return false;
+                }
+            }
+            var modDataV3 = modDataV3tmp.CopyToDataTable();
+
+            //var xfields = new[] { ModalResultField.dist };
+            var xfield = ModalResultField.dist;
+            var yfields = new[] {
+                ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear,
+                ModalResultField.Pe_eng, ModalResultField.Tq_eng, ModalResultField.FCMap
+            };
+
+            var titleHeight = (50 * 100.0f) / (_diagramSize.Height * yfields.Count());
+
+            //foreach (var xfield in xfields) {
+            var fileName = string.Format("{0}_{1}-{2:D3}_{3:D3}.png", Path.GetFileNameWithoutExtension(fileNameV3),
+                xfield.GetName(), (int)(start / 1000), (int)(end / 1000));
+
+            var x = LoadData(modDataV3, xfield.GetName());
+            var x2 = new double[] { double.NegativeInfinity };
+            if (fileNameV22 != null && modDataV22 != null) {
+                x2 = LoadData(modDataV22, xfield.GetName());
+            }
+            var plotSize = new Size(_diagramSize.Width, _diagramSize.Height * yfields.Count());
+            var maxX = (int)(Math.Ceiling(Math.Max(x.Max(), x2.Max()) * 1.01 / 10.0) * 10.0);
+            var minX = (int)(Math.Floor(Math.Max(x.Min(), x2.Min()) / 10.0) * 10.0);
+            var chart = new Chart { Size = plotSize };
+
+
+            for (var i = 0; i < yfields.Length; i++) {
+                var yfield = yfields[i];
+                var y = LoadData(modDataV3, yfield.GetName());
+
+
+                var chartArea = AddChartArea(chart, yfield.ToString(), xfield.GetCaption(), maxX, minX,
+                    yfield.GetCaption(), yfield == ModalResultField.Gear);
+
+                var legend = CreateLegend(chart, yfield.ToString());
+
+                if (yfield == ModalResultField.v_act) {
+                    var y3 = LoadData(modDataV3, ModalResultField.v_targ.GetName());
+                    var series3 = CreateSeries("v_target", legend, chartArea, chart, Color.Green, x, y3);
+
+                    var grad = LoadData(modDataV3, ModalResultField.grad.GetName());
+
+                    chartArea.AxisY2.Enabled = AxisEnabled.True;
+                    chartArea.AxisY2.Title = "gradient [%]";
+                    chartArea.AxisY2.TitleFont = AxisTitleFont;
+                    chartArea.AxisY2.LabelStyle.Font = AxisLabelFont;
+                    chartArea.AxisY2.LabelAutoFitStyle = LabelAutoFitStyles.None;
+                    chartArea.AxisY2.MinorGrid.Enabled = false;
+                    chartArea.AxisY2.MajorGrid.Enabled = false;
+                    var max = Math.Max(-Math.Round(grad.Min() * 2), Math.Round(grad.Max() * 2));
+                    //chartArea.AxisY2.si
+                    chartArea.AxisY2.Minimum = -max;
+                    chartArea.AxisY2.Maximum = max;
+                    chartArea.AxisY2.RoundAxisValues();
+
+                    var seriesGrad = CreateSeries("Gradient", legend, chartArea, chart, Color.Coral, x, grad);
+                    seriesGrad.YAxisType = AxisType.Secondary;
+                }
+
+
+                var series1 = CreateSeries(string.Format("Vecto 3 - {0}", yfield), legend, chartArea, chart,
+                    Color.Blue, x, y);
+
+                if (fileNameV22 != null) {
+                    var y2 = LoadData(modDataV22, yfield.GetName());
+                    var series2 = CreateSeries(string.Format("Vecto 2.2 - {0}", yfield), legend, chartArea, chart,
+                        Color.Red, x2, y2);
+                }
+
+                PositionChartArea(chartArea, titleHeight, i, yfields.Count());
+
+                if (i > 0) {
+                    AlignChart(chart, yfield.ToString(), yfields[0].ToString());
+                }
+                //}
 
                 AddTitle(chart, Path.GetFileNameWithoutExtension(fileName), yfields[0].ToString());
 
-			    chart.Invalidate();
-				chart.SaveImage(fileName, ChartImageFormat.Png);
-			}
-		}
-
-	    private static void AddTitle(Chart chart, string titleText, string dockToChartArea)
-	    {
-	        var title = new Title();
-	        title.Text = titleText;
-	        title.DockedToChartArea = dockToChartArea;
-	        title.IsDockedInsideChartArea = false;
-	        title.Font = new Font("Verdana", 18, FontStyle.Bold);
-	        chart.Titles.Add(title);
-	    }
-
-	    private static double[] LoadData(DataTable modDataV3, string field)
-	    {
-	        return modDataV3.Rows.Cast<DataRow>()
-	            .Select(v => v.Field<string>(field).Length == 0 
-	                ? Double.NaN 
-	                : v.Field<string>(field).ToDouble())
-	            .ToArray();
-	    }
-
-	    private static void AlignChart(Chart chart, string chartToAlign, string chartToAlignWith)
-	    {
-	        chart.ChartAreas[chartToAlign].AlignWithChartArea = chartToAlignWith;
-	        chart.ChartAreas[chartToAlign].AlignmentOrientation = AreaAlignmentOrientations.Vertical;
-	        chart.ChartAreas[chartToAlign].AlignmentStyle = AreaAlignmentStyles.All;
-	    }
-
-	    private static void PositionChartArea(ChartArea chartArea, float titleHeight, int i, int numCharts)
-	    {
-	        chartArea.Position.Auto = false;
-	        chartArea.Position.Width = 85;
-	        chartArea.Position.Height = (100.0f - titleHeight) / numCharts;
-	        chartArea.Position.X = 0;
-	        chartArea.Position.Y = (i * (100.0f - titleHeight)) / numCharts + titleHeight;
-	    }
-
-	    private static ChartArea AddChartArea(Chart chart, string name, string axisXTitle, int xMax, int xMin, string axisYTitle, bool discreteValues)
-	    {
-	        var chartArea = new ChartArea { Name = name };
-	        chartArea.AxisX.MajorGrid.LineColor = Color.DarkGray;
-	        chartArea.AxisY.MajorGrid.LineColor = Color.DarkGray;
-	        chartArea.AxisX.LabelStyle.Font = AxisLabelFont;
-	        chartArea.AxisY.LabelStyle.Font = AxisLabelFont;
-
-	        chartArea.AxisX.Interval = xMax / 20.0;
-	        chartArea.AxisX.Maximum = xMax;
-	        chartArea.AxisX.Minimum = xMin;
-	        chartArea.AxisX.MinorGrid.Enabled = true;
-	        chartArea.AxisX.MinorGrid.Interval = xMax / 100.0;
-	        chartArea.AxisX.MinorGrid.LineColor = Color.LightGray;
-	        chartArea.AxisX.Title = axisXTitle;
-	        chartArea.AxisX.TitleFont = AxisTitleFont;
-	        chartArea.AxisX.RoundAxisValues();
-	        chartArea.AxisX.MajorTickMark.Size = 2 * 100.0f / _diagramSize.Height;
-
-	        chartArea.AxisY.Title = axisYTitle;
-	        chartArea.AxisY.TitleFont = AxisTitleFont;
-	        chartArea.AxisY.RoundAxisValues();
-	        if (discreteValues) {
-	            chartArea.AxisY.MajorGrid.Interval = 1;
-	            chartArea.AxisY.MinorGrid.Enabled = false;
-	        } else {
-	            chartArea.AxisY.MinorGrid.Enabled = true;
-	        }
-	        chartArea.AxisY.MinorGrid.LineColor = Color.LightGray;
-	        chartArea.AxisY.MajorTickMark.Size = 5 * 100.0f / _diagramSize.Width;
-
-	        chart.ChartAreas.Add(chartArea);
-	        return chartArea;
-	    }
-
-	    private static Legend CreateLegend(Chart chart, string dockToChartArea)
-	    {
-	        var legend = new Legend(dockToChartArea.ToString()) {
-	            Docking = Docking.Right,
-	            IsDockedInsideChartArea = false,
-	            DockedToChartArea = dockToChartArea,
-	            Font = LegendFont,
-	        };
-	        chart.Legends.Add(legend);
-	        return legend;
-	    }
-
-	    private static Series CreateSeries(String name, Legend legend, ChartArea chartArea, Chart chart, Color color, double[] x, double[] y)
-	    {
-	        ModalResultField yfield;
-	        var series1 = new Series {
-	            Name = name,
-	            ChartType = SeriesChartType.Line,
-	            Color = color,
-	            BorderWidth = 2,
-	            Legend = legend.Name,
-	            IsVisibleInLegend = true,
-	            ChartArea = chartArea.Name,
-	        };
-
-	        chart.Series.Add(series1);
-	        chart.Series[series1.Name].Points.DataBindXY(x, y);
-	        return series1;
-	    }
-
-	    //public static void Write(string fileName)
-		//{
-		//	if (!_enabled) {
-		//		return;
-		//	}
-
-		//	var modDataV3 = VectoCSVFile.Read(fileName);
-
-		//	var xfields = new[] { ModalResultField.time, ModalResultField.dist };
-
-		//	var yfields = new[] {
-		//		ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng,
-		//		ModalResultField.Tq_eng, ModalResultField.FCMap
-		//	};
-
-		//	var images = new List<Stream>();
-		//	try {
-		//		foreach (var xfield in xfields) {
-		//			var x = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(xfield.GetName())).ToArray();
-
-		//			for (var i = 1; i <= yfields.Length; i++) {
-		//				var yfield = yfields[i - 1];
-		//				var y = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(yfield.GetName())).ToArray();
-
-		//				var values = string.Format("{0}|{1}", string.Join(",", x), string.Join(",", y));
-
-		//				if (yfield == ModalResultField.v_act) {
-		//					var y3 =
-		//						modDataV3.Rows.Cast<DataRow>()
-		//							.Select(v => v.Field<string>(ModalResultField.v_targ.GetName()))
-		//							.Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v);
-
-		//					values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3));
-		//				}
-
-		//				values = values.Replace("NaN", "0");
-		//				if (values.Length > 14000) {
-		//					// remove all decimal places to reduce request size
-		//					values = Regex.Replace(values, @"\..*?,", ",");
-		//				}
-		//				var maxX = (int)Math.Ceiling(x.ToDouble().Max());
-		//				images.Add(CreateGraphStream(xfield.GetCaption(), yfield.GetCaption(), maxX, values));
-		//			}
-		//			var outfileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileName), xfield.GetName());
-		//			SaveImages(outfileName, images.ToArray());
-		//			images.Clear();
-		//		}
-		//	} finally {
-		//		images.ForEach(x => x.Close());
-		//	}
-		//}
-	}
+                chart.Invalidate();
+                chart.SaveImage(fileName, ChartImageFormat.Png);
+            }
+            return true;
+        }
+
+
+        private static void AddTitle(Chart chart, string titleText, string dockToChartArea)
+        {
+            var title = new Title();
+            title.Text = titleText;
+            title.DockedToChartArea = dockToChartArea;
+            title.IsDockedInsideChartArea = false;
+            title.Font = new Font("Verdana", 18, FontStyle.Bold);
+            chart.Titles.Add(title);
+        }
+
+        private static double[] LoadData(DataTable modDataV3, string field)
+        {
+            return modDataV3.Rows.Cast<DataRow>()
+                .Select(v => v.Field<string>(field).Length == 0
+                    ? Double.NaN
+                    : v.Field<string>(field).ToDouble())
+                .ToArray();
+        }
+
+
+        private static void AlignChart(Chart chart, string chartToAlign, string chartToAlignWith)
+        {
+            chart.ChartAreas[chartToAlign].AlignWithChartArea = chartToAlignWith;
+            chart.ChartAreas[chartToAlign].AlignmentOrientation = AreaAlignmentOrientations.Vertical;
+            chart.ChartAreas[chartToAlign].AlignmentStyle = AreaAlignmentStyles.All;
+        }
+
+        private static void PositionChartArea(ChartArea chartArea, float titleHeight, int i, int numCharts)
+        {
+            chartArea.Position.Auto = false;
+            chartArea.Position.Width = 85;
+            chartArea.Position.Height = (100.0f - titleHeight) / numCharts;
+            chartArea.Position.X = 0;
+            chartArea.Position.Y = (i * (100.0f - titleHeight)) / numCharts + titleHeight;
+        }
+
+        private static ChartArea AddChartArea(Chart chart, string name, string axisXTitle, int xMax, int xMin,
+            string axisYTitle, bool discreteValues)
+        {
+            var chartArea = new ChartArea { Name = name };
+            chartArea.AxisX.MajorGrid.LineColor = Color.DarkGray;
+            chartArea.AxisY.MajorGrid.LineColor = Color.DarkGray;
+            chartArea.AxisX.LabelStyle.Font = AxisLabelFont;
+            chartArea.AxisY.LabelStyle.Font = AxisLabelFont;
+
+            chartArea.AxisX.Interval = xMax / 20.0;
+            chartArea.AxisX.Maximum = xMax;
+            chartArea.AxisX.Minimum = xMin;
+            chartArea.AxisX.MinorGrid.Enabled = true;
+            chartArea.AxisX.MinorGrid.Interval = (xMax - xMin) / 100.0;
+            chartArea.AxisX.MinorGrid.LineColor = Color.LightGray;
+            chartArea.AxisX.Title = axisXTitle;
+            chartArea.AxisX.TitleFont = AxisTitleFont;
+            chartArea.AxisX.RoundAxisValues();
+            chartArea.AxisX.MajorTickMark.Size = 2 * 100.0f / _diagramSize.Height;
+
+            chartArea.AxisY.Title = axisYTitle;
+            chartArea.AxisY.TitleFont = AxisTitleFont;
+            chartArea.AxisY.RoundAxisValues();
+            if (discreteValues) {
+                chartArea.AxisY.MajorGrid.Interval = 1;
+                chartArea.AxisY.MinorGrid.Enabled = false;
+            } else {
+                chartArea.AxisY.MinorGrid.Enabled = true;
+            }
+            chartArea.AxisY.MinorGrid.LineColor = Color.LightGray;
+            chartArea.AxisY.MajorTickMark.Size = 5 * 100.0f / _diagramSize.Width;
+
+            chart.ChartAreas.Add(chartArea);
+            return chartArea;
+        }
+
+        private static Legend CreateLegend(Chart chart, string dockToChartArea)
+        {
+            var legend = new Legend(dockToChartArea.ToString()) {
+                Docking = Docking.Right,
+                IsDockedInsideChartArea = false,
+                DockedToChartArea = dockToChartArea,
+                Font = LegendFont,
+            };
+            chart.Legends.Add(legend);
+            return legend;
+        }
+
+        private static Series CreateSeries(String name, Legend legend, ChartArea chartArea, Chart chart, Color color,
+            double[] x, double[] y)
+        {
+            ModalResultField yfield;
+            var series1 = new Series {
+                Name = name,
+                ChartType = SeriesChartType.Line,
+                Color = color,
+                BorderWidth = 2,
+                Legend = legend.Name,
+                IsVisibleInLegend = true,
+                ChartArea = chartArea.Name,
+            };
+
+            chart.Series.Add(series1);
+            chart.Series[series1.Name].Points.DataBindXY(x, y);
+            return series1;
+        }
+
+        //public static void Write(string fileName)
+        //{
+        //	if (!_enabled) {
+        //		return;
+        //	}
+
+        //	var modDataV3 = VectoCSVFile.Read(fileName);
+
+        //	var xfields = new[] { ModalResultField.time, ModalResultField.dist };
+
+        //	var yfields = new[] {
+        //		ModalResultField.v_act, ModalResultField.acc, ModalResultField.n, ModalResultField.Gear, ModalResultField.Pe_eng,
+        //		ModalResultField.Tq_eng, ModalResultField.FCMap
+        //	};
+
+        //	var images = new List<Stream>();
+        //	try {
+        //		foreach (var xfield in xfields) {
+        //			var x = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(xfield.GetName())).ToArray();
+
+        //			for (var i = 1; i <= yfields.Length; i++) {
+        //				var yfield = yfields[i - 1];
+        //				var y = modDataV3.Rows.Cast<DataRow>().Select(v => v.Field<string>(yfield.GetName())).ToArray();
+
+        //				var values = string.Format("{0}|{1}", string.Join(",", x), string.Join(",", y));
+
+        //				if (yfield == ModalResultField.v_act) {
+        //					var y3 =
+        //						modDataV3.Rows.Cast<DataRow>()
+        //							.Select(v => v.Field<string>(ModalResultField.v_targ.GetName()))
+        //							.Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v);
+
+        //					values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3));
+        //				}
+
+        //				values = values.Replace("NaN", "0");
+        //				if (values.Length > 14000) {
+        //					// remove all decimal places to reduce request size
+        //					values = Regex.Replace(values, @"\..*?,", ",");
+        //				}
+        //				var maxX = (int)Math.Ceiling(x.ToDouble().Max());
+        //				images.Add(CreateGraphStream(xfield.GetCaption(), yfield.GetCaption(), maxX, values));
+        //			}
+        //			var outfileName = string.Format("{0}_{1}.png", Path.GetFileNameWithoutExtension(fileName), xfield.GetName());
+        //			SaveImages(outfileName, images.ToArray());
+        //			images.Clear();
+        //		}
+        //	} finally {
+        //		images.ForEach(x => x.Close());
+        //	}
+        //}
+    }
 }
\ No newline at end of file