Index: branches/HeuristicLab.Drawing/CustomPostBuildTemplate_UpdateLocalInstallation.cmd
===================================================================
--- branches/HeuristicLab.Drawing/CustomPostBuildTemplate_UpdateLocalInstallation.cmd	(revision 4773)
+++ branches/HeuristicLab.Drawing/CustomPostBuildTemplate_UpdateLocalInstallation.cmd	(revision 4773)
@@ -0,0 +1,4 @@
+set target=C:\Program Files\HeuristicLab 3.3
+
+copy "%Source%" "%target%"
+If "%Files.0%" neq "" For /F "tokens=2 delims===" %%A in ('set Files.') DO copy "%%A" "%target%"
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing.sln
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing.sln	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing.sln	(revision 4773)
@@ -0,0 +1,32 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Drawing-3.3", "HeuristicLab.Drawing\3.3\HeuristicLab.Drawing-3.3.csproj", "{B462D3CC-8866-42F0-9832-AD0967613B72}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|x64.ActiveCfg = Debug|x64
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|x64.Build.0 = Debug|x64
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|x86.ActiveCfg = Debug|x86
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Debug|x86.Build.0 = Debug|x86
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|x64.ActiveCfg = Release|x64
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|x64.Build.0 = Release|x64
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|x86.ActiveCfg = Release|x86
+		{B462D3CC-8866-42F0-9832-AD0967613B72}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/AxisType.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/AxisType.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/AxisType.cs	(revision 4773)
@@ -0,0 +1,34 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HeuristicLab.Drawing {
+  [FlagsAttribute]
+  public enum AxisType {
+    None = 0,
+    Horizontal = 1,
+    Vertical = 2,
+    Both = Horizontal | Vertical
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Chart.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Chart.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Chart.cs	(revision 4773)
@@ -0,0 +1,279 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public class Chart : IChart {
+    private PointD originalLowerLeft;
+    private PointD originalUpperRight;
+    private List<Offset> zoomHistory;
+
+    private ChartMode myMode;
+    public virtual ChartMode Mode {
+      get { return myMode; }
+      set {
+        myMode = value;
+        OnUpdate();
+      }
+    }
+
+    private PointD myLowerLeft;
+    public virtual PointD LowerLeft {
+      get { return myLowerLeft; }
+    }
+    private PointD myUpperRight;
+    public virtual PointD UpperRight {
+      get { return myUpperRight; }
+    }
+    public virtual SizeD Size {
+      get { return new SizeD(UpperRight.X - LowerLeft.X, UpperRight.Y - LowerLeft.Y); }
+    }
+    private Size mySizeInPixels;
+    public Size SizeInPixels {
+      get { return mySizeInPixels; }
+    }
+    public SizeD PixelToWorldRatio {
+      get { return new SizeD(Size.Width / SizeInPixels.Width, Size.Height / SizeInPixels.Height); }
+    }
+    public SizeD WorldToPixelRatio {
+      get { return new SizeD(SizeInPixels.Width / Size.Width, SizeInPixels.Height / Size.Height); }
+    }
+
+    private IGroup myGroup;
+    public IGroup Group {
+      get { return myGroup; }
+    }
+
+    private bool myUpdateEnabled;
+    public bool UpdateEnabled {
+      get { return myUpdateEnabled; }
+      set { myUpdateEnabled = value; }
+    }
+
+    public Chart(PointD lowerLeft, PointD upperRight) {
+      myUpdateEnabled = false;
+      zoomHistory = new List<Offset>();
+      myMode = ChartMode.Move;
+      SetPosition(lowerLeft, upperRight);
+      mySizeInPixels = new Size(100, 100);
+      myGroup = new Group(this);
+      Group.Update += new EventHandler(Group_Update);
+      myUpdateEnabled = true;
+    }
+    public Chart(double x1, double y1, double x2, double y2)
+      : this(new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+
+    public PointD TransformPixelToWorld(Point point) {
+      double x = LowerLeft.X + point.X * PixelToWorldRatio.Width;
+      double y = LowerLeft.Y + (SizeInPixels.Height - point.Y) * PixelToWorldRatio.Height;
+      return new PointD(x, y);
+    }
+    public SizeD TransformPixelToWorld(Size size) {
+      double width = size.Width * PixelToWorldRatio.Width;
+      double height = size.Height * PixelToWorldRatio.Height;
+      return new SizeD(width, height);
+    }
+    public Point TransformWorldToPixel(PointD point) {
+      int x = (int)((point.X - LowerLeft.X) * WorldToPixelRatio.Width);
+      int y = (int)((UpperRight.Y - point.Y) * WorldToPixelRatio.Height);
+      return new Point(x, y);
+    }
+    public Size TransformWorldToPixel(SizeD size) {
+      int width = (int)(size.Width * WorldToPixelRatio.Width);
+      int height = (int)(size.Height * WorldToPixelRatio.Height);
+      return new Size(width, height);
+    }
+
+    public virtual void SetPosition(PointD lowerLeft, PointD upperRight) {
+      if ((lowerLeft.X >= upperRight.X) || (lowerLeft.Y >= upperRight.Y))
+        throw new ArgumentException("Lower left point is greater or equal than upper right point");
+
+      originalLowerLeft = lowerLeft;
+      originalUpperRight = upperRight;
+      if (zoomHistory != null) zoomHistory.Clear();
+      myLowerLeft = lowerLeft;
+      myUpperRight = upperRight;
+      OnUpdate();
+    }
+    public void SetPosition(double x1, double y1, double x2, double y2) {
+      SetPosition(new PointD(x1, y1), new PointD(x2, y2));
+    }
+    public virtual void Move(Offset delta) {
+      myLowerLeft += delta;
+      myUpperRight += delta;
+      OnUpdate();
+    }
+    public void Move(double dx, double dy) {
+      Move(new Offset(dx, dy));
+    }
+
+    public virtual void ZoomIn(PointD lowerLeft, PointD upperRight) {
+      zoomHistory.Insert(0, LowerLeft - lowerLeft);
+      zoomHistory.Insert(0, UpperRight - upperRight);
+      myLowerLeft = lowerLeft;
+      myUpperRight = upperRight;
+      OnUpdate();
+    }
+    public void ZoomIn(double x1, double y1, double x2, double y2) {
+      ZoomIn(new PointD(x1, y1), new PointD(x2, y2));
+    }
+    public virtual void ZoomIn(Point lowerLeft, Point upperRight) {
+      ZoomIn(TransformPixelToWorld(lowerLeft), TransformPixelToWorld(upperRight));
+    }
+    public void ZoomIn(int x1, int y1, int x2, int y2) {
+      ZoomIn(new Point(x1, y1), new Point(x2, y2));
+    }
+    public virtual void ZoomOut() {
+      if (zoomHistory.Count > 0) {
+        Offset upperRight = zoomHistory[0];
+        zoomHistory.RemoveAt(0);
+        Offset lowerLeft = zoomHistory[0];
+        zoomHistory.RemoveAt(0);
+        myLowerLeft = LowerLeft + lowerLeft;
+        myUpperRight = UpperRight + upperRight;
+        OnUpdate();
+      } else {
+        myLowerLeft.X -= Size.Width / 4;
+        myLowerLeft.Y -= Size.Height / 4;
+        myUpperRight.X += Size.Width / 4;
+        myUpperRight.Y += Size.Height / 4;
+        OnUpdate();
+      }
+    }
+    public virtual void Unzoom() {
+      SetPosition(originalLowerLeft, originalUpperRight);
+    }
+
+    public virtual IPrimitive GetPrimitive(Point point) {
+      return Group.GetPrimitive(TransformPixelToWorld(point));
+    }
+    public IPrimitive GetPrimitive(int x, int y) {
+      return GetPrimitive(new Point(x, y));
+    }
+    public virtual IList<IPrimitive> GetAllPrimitives(Point point) {
+      return Group.GetAllPrimitives(TransformPixelToWorld(point));
+    }
+    public IList<IPrimitive> GetAllPrimitives(int x, int y) {
+      return GetAllPrimitives(new Point(x, y));
+    }
+
+    public virtual Cursor GetCursor(Point point) {
+      Cursor cursor = Group.GetCursor(TransformPixelToWorld(point));
+      if (cursor != null) return cursor;
+
+      if (Mode == ChartMode.Move) return Cursors.Hand;
+      if (Mode == ChartMode.Select) return Cursors.Arrow;
+      if (Mode == ChartMode.Zoom) return Cursors.Arrow;
+      return Cursors.Default;
+    }
+    public Cursor GetCursor(int x, int y) {
+      return GetCursor(new Point(x, y));
+    }
+    public virtual string GetToolTipText(Point point) {
+      return Group.GetToolTipText(TransformPixelToWorld(point));
+    }
+    public string GetToolTipText(int x, int y) {
+      return GetToolTipText(new Point(x, y));
+    }
+
+    public virtual void MouseClick(Point point, MouseButtons button) {
+      if (Mode == ChartMode.Select) {
+        if (button == MouseButtons.Left) {
+          IPrimitive clicked = GetPrimitive(point);
+          UpdateEnabled = false;
+          foreach (IPrimitive primitive in Group.SelectedPrimitives)
+            primitive.Selected = false;
+          UpdateEnabled = true;
+          if (clicked != null) {
+            PointD p = TransformPixelToWorld(point);
+            clicked.MouseClick(p, button);
+          } else OnUpdate();
+        }
+      } else if (Mode == ChartMode.Move) {
+        if (button == MouseButtons.Middle) {
+          PointD center = LowerLeft + new Offset(Size.Width / 2, Size.Height / 2);
+          Move(TransformPixelToWorld(point) - center);
+        }
+      }
+    }
+    public void MouseClick(int x, int y, MouseButtons button) {
+      MouseClick(new Point(x, y), button);
+    }
+    public virtual void MouseDoubleClick(Point point, MouseButtons button) {
+    }
+    public void MouseDoubleClick(int x, int y, MouseButtons button) {
+      MouseDoubleClick(new Point(x, y), button);
+    }
+    public virtual void MouseMove(Point start, Point end) {
+    }
+    public void MouseMove(int x1, int y1, int x2, int y2) {
+      MouseMove(new Point(x1, y1), new Point(x2, y2));
+    }
+    public virtual void MouseDrag(Point start, Point end, MouseButtons button) {
+      PointD p1 = TransformPixelToWorld(start);
+      PointD p2 = TransformPixelToWorld(end);
+      Offset offset = p2 - p1;
+      if (Mode == ChartMode.Move) {
+        Move(-1 * offset.DX, -1 * offset.DY);
+      } else if (Mode == ChartMode.Select) {
+        if (button == MouseButtons.Left) {
+          IList<IPrimitive> selected = Group.SelectedPrimitives;
+          UpdateEnabled = false;
+          foreach (IPrimitive primitive in selected)
+            primitive.MouseDrag(p1, offset, button);
+          UpdateEnabled = true;
+          OnUpdate();
+        }
+      }
+    }
+    public void MouseDrag(int x1, int y1, int x2, int y2, MouseButtons button) {
+      MouseDrag(new Point(x1, y1), new Point(x2, y2), button);
+    }
+
+    public virtual void Render(Graphics graphics, int width, int height) {
+      mySizeInPixels = new Size(width, height);
+      Group.PreDraw(graphics);
+      Group.Draw(graphics);
+      Group.PostDraw(graphics);
+    }
+
+    public event EventHandler Update;
+    public void EnforceUpdate() {
+      if (Update != null) {
+        Update(this, new EventArgs());
+      }
+    }
+    protected virtual void OnUpdate() {
+      if ((UpdateEnabled) && (Update != null)) {
+        Update(this, new EventArgs());
+      }
+    }
+    private void Group_Update(object sender, EventArgs e) {
+      OnUpdate();
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.Designer.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.Designer.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.Designer.cs	(revision 4773)
@@ -0,0 +1,205 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Drawing {
+  partial class ChartControl {
+    /// <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.components = new System.ComponentModel.Container();
+      this.pictureBox = new System.Windows.Forms.PictureBox();
+      this.pictureBoxContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+      this.moveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.zoomToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.selectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
+      this.oneLayerUpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.oneLayerDownToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.intoForegroundToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.intoBackgroundToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
+      this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      this.pictureBoxContextMenuStrip.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.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.pictureBox.BackColor = System.Drawing.Color.White;
+      this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.pictureBox.ContextMenuStrip = this.pictureBoxContextMenuStrip;
+      this.pictureBox.Location = new System.Drawing.Point(0, 0);
+      this.pictureBox.Name = "pictureBox";
+      this.pictureBox.Size = new System.Drawing.Size(266, 236);
+      this.pictureBox.TabIndex = 0;
+      this.pictureBox.TabStop = false;
+      this.pictureBox.VisibleChanged += new System.EventHandler(this.pictureBox_VisibleChanged);
+      this.pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
+      this.pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
+      this.pictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
+      this.pictureBox.SizeChanged += new System.EventHandler(this.pictureBox_SizeChanged);
+      // 
+      // pictureBoxContextMenuStrip
+      // 
+      this.pictureBoxContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.moveToolStripMenuItem,
+            this.zoomToolStripMenuItem,
+            this.selectToolStripMenuItem,
+            this.toolStripMenuItem1,
+            this.oneLayerUpToolStripMenuItem,
+            this.oneLayerDownToolStripMenuItem,
+            this.intoForegroundToolStripMenuItem,
+            this.intoBackgroundToolStripMenuItem,
+            this.toolStripMenuItem2,
+            this.propertiesToolStripMenuItem});
+      this.pictureBoxContextMenuStrip.Name = "pictureBoxContextMenuStrip";
+      this.pictureBoxContextMenuStrip.Size = new System.Drawing.Size(165, 192);
+      // 
+      // moveToolStripMenuItem
+      // 
+      this.moveToolStripMenuItem.Checked = true;
+      this.moveToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.moveToolStripMenuItem.Name = "moveToolStripMenuItem";
+      this.moveToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.moveToolStripMenuItem.Text = "&Move";
+      this.moveToolStripMenuItem.Click += new System.EventHandler(this.moveToolStripMenuItem_Click);
+      // 
+      // zoomToolStripMenuItem
+      // 
+      this.zoomToolStripMenuItem.Name = "zoomToolStripMenuItem";
+      this.zoomToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.zoomToolStripMenuItem.Text = "&Zoom";
+      this.zoomToolStripMenuItem.Click += new System.EventHandler(this.zoomToolStripMenuItem_Click);
+      // 
+      // selectToolStripMenuItem
+      // 
+      this.selectToolStripMenuItem.Name = "selectToolStripMenuItem";
+      this.selectToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.selectToolStripMenuItem.Text = "&Select";
+      this.selectToolStripMenuItem.Click += new System.EventHandler(this.selectToolStripMenuItem_Click);
+      // 
+      // toolStripMenuItem1
+      // 
+      this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+      this.toolStripMenuItem1.Size = new System.Drawing.Size(161, 6);
+      // 
+      // oneLayerUpToolStripMenuItem
+      // 
+      this.oneLayerUpToolStripMenuItem.Enabled = false;
+      this.oneLayerUpToolStripMenuItem.Name = "oneLayerUpToolStripMenuItem";
+      this.oneLayerUpToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.oneLayerUpToolStripMenuItem.Text = "One Layer &Up";
+      this.oneLayerUpToolStripMenuItem.Click += new System.EventHandler(this.oneLayerUpToolStripMenuItem_Click);
+      // 
+      // oneLayerDownToolStripMenuItem
+      // 
+      this.oneLayerDownToolStripMenuItem.Enabled = false;
+      this.oneLayerDownToolStripMenuItem.Name = "oneLayerDownToolStripMenuItem";
+      this.oneLayerDownToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.oneLayerDownToolStripMenuItem.Text = "OneLayer &Down";
+      this.oneLayerDownToolStripMenuItem.Click += new System.EventHandler(this.oneLayerDownToolStripMenuItem_Click);
+      // 
+      // intoForegroundToolStripMenuItem
+      // 
+      this.intoForegroundToolStripMenuItem.Enabled = false;
+      this.intoForegroundToolStripMenuItem.Name = "intoForegroundToolStripMenuItem";
+      this.intoForegroundToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.intoForegroundToolStripMenuItem.Text = "Into &Foreground";
+      this.intoForegroundToolStripMenuItem.Click += new System.EventHandler(this.intoForegroundToolStripMenuItem_Click);
+      // 
+      // intoBackgroundToolStripMenuItem
+      // 
+      this.intoBackgroundToolStripMenuItem.Enabled = false;
+      this.intoBackgroundToolStripMenuItem.Name = "intoBackgroundToolStripMenuItem";
+      this.intoBackgroundToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.intoBackgroundToolStripMenuItem.Text = "Into &Background";
+      this.intoBackgroundToolStripMenuItem.Click += new System.EventHandler(this.intoBackgroundToolStripMenuItem_Click);
+      // 
+      // toolStripMenuItem2
+      // 
+      this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+      this.toolStripMenuItem2.Size = new System.Drawing.Size(161, 6);
+      // 
+      // propertiesToolStripMenuItem
+      // 
+      this.propertiesToolStripMenuItem.Enabled = false;
+      this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem";
+      this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+      this.propertiesToolStripMenuItem.Text = "&Properties";
+      this.propertiesToolStripMenuItem.Click += new System.EventHandler(this.propertiesToolStripMenuItem_Click);
+      // 
+      // ChartControl
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.BackColor = System.Drawing.SystemColors.Control;
+      this.Controls.Add(this.pictureBox);
+      this.Name = "ChartControl";
+      this.Size = new System.Drawing.Size(266, 236);
+      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ChartControl_KeyDown);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.pictureBoxContextMenuStrip.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.PictureBox pictureBox;
+    protected System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.ContextMenuStrip pictureBoxContextMenuStrip;
+    protected System.Windows.Forms.ToolStripMenuItem moveToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem zoomToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem selectToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
+    protected System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem oneLayerUpToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem oneLayerDownToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem intoForegroundToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripMenuItem intoBackgroundToolStripMenuItem;
+    protected System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
+
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.cs	(revision 4773)
@@ -0,0 +1,224 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public partial class ChartControl : UserControl {
+    private Bitmap bitmap;
+    private bool renderingRequired;
+    private Point buttonDownPoint;
+    private Point mousePosition;
+    private int mouseClickCount;
+
+    private Chart myChart;
+    public Chart Chart {
+      get { return myChart; }
+      set {
+        if (myChart != null) myChart.Update -= new EventHandler(myChart_Update);
+        myChart = value;
+        if (myChart != null) {
+          myChart.Update += new EventHandler(myChart_Update);
+          SetMode(Chart.Mode);
+        }
+        GenerateImage();
+      }
+    }
+    private bool myScaleOnResize;
+    public bool ScaleOnResize {
+      get { return myScaleOnResize; }
+      set { myScaleOnResize = value; }
+    }
+
+    public ChartControl() {
+      InitializeComponent();
+      myScaleOnResize = true;
+      GenerateImage();
+    }
+
+    private void myChart_Update(object sender, EventArgs e) {
+      GenerateImage();
+    }
+    private void pictureBox_SizeChanged(object sender, EventArgs e) {
+      if (ScaleOnResize) {
+        if ((pictureBox.Width > 0) && (pictureBox.Height > 0) && (Chart != null)) {
+          PointD point = Chart.TransformPixelToWorld(new Point(pictureBox.Width, Chart.SizeInPixels.Height - pictureBox.Height));
+          Chart.SetPosition(Chart.LowerLeft, point);
+        }
+      }
+      GenerateImage();
+    }
+    private void pictureBox_VisibleChanged(object sender, EventArgs e) {
+      if (pictureBox.Visible && renderingRequired) {
+        GenerateImage();
+      }
+    }
+
+    private void pictureBox_MouseDown(object sender, MouseEventArgs e) {
+      buttonDownPoint = e.Location;
+      mouseClickCount = e.Clicks;
+    }
+    private void pictureBox_MouseUp(object sender, MouseEventArgs e) {
+      if (e.Button == MouseButtons.Left) {
+        if (Chart.Mode == ChartMode.Zoom) {
+          pictureBox.Refresh();
+          Point lowerLeft = new Point(Math.Min(e.X, buttonDownPoint.X),
+                                      Math.Max(e.Y, buttonDownPoint.Y));
+          Point upperRight = new Point(Math.Max(e.X, buttonDownPoint.X),
+                                       Math.Min(e.Y, buttonDownPoint.Y));
+          if ((lowerLeft.X != upperRight.X) && (lowerLeft.Y != upperRight.Y)) {
+            Chart.ZoomIn(lowerLeft, upperRight);
+          }
+        }
+      } else if (e.Button == MouseButtons.Right) {
+        propertiesToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
+        oneLayerUpToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
+        oneLayerDownToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
+        intoForegroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
+        intoBackgroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
+      } else if (e.Button == MouseButtons.Middle) {
+        if (Chart.Mode == ChartMode.Zoom) {
+          if (mouseClickCount == 1) Chart.ZoomOut();
+          else if (mouseClickCount == 2) Chart.Unzoom();
+        }
+      }
+      if (buttonDownPoint == e.Location) {
+        if (mouseClickCount == 1)
+          Chart.MouseClick(e.Location, e.Button);
+        else if (mouseClickCount == 2)
+          Chart.MouseDoubleClick(e.Location, e.Button);
+      }
+    }
+    private void pictureBox_MouseMove(object sender, MouseEventArgs e) {
+      toolTip.SetToolTip(pictureBox, Chart.GetToolTipText(e.Location));
+      Cursor cursor = Chart.GetCursor(e.Location);
+      if (cursor != null) pictureBox.Cursor = cursor;
+      else pictureBox.Cursor = Cursors.Default;
+
+      if (e.Button != MouseButtons.None) {
+        if ((Chart.Mode == ChartMode.Zoom) && (e.Button == MouseButtons.Left)) {
+          pictureBox.Refresh();
+          Graphics graphics = pictureBox.CreateGraphics();
+          Pen pen = new Pen(Color.Gray);
+          pen.DashStyle = DashStyle.Dash;
+          graphics.DrawRectangle(pen,
+                                 Math.Min(e.X, buttonDownPoint.X),
+                                 Math.Min(e.Y, buttonDownPoint.Y),
+                                 Math.Abs(e.X - buttonDownPoint.X),
+                                 Math.Abs(e.Y - buttonDownPoint.Y));
+          pen.Dispose();
+          graphics.Dispose();
+        }
+        Chart.MouseDrag(mousePosition, e.Location, e.Button);
+      } else {
+        Chart.MouseMove(mousePosition, e.Location);
+      }
+      mousePosition = e.Location;
+    }
+
+    private void ChartControl_KeyDown(object sender, KeyEventArgs e) {
+      if (Chart.Mode == ChartMode.Select) {
+        if (e.KeyCode == Keys.Delete) {
+          IList<IPrimitive> selected = Chart.Group.SelectedPrimitives;
+          Chart.UpdateEnabled = false;
+          foreach (IPrimitive primitive in selected)
+            Chart.Group.Remove(primitive);
+          Chart.UpdateEnabled = true;
+          Chart.EnforceUpdate();
+        }
+      }
+    }
+
+    private void moveToolStripMenuItem_Click(object sender, EventArgs e) {
+      SetMode(ChartMode.Move);
+    }
+    private void zoomToolStripMenuItem_Click(object sender, EventArgs e) {
+      SetMode(ChartMode.Zoom);
+    }
+    private void selectToolStripMenuItem_Click(object sender, EventArgs e) {
+      SetMode(ChartMode.Select);
+    }
+    private void oneLayerUpToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (Chart.Group.SelectedPrimitives.Count == 1) {
+        Chart.Group.SelectedPrimitives[0].OneLayerUp();
+      }
+    }
+    private void oneLayerDownToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (Chart.Group.SelectedPrimitives.Count == 1) {
+        Chart.Group.SelectedPrimitives[0].OneLayerDown();
+      }
+    }
+    private void intoForegroundToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (Chart.Group.SelectedPrimitives.Count == 1) {
+        Chart.Group.SelectedPrimitives[0].IntoForeground();
+      }
+    }
+    private void intoBackgroundToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (Chart.Group.SelectedPrimitives.Count == 1) {
+        Chart.Group.SelectedPrimitives[0].IntoBackground();
+      }
+    }
+    private void propertiesToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (Chart.Group.SelectedPrimitives.Count == 1) {
+        PropertiesDialog dialog = new PropertiesDialog(Chart.Group.SelectedPrimitives[0]);
+        dialog.ShowDialog(this);
+        dialog.Dispose();
+      }
+    }
+
+    private void GenerateImage() {
+      if (!Visible) {
+        renderingRequired = true;
+      } else {
+        if ((pictureBox.Width == 0) || (pictureBox.Height == 0)) {
+          bitmap = null;
+        } else {
+          bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+          if (Chart != null) {
+            Graphics graphics = Graphics.FromImage(bitmap);
+            graphics.SetClip(new System.Drawing.Rectangle(0, 0, pictureBox.Width, pictureBox.Height));
+            Chart.Render(graphics, pictureBox.Width, pictureBox.Height);
+            graphics.Dispose();
+          }
+        }
+        pictureBox.Image = bitmap;
+        renderingRequired = false;
+      }
+    }
+
+    private void SetMode(ChartMode mode) {
+      moveToolStripMenuItem.Checked = false;
+      zoomToolStripMenuItem.Checked = false;
+      selectToolStripMenuItem.Checked = false;
+      if (mode == ChartMode.Move) moveToolStripMenuItem.Checked = true;
+      else if (mode == ChartMode.Zoom) zoomToolStripMenuItem.Checked = true;
+      else if (mode == ChartMode.Select) selectToolStripMenuItem.Checked = true;
+      Chart.Mode = mode;
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.resx
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.resx	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartControl.resx	(revision 4773)
@@ -0,0 +1,126 @@
+<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="pictureBoxContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>102, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartMode.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartMode.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ChartMode.cs	(revision 4773)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HeuristicLab.Drawing {
+  public enum ChartMode {
+    Move,
+    Zoom,
+    Select
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ClassDiagram.cd
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ClassDiagram.cd	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/ClassDiagram.cd	(revision 4773)
@@ -0,0 +1,154 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="FullSignature">
+  <Font Name="Tahoma" Size="8.25" />
+  <Class Name="HeuristicLab.Charting.Chart" Collapsed="true" BaseTypeListCollapsed="true">
+    <Position X="36.75" Y="0.5" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>Chart.cs</FileName>
+      <HashCode>IAQAhGIABIACwAKAFAAAAAAiEAMBAgCEABgYARGAAAA=</HashCode>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" Collapsed="true" />
+  </Class>
+  <Class Name="HeuristicLab.Charting.ChartControl" Collapsed="true">
+    <Position X="38.5" Y="0.5" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>ChartControl.cs</FileName>
+      <HashCode>AgLgCIQBECBAogCCDCCACgBuEKAAAgAEASAAAACAAiA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.Ellipse">
+    <Position X="6.5" Y="14.5" Width="5.25" />
+    <TypeIdentifier>
+      <FileName>Primitives\Ellipse.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.FixedSizeCircle">
+    <Position X="25" Y="13.75" Width="5" />
+    <TypeIdentifier>
+      <FileName>Primitives\FixedSizeCircle.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.FixedSizePrimitiveBase">
+    <Position X="27.75" Y="9.5" Width="5.25" />
+    <TypeIdentifier>
+      <FileName>Primitives\FixedSizePrimitiveBase.cs</FileName>
+      <HashCode>AAAAABAAAIAAgAAAAAAAAAAAAIAAAgAAAAAAAAAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.FixedSizeRectangle">
+    <Position X="30.75" Y="13.75" Width="5" />
+    <TypeIdentifier>
+      <FileName>Primitives\FixedSizeRectangle.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.Group">
+    <Position X="2" Y="9.5" Width="3.75" />
+    <TypeIdentifier>
+      <FileName>Primitives\Group.cs</FileName>
+      <HashCode>AAIAAAAAAIAABgAAAAAABBACAAIACEAAgAIQAABWABo=</HashCode>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" />
+  </Class>
+  <Class Name="HeuristicLab.Charting.Line">
+    <Position X="19.25" Y="14.75" Width="4.25" />
+    <TypeIdentifier>
+      <FileName>Primitives\Line.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.LinearPrimitiveBase">
+    <Position X="18.5" Y="9.5" Width="5.75" />
+    <TypeIdentifier>
+      <FileName>Primitives\LinearPrimitiveBase.cs</FileName>
+      <HashCode>AAIAEAAAAKAEggIAAAAAAABAAACAAgAAAAAQAAAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.PrimitiveBase">
+    <Position X="16.5" Y="0.5" Width="5" />
+    <TypeIdentifier>
+      <FileName>Primitives\PrimitiveBase.cs</FileName>
+      <HashCode>AAQADEIAAIAiiiJAAAAAABAAEAIASgAAAAoYAAGCARI=</HashCode>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" />
+  </Class>
+  <Class Name="HeuristicLab.Charting.Rectangle">
+    <Position X="12.5" Y="14.5" Width="5.25" />
+    <TypeIdentifier>
+      <FileName>Primitives\Rectangle.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.RectangularPrimitiveBase">
+    <Position X="9" Y="9.5" Width="6.25" />
+    <TypeIdentifier>
+      <FileName>Primitives\RectangularPrimitiveBase.cs</FileName>
+      <HashCode>AAAAECAABIAAggKAAAAAAAAAAAAAAgAAAAAQAQAAABA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.SelectionRectangle">
+    <Position X="31.25" Y="16.25" Width="4" />
+    <TypeIdentifier>
+      <FileName>Primitives\SelectionRectangle.cs</FileName>
+      <HashCode>AAAAAAAAAAAAAAEAAIAAAAAAAAAAAAAAAAAQAAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="HeuristicLab.Charting.PropertiesDialog" Collapsed="true">
+    <Position X="36.75" Y="1.5" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>PropertiesDialog.cs</FileName>
+      <HashCode>AAAAAAAAACAAAAAAAACAAAACGAAAEAAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Struct Name="HeuristicLab.Charting.Offset" Collapsed="true">
+    <Position X="36.75" Y="2.75" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>Structs\Offset.cs</FileName>
+      <HashCode>AAJABAAAAAAAQAAEwAMCAABAAAAYAIgAAAAAAAAAAiA=</HashCode>
+    </TypeIdentifier>
+  </Struct>
+  <Struct Name="HeuristicLab.Charting.PointD" Collapsed="true">
+    <Position X="38.5" Y="2.75" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>Structs\PointD.cs</FileName>
+      <HashCode>AAJABAAAAAAAAgAEwBMCAAAAAAAAAIAAAAAAAAAAYiA=</HashCode>
+    </TypeIdentifier>
+  </Struct>
+  <Struct Name="HeuristicLab.Charting.SizeD" Collapsed="true">
+    <Position X="36.75" Y="3.75" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>Structs\SizeD.cs</FileName>
+      <HashCode>AAJABAAABAAAAkAEwAMCAEAAAAAAAIAAAgAAAAAAAiA=</HashCode>
+    </TypeIdentifier>
+  </Struct>
+  <Interface Name="HeuristicLab.Charting.IChart" Collapsed="true">
+    <Position X="36.75" Y="5" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>Interfaces\IChart.cs</FileName>
+      <HashCode>IAQABEIAAIAAgAKAEAAAAAAiEAIBAgCEABAYAQCAAAA=</HashCode>
+    </TypeIdentifier>
+  </Interface>
+  <Interface Name="HeuristicLab.Charting.IGroup">
+    <Position X="1.25" Y="24.5" Width="3.75" />
+    <TypeIdentifier>
+      <FileName>Interfaces\IGroup.cs</FileName>
+      <HashCode>AAIAAAAAAAAABAAAAAAABBACAAAACEAAAAIAAABWAAA=</HashCode>
+    </TypeIdentifier>
+  </Interface>
+  <Interface Name="HeuristicLab.Charting.IPrimitive">
+    <Position X="0.5" Y="17.5" Width="5" />
+    <TypeIdentifier>
+      <FileName>Interfaces\IPrimitive.cs</FileName>
+      <HashCode>AAQABEIAAIAgiiIAAAAAABAAEAIACAAAAAIYAACCABI=</HashCode>
+    </TypeIdentifier>
+  </Interface>
+  <Enum Name="HeuristicLab.Charting.ChartMode" Collapsed="true">
+    <Position X="36.75" Y="6" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>ChartMode.cs</FileName>
+      <HashCode>AAAAAAAAAIAAAAAAEAAAAAAAAAAAAAAAAAAAQAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Enum>
+</ClassDiagram>
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj	(revision 4773)
@@ -0,0 +1,204 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{B462D3CC-8866-42F0-9832-AD0967613B72}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Drawing</RootNamespace>
+    <AssemblyName>HeuristicLab.Drawing-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <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>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </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>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <DocumentationFile>bin\Release\HeuristicLab.Drawing-3.3.XML</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>bin\Release\HeuristicLab.Drawing-3.3.XML</DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>bin\Release\HeuristicLab.Drawing-3.3.XML</DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>C:\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Chart.cs" />
+    <Compile Include="ChartControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ChartControl.designer.cs">
+      <DependentUpon>ChartControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ChartMode.cs" />
+    <Compile Include="AxisType.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Interfaces\IGroup.cs" />
+    <Compile Include="Interfaces\IChart.cs" />
+    <Compile Include="Interfaces\IPrimitive.cs" />
+    <Compile Include="Primitives\Axis.cs" />
+    <Compile Include="Primitives\AxisPrimitiveBase.cs" />
+    <Compile Include="Primitives\LinearPrimitiveBase.cs" />
+    <Compile Include="Primitives\RectangularPrimitiveBase.cs" />
+    <Compile Include="Primitives\Ellipse.cs" />
+    <Compile Include="Primitives\FixedSizeCircle.cs" />
+    <Compile Include="Primitives\FixedSizePrimitiveBase.cs" />
+    <Compile Include="Primitives\FixedSizeRectangle.cs" />
+    <Compile Include="Primitives\Group.cs" />
+    <Compile Include="Primitives\Line.cs" />
+    <Compile Include="Primitives\PrimitiveBase.cs" />
+    <Compile Include="Primitives\Rectangle.cs" />
+    <Compile Include="Primitives\SelectionRectangle.cs" />
+    <Compile Include="PropertiesDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="PropertiesDialog.designer.cs">
+      <DependentUpon>PropertiesDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Structs\Offset.cs" />
+    <Compile Include="Structs\PointD.cs" />
+    <Compile Include="Structs\SizeD.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="ChartControl.resx">
+      <DependentUpon>ChartControl.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="PropertiesDialog.resx">
+      <DependentUpon>PropertiesDialog.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="ClassDiagram.cd" />
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- 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>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>set ProjectName=$(ProjectName)
+set Source=$(TargetPath)
+set Configuration=$(ConfigurationName)
+set Platform=$(PlatformName)
+set SolutionDir=$(SolutionDir)
+
+if exist "$(SolutionDir)CustomPostBuild.cmd" call "$(SolutionDir)CustomPostBuild.cmd"</PostBuildEvent>
+  </PropertyGroup>
+</Project>
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj.user
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj.user	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/HeuristicLab.Drawing-3.3.csproj.user	(revision 4773)
@@ -0,0 +1,14 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <PublishUrlHistory />
+    <InstallUrlHistory />
+    <SupportUrlHistory />
+    <UpdateUrlHistory />
+    <BootstrapperUrlHistory />
+    <ErrorReportUrlHistory />
+    <FallbackCulture>en-US</FallbackCulture>
+    <VerifyUploadedFiles>false</VerifyUploadedFiles>
+    <ProjectView>ProjectFiles</ProjectView>
+  </PropertyGroup>
+</Project>
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IChart.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IChart.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IChart.cs	(revision 4773)
@@ -0,0 +1,81 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public interface IChart {
+    ChartMode Mode { get; set; }
+    PointD LowerLeft { get; }
+    PointD UpperRight { get; }
+    SizeD Size { get; }
+    Size SizeInPixels { get; }
+    SizeD PixelToWorldRatio { get; }
+    SizeD WorldToPixelRatio { get; }
+    IGroup Group { get; }
+    bool UpdateEnabled { get; }
+
+    PointD TransformPixelToWorld(Point point);
+    SizeD TransformPixelToWorld(Size size);
+    Point TransformWorldToPixel(PointD point);
+    Size TransformWorldToPixel(SizeD size);
+
+    void SetPosition(PointD lowerLeft, PointD upperRight);
+    void SetPosition(double x1, double y1, double x2, double y2);
+    void Move(Offset delta);
+    void Move(double dx, double dy);
+
+    void ZoomIn(PointD lowerLeft, PointD upperRight);
+    void ZoomIn(double x1, double y1, double x2, double y2);
+    void ZoomIn(Point lowerLeft, Point upperRight);
+    void ZoomIn(int x1, int y1, int x2, int y2);
+    void ZoomOut();
+    void Unzoom();
+
+    IPrimitive GetPrimitive(Point point);
+    IPrimitive GetPrimitive(int x, int y);
+    IList<IPrimitive> GetAllPrimitives(Point point);
+    IList<IPrimitive> GetAllPrimitives(int x, int y);
+
+    Cursor GetCursor(Point point);
+    Cursor GetCursor(int x, int y);
+    string GetToolTipText(Point point);
+    string GetToolTipText(int x, int y);
+
+    void MouseClick(Point point, MouseButtons button);
+    void MouseClick(int x, int y, MouseButtons button);
+    void MouseDoubleClick(Point point, MouseButtons button);
+    void MouseDoubleClick(int x, int y, MouseButtons button);
+    void MouseMove(Point start, Point end);
+    void MouseMove(int x1, int y1, int x2, int y2);
+    void MouseDrag(Point start, Point end, MouseButtons button);
+    void MouseDrag(int x1, int y1, int x2, int y2, MouseButtons button);
+
+    void Render(Graphics graphics, int width, int height);
+
+    event EventHandler Update;
+    void EnforceUpdate();
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IGroup.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IGroup.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IGroup.cs	(revision 4773)
@@ -0,0 +1,48 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+
+namespace HeuristicLab.Drawing {
+  public interface IGroup : IPrimitive {
+    ReadOnlyCollection<IPrimitive> Primitives { get; }
+    ReadOnlyCollection<IPrimitive> SelectedPrimitives { get; }
+
+    void Add(IPrimitive primitive);
+    void AddRange(IEnumerable<IPrimitive> primitives);
+    bool Contains(IPrimitive primitive);
+    bool Remove(IPrimitive primitive);
+    void Clear();
+
+    IPrimitive GetPrimitive(PointD point);
+    IPrimitive GetPrimitive(double x, double y);
+    IList<IPrimitive> GetAllPrimitives(PointD point);
+    IList<IPrimitive> GetAllPrimitives(double x, double y);
+
+    void OneLayerUp(IPrimitive primitive);
+    void OneLayerDown(IPrimitive primitive);
+    void IntoForeground(IPrimitive primitive);
+    void IntoBackground(IPrimitive primitive);
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IPrimitive.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IPrimitive.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Interfaces/IPrimitive.cs	(revision 4773)
@@ -0,0 +1,71 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public interface IPrimitive {
+    IChart Chart { get; }
+    IGroup Group { get; set; }
+    Pen Pen { get; set; }
+    Brush Brush { get; set; }
+    bool UpdateEnabled { get; }
+    bool Selected { get; set; }
+    string ToolTipText { get; set; }
+    object Tag { get; set; }
+
+    void Move(Offset delta);
+    void Move(double dx, double dy);
+
+    bool ContainsPoint(PointD point);
+    bool ContainsPoint(double x, double y);
+
+    Cursor GetCursor(PointD point);
+    Cursor GetCursor(double x, double y);
+    string GetToolTipText(PointD point);
+    string GetToolTipText(double x, double y);
+
+    void OneLayerUp();
+    void OneLayerDown();
+    void IntoForeground();
+    void IntoBackground();
+
+    void MouseClick(PointD point, MouseButtons button);
+    void MouseClick(double x, double y, MouseButtons button);
+    void MouseDoubleClick(PointD point, MouseButtons button);
+    void MouseDoubleClick(double x, double y, MouseButtons button);
+    void MouseMove(PointD point, Offset offset);
+    void MouseMove(double x, double y, double dx, double dy);
+    void MouseDrag(PointD point, Offset offset, MouseButtons button);
+    void MouseDrag(double x, double y, double dx, double dy, MouseButtons button);
+
+    void PreDraw(Graphics graphics);
+    void Draw(Graphics graphics);
+    void PostDraw(Graphics graphics);
+
+    event EventHandler Update;
+    void EnforceUpdate();
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Plugin.cs.frame
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Plugin.cs.frame	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Plugin.cs.frame	(revision 4773)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Drawing {
+  [Plugin("HeuristicLab.Drawing", "3.3.1.$WCREV$")]
+  [PluginFile("HeuristicLab.Drawing-3.3.dll", PluginFileType.Assembly)]
+  public class HeuristicLabDrawingPlugin : PluginBase { }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Axis.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Axis.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Axis.cs	(revision 4773)
@@ -0,0 +1,132 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public class Axis : AxisPrimitiveBase {
+    public Axis(IChart chart, PointD point, AxisType axisType)
+      : base(chart, point, axisType) {
+    }
+    public Axis(IChart chart, double x, double y, AxisType axisType)
+      : this(chart, new PointD(x, y), axisType) {
+    }
+    public Axis(IChart chart, PointD point, AxisType axisType, Pen pen, Brush brush)
+      : base(chart, point, axisType, pen, brush) {
+    }
+    public Axis(IChart chart, double x, double y, AxisType axisType, Pen pen, Brush brush)
+      : this(chart, new PointD(x, y), axisType, pen, brush) {
+    }
+
+    public override void Draw(Graphics graphics) {
+      int pixelsPerInterval = 100;
+      Font axisValuesFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular, GraphicsUnit.Pixel);
+      Font axisLabelsFont = new Font(FontFamily.GenericSansSerif, 14, FontStyle.Regular, GraphicsUnit.Pixel);
+
+      if ((AxisType & AxisType.Horizontal) == AxisType.Horizontal) {
+        int intervals = Chart.SizeInPixels.Width / pixelsPerInterval;
+
+        if (intervals > 0) {
+          double step = (Chart.UpperRight.X - Chart.LowerLeft.X) / intervals;
+          step = Math.Pow(10, Math.Floor(Math.Log10(step)));
+          if ((Chart.UpperRight.X - Chart.LowerLeft.X) / (step * 5) > intervals)
+            step = step * 5;
+          else if ((Chart.UpperRight.X - Chart.LowerLeft.X) / (step * 2) > intervals)
+            step = step * 2;
+
+          double x = Math.Floor(Chart.LowerLeft.X / step) * step;
+          PointD current = new PointD(x, Point.Y);
+          while (current.X <= Chart.UpperRight.X) {
+            Point p = Chart.TransformWorldToPixel(current);
+            if (ShowGrid)
+              graphics.DrawLine(Pens.LightGray, p.X, 0, p.X, Chart.SizeInPixels.Height);
+            graphics.DrawLine(Pen, p.X, p.Y - 3, p.X, p.Y + 3);
+            graphics.DrawString(current.X.ToString(),
+                                axisValuesFont,
+                                Brush,
+                                p.X,
+                                p.Y + 5,
+                                StringFormat.GenericDefault);
+            current.X = current.X + step;
+          }
+          if ((HorizontalLabel != null) && (HorizontalLabel != "")) {
+            Point p = Chart.TransformWorldToPixel(Point);
+            graphics.DrawString(HorizontalLabel,
+                                axisLabelsFont,
+                                Brush,
+                                Chart.SizeInPixels.Width - 20,
+                                p.Y + 20,
+                                new StringFormat(StringFormatFlags.DirectionRightToLeft));
+          }
+        }
+      }
+      if ((AxisType & AxisType.Vertical) == AxisType.Vertical) {
+        int intervals = Chart.SizeInPixels.Height / pixelsPerInterval;
+
+        if (intervals > 0) {
+          double step = (Chart.UpperRight.Y - Chart.LowerLeft.Y) / intervals;
+          step = Math.Pow(10, Math.Floor(Math.Log10(step)));
+          if ((Chart.UpperRight.Y - Chart.LowerLeft.Y) / (step * 5) > intervals)
+            step = step * 5;
+          else if ((Chart.UpperRight.Y - Chart.LowerLeft.Y) / (step * 2) > intervals)
+            step = step * 2;
+
+          double y = Math.Floor(Chart.LowerLeft.Y / step) * step;
+          PointD current = new PointD(Point.X, y);
+          while (current.Y <= Chart.UpperRight.Y) {
+            Point p = Chart.TransformWorldToPixel(current);
+            if (ShowGrid)
+              graphics.DrawLine(Pens.LightGray, 0, p.Y, Chart.SizeInPixels.Width, p.Y);
+            graphics.DrawLine(Pen, p.X - 3, p.Y, p.X + 3, p.Y);
+            graphics.DrawString(current.Y.ToString(),
+                                axisValuesFont,
+                                Brush,
+                                p.X + 5,
+                                p.Y,
+                                StringFormat.GenericDefault);
+            current.Y = current.Y + step;
+          }
+          if ((VerticalLabel != null) && (VerticalLabel != "")) {
+            Point p = Chart.TransformWorldToPixel(Point);
+            graphics.DrawString(VerticalLabel,
+                                axisLabelsFont,
+                                Brush,
+                                p.X - 20,
+                                20,
+                                new StringFormat(StringFormatFlags.DirectionRightToLeft | StringFormatFlags.DirectionVertical));
+          }
+        }
+      }
+      if ((AxisType & AxisType.Horizontal) == AxisType.Horizontal) {
+        Point p = Chart.TransformWorldToPixel(Point);
+        graphics.DrawLine(Pen, 0, p.Y, Chart.SizeInPixels.Width, p.Y);
+      }
+      if ((AxisType & AxisType.Vertical) == AxisType.Vertical) {
+        Point p = Chart.TransformWorldToPixel(Point);
+        graphics.DrawLine(Pen, p.X, 0, p.X, Chart.SizeInPixels.Height);
+      }
+      base.Draw(graphics);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/AxisPrimitiveBase.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/AxisPrimitiveBase.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/AxisPrimitiveBase.cs	(revision 4773)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public abstract class AxisPrimitiveBase : PrimitiveBase {
+    private AxisType myAxisType;
+    public AxisType AxisType {
+      get { return myAxisType; }
+    }
+    private PointD myPoint;
+    public virtual PointD Point {
+      get { return myPoint; }
+    }
+    private bool myShowGrid;
+    public bool ShowGrid {
+      get { return myShowGrid; }
+      set {
+        if (value != myShowGrid) {
+          myShowGrid = value;
+          OnUpdate();
+        }
+      }
+    }
+    private string myHorizontalLabel;
+    public string HorizontalLabel {
+      get { return myHorizontalLabel; }
+      set {
+        if (value != myHorizontalLabel) {
+          myHorizontalLabel = value;
+          OnUpdate();
+        }
+      }
+    }
+    private string myVerticalLabel;
+    public string VerticalLabel {
+      get { return myVerticalLabel; }
+      set {
+        if (value != myVerticalLabel) {
+          myVerticalLabel = value;
+          OnUpdate();
+        }
+      }
+    }
+
+    protected AxisPrimitiveBase(IChart chart, PointD point, AxisType axisType)
+      : base(chart) {
+      Brush = Brushes.Black;
+      myPoint = point;
+      myAxisType = axisType;
+      myShowGrid = true;
+    }
+    protected AxisPrimitiveBase(IChart chart, double x, double y, AxisType axisType)
+      : this(chart, new PointD(x, y), axisType) {
+    }
+    protected AxisPrimitiveBase(IChart chart, PointD point, AxisType axisType, Pen pen, Brush brush)
+      : base(chart, pen, brush) {
+      myPoint = point;
+      myAxisType = axisType;
+      myShowGrid = true;
+    }
+    protected AxisPrimitiveBase(IChart chart, double x, double y, AxisType axisType, Pen pen, Brush brush)
+      : this(chart, new PointD(x, y), axisType, pen, brush) {
+    }
+
+    public virtual void SetPosition(PointD point) {
+      myPoint = point;
+      OnUpdate();
+    }
+    public void SetPosition(double x, double y) {
+      SetPosition(new PointD(x, y));
+    }
+    public override void Move(Offset delta) {
+      SetPosition(Point + delta);
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      SizeD size = Chart.TransformPixelToWorld(new Size(5, 5));
+      bool result = false;
+      if ((AxisType & AxisType.Horizontal) == AxisType.Horizontal)
+        result = result || (point.Y >= Point.Y - (size.Height / 2)) && (point.Y <= Point.Y + (size.Height / 2));
+      if ((AxisType & AxisType.Vertical) == AxisType.Vertical)
+        result = result || (point.X >= Point.X - (size.Height / 2)) && (point.X <= Point.X + (size.Height / 2));
+      return result;
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Ellipse.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Ellipse.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Ellipse.cs	(revision 4773)
@@ -0,0 +1,79 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public class Ellipse : RectangularPrimitiveBase {
+    public Ellipse(IChart chart, PointD lowerLeft, PointD upperRight)
+      : base(chart, lowerLeft, upperRight) {
+    }
+    public Ellipse(IChart chart, double x1, double y1, double x2, double y2)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+    public Ellipse(IChart chart, PointD lowerLeft, PointD upperRight, Pen pen, Brush brush)
+      : base(chart, lowerLeft, upperRight, pen, brush) {
+    }
+    public Ellipse(IChart chart, double x1, double y1, double x2, double y2, Pen pen, Brush brush)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen, brush) {
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      if (base.ContainsPoint(point)) return true;
+
+      PointD midpoint;
+      PointD focus1;
+      PointD focus2;
+      Offset focus1_point;
+      Offset focus2_point;
+
+      double a = Size.Width / 2;   // half length of horizontal axis
+      double b = Size.Height / 2;  // half length of vertical axis
+      midpoint = LowerLeft + new Offset(a, b);
+
+      if (a >= b) {
+        double e = Math.Sqrt(a * a - b * b);  // linear eccentricity
+        focus1 = new PointD(midpoint.X - e, midpoint.Y);
+        focus2 = new PointD(midpoint.X + e, midpoint.Y);
+      } else {
+        double e = Math.Sqrt(b * b - a * a);  // linear eccentricity
+        focus1 = new PointD(midpoint.X, midpoint.Y - e);
+        focus2 = new PointD(midpoint.X, midpoint.Y + e);
+      }
+      focus1_point = focus1 - point;
+      focus2_point = focus2 - point;
+
+      return focus1_point.Length + focus2_point.Length <= 2 * Math.Max(a, b);
+    }
+
+    public override void Draw(Graphics graphics) {
+      Point p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height));
+      Size s = Chart.TransformWorldToPixel(Size);
+      if (Brush != null)
+        graphics.FillEllipse(Brush, p.X, p.Y, s.Width, s.Height);
+      graphics.DrawEllipse(Pen, p.X, p.Y, s.Width, s.Height);
+      base.Draw(graphics);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeCircle.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeCircle.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeCircle.cs	(revision 4773)
@@ -0,0 +1,66 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public class FixedSizeCircle : FixedSizePrimitiveBase {
+    public FixedSizeCircle(IChart chart, PointD point, int diameter)
+      : base(chart, point, new Size(diameter, diameter)) {
+    }
+    public FixedSizeCircle(IChart chart, double x, double y, int diameter)
+      : this(chart, new PointD(x, y), diameter) {
+    }
+    public FixedSizeCircle(IChart chart, PointD point, int diameter, Pen pen, Brush brush)
+      : base(chart, point, new Size(diameter, diameter), pen, brush) {
+    }
+    public FixedSizeCircle(IChart chart, double x, double y, int diameter, Pen pen, Brush brush)
+      : this(chart, new PointD(x, y), diameter, pen, brush) {
+    }
+
+    public override void Draw(Graphics graphics) {
+      Point p = Chart.TransformWorldToPixel(Point);
+
+      graphics.FillEllipse(Brush,
+                           p.X - (Size.Width / 2),
+                           p.Y - (Size.Height / 2),
+                           Size.Width,
+                           Size.Height);
+      graphics.DrawEllipse(Pen,
+                           p.X - (Size.Width / 2),
+                           p.Y - (Size.Height / 2),
+                           Size.Width,
+                           Size.Height);
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      PointD center = Chart.TransformWorldToPixel(this.Point);
+      PointD x = Chart.TransformWorldToPixel(point);
+      double xDistance = x.X - center.X;
+      double yDistance = x.Y - center.Y;
+
+      return Size.Height*Size.Height/4.0 >= (xDistance * xDistance + yDistance * yDistance);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizePrimitiveBase.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizePrimitiveBase.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizePrimitiveBase.cs	(revision 4773)
@@ -0,0 +1,72 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public abstract class FixedSizePrimitiveBase : PrimitiveBase {
+    private PointD myPoint;
+    public virtual PointD Point {
+      get { return myPoint; }
+    }
+    private Size mySize;
+    public virtual Size Size {
+      get { return mySize; }
+    }
+
+    protected FixedSizePrimitiveBase(IChart chart, PointD point, Size size)
+      : base(chart) {
+      myPoint = point;
+      mySize = size;
+    }
+    protected FixedSizePrimitiveBase(IChart chart, double x, double y, Size size)
+      : this(chart, new PointD(x, y), size) {
+    }
+    protected FixedSizePrimitiveBase(IChart chart, PointD point, Size size, Pen pen, Brush brush)
+      : base(chart, pen, brush) {
+      myPoint = point;
+      mySize = size;
+    }
+    protected FixedSizePrimitiveBase(IChart chart, double x, double y, Size size, Pen pen, Brush brush)
+      : this(chart, new PointD(x, y), size, pen, brush) {
+    }
+
+    public virtual void SetPosition(PointD point) {
+      myPoint = point;
+      OnUpdate();
+    }
+    public void SetPosition(double x, double y) {
+      SetPosition(new PointD(x, y));
+    }
+    public override void Move(Offset delta) {
+      SetPosition(Point + delta);
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      SizeD size = Chart.TransformPixelToWorld(Size);
+      return (point.X >= Point.X - (size.Width / 2)) && (point.X <= Point.X + (size.Width / 2)) &&
+             (point.Y >= Point.Y - (size.Height / 2)) && (point.Y <= Point.Y + (size.Height / 2));
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeRectangle.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeRectangle.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/FixedSizeRectangle.cs	(revision 4773)
@@ -0,0 +1,57 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public class FixedSizeRectangle : FixedSizePrimitiveBase {
+    public FixedSizeRectangle(IChart chart, PointD point, Size size)
+      : base(chart, point, size) {
+    }
+    public FixedSizeRectangle(IChart chart, double x, double y, Size size)
+      : this(chart, new PointD(x, y), size) {
+    }
+    public FixedSizeRectangle(IChart chart, PointD point, Size size, Pen pen, Brush brush)
+      : base(chart, point, size, pen, brush) {
+    }
+    public FixedSizeRectangle(IChart chart, double x, double y, Size size, Pen pen, Brush brush)
+      : this(chart, new PointD(x, y), size, pen, brush) {
+    }
+
+    public override void Draw(Graphics graphics) {
+      Point p = Chart.TransformWorldToPixel(Point);
+
+      graphics.FillRectangle(Brush,
+                             p.X - (Size.Width / 2),
+                             p.Y - (Size.Height / 2),
+                             Size.Width,
+                             Size.Height);
+      graphics.DrawRectangle(Pen,
+                             p.X - (Size.Width / 2),
+                             p.Y - (Size.Height / 2),
+                             Size.Width,
+                             Size.Height);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Group.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Group.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Group.cs	(revision 4773)
@@ -0,0 +1,204 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public class Group : PrimitiveBase, IGroup {
+    private IList<IPrimitive> myPrimitives;
+    public virtual ReadOnlyCollection<IPrimitive> Primitives {
+      get { return new ReadOnlyCollection<IPrimitive>(myPrimitives); }
+    }
+    public virtual ReadOnlyCollection<IPrimitive> SelectedPrimitives {
+      get {
+        List<IPrimitive> selected = new List<IPrimitive>();
+        foreach (IPrimitive primitive in myPrimitives) {
+          if (primitive.Selected) selected.Add(primitive);
+        }
+        return new ReadOnlyCollection<IPrimitive>(selected);
+      }
+    }
+    public override bool Selected {
+      get { return base.Selected; }
+      set {
+        bool updateEnabled = UpdateEnabled;
+        UpdateEnabled = false;
+        foreach (IPrimitive primitive in myPrimitives)
+          primitive.Selected = value;
+        UpdateEnabled = updateEnabled;
+        base.Selected = value;
+      }
+    }
+
+    public Group(IChart chart)
+      : base(chart) {
+      myPrimitives = new List<IPrimitive>();
+    }
+
+    public virtual void Add(IPrimitive primitive) {
+      if (Contains(primitive))
+        throw new ArgumentException("Primitive already added");
+
+      myPrimitives.Insert(0, primitive);
+      primitive.Group = this;
+      primitive.Update += new EventHandler(primitive_Update);
+      OnUpdate();
+    }
+    public virtual void AddRange(IEnumerable<IPrimitive> primitives) {
+      foreach (IPrimitive primitive in primitives) {
+        if (Contains(primitive))
+          throw new ArgumentException("Primitive already added");
+
+        myPrimitives.Insert(0, primitive);
+        primitive.Group = this;
+        primitive.Update += new EventHandler(primitive_Update);
+      }
+      OnUpdate();
+    }
+    public virtual bool Contains(IPrimitive primitive) {
+      return myPrimitives.Contains(primitive);
+    }
+    public virtual bool Remove(IPrimitive primitive) {
+      if (myPrimitives.Remove(primitive)) {
+        primitive.Group = null;
+        primitive.Update -= new EventHandler(primitive_Update);
+        OnUpdate();
+        return true;
+      } else {
+        return false;
+      }
+    }
+    public virtual void Clear() {
+      foreach (IPrimitive primitive in myPrimitives) {
+        primitive.Group = null;
+        primitive.Update -= new EventHandler(primitive_Update);
+      }
+      myPrimitives.Clear();
+      OnUpdate();
+    }
+
+    public virtual IPrimitive GetPrimitive(PointD point) {
+      int i = 0;
+      while ((i < myPrimitives.Count) && (!myPrimitives[i].ContainsPoint(point)))
+        i++;
+      if (i == myPrimitives.Count) return null;
+      else return myPrimitives[i];
+    }
+    public IPrimitive GetPrimitive(double x, double y) {
+      return GetPrimitive(new PointD(x, y));
+    }
+    public virtual IList<IPrimitive> GetAllPrimitives(PointD point) {
+      List<IPrimitive> primitives = new List<IPrimitive>();
+      for (int i = 0; i < myPrimitives.Count; i++) {
+        if (myPrimitives[i].ContainsPoint(point)) {
+          primitives.Add(myPrimitives[i]);
+          if (myPrimitives[i] is IGroup) {
+            primitives.AddRange(((IGroup)myPrimitives[i]).Primitives);
+          }
+        }
+      }
+      return primitives;
+    }
+    public IList<IPrimitive> GetAllPrimitives(double x, double y) {
+      return GetAllPrimitives(new PointD(x, y));
+    }
+
+    public override void Move(Offset delta) {
+      bool updateEnabled = UpdateEnabled;
+      UpdateEnabled = false;
+      foreach (IPrimitive primitive in myPrimitives)
+        primitive.Move(delta);
+      UpdateEnabled = updateEnabled;
+      OnUpdate();
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      return GetPrimitive(point) != null;
+    }
+
+    public override Cursor GetCursor(PointD point) {
+      IPrimitive primitive = GetPrimitive(point);
+      if (primitive != null) return primitive.GetCursor(point);
+      else return base.GetCursor(point);
+    }
+    public override string GetToolTipText(PointD point) {
+      IPrimitive primitive = GetPrimitive(point);
+      if (primitive != null) return primitive.GetToolTipText(point);
+      else return base.GetToolTipText(point);
+    }
+
+    public void OneLayerUp(IPrimitive primitive) {
+      if (!Contains(primitive))
+        throw new ArgumentException("Primitive not found");
+
+      int index = myPrimitives.IndexOf(primitive);
+      if (index > 0) {
+        myPrimitives.Remove(primitive);
+        myPrimitives.Insert(index - 1, primitive);
+        OnUpdate();
+      }
+    }
+    public void OneLayerDown(IPrimitive primitive) {
+      if (!Contains(primitive))
+        throw new ArgumentException("Primitive not found");
+
+      int index = myPrimitives.IndexOf(primitive);
+      if (index < myPrimitives.Count - 1) {
+        myPrimitives.Remove(primitive);
+        myPrimitives.Insert(index + 1, primitive);
+        OnUpdate();
+      }
+    }
+    public void IntoForeground(IPrimitive primitive) {
+      if (!Contains(primitive))
+        throw new ArgumentException("Primitive not found");
+
+      myPrimitives.Remove(primitive);
+      myPrimitives.Insert(0, primitive);
+      OnUpdate();
+    }
+    public void IntoBackground(IPrimitive primitive) {
+      if (!Contains(primitive))
+        throw new ArgumentException("Primitive not found");
+
+      myPrimitives.Remove(primitive);
+      myPrimitives.Add(primitive);
+      OnUpdate();
+    }
+
+    public override void Draw(Graphics graphics) {
+      for (int i = myPrimitives.Count - 1; i >= 0; i--) {
+        myPrimitives[i].PreDraw(graphics);
+        myPrimitives[i].Draw(graphics);
+        myPrimitives[i].PostDraw(graphics);
+      }
+    }
+
+    private void primitive_Update(object sender, EventArgs e) {
+      OnUpdate();
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Line.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Line.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Line.cs	(revision 4773)
@@ -0,0 +1,72 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public class Line : LinearPrimitiveBase {
+    public Line(IChart chart, PointD start, PointD end)
+      : base(chart, start, end) {
+    }
+    public Line(IChart chart, double x1, double y1, double x2, double y2)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+    public Line(IChart chart, PointD start, PointD end, Pen pen)
+      : base(chart, start, end, pen, null) {
+    }
+    public Line(IChart chart, double x1, double y1, double x2, double y2, Pen pen)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen) {
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      if (base.ContainsPoint(point)) return true;
+
+      double penWidthX = Chart.PixelToWorldRatio.Width * (Pen.Width + 1);
+      double penWidthY = Chart.PixelToWorldRatio.Height * (Pen.Width + 1);
+
+      if ((point.X < (Math.Min(Start.X, End.X) - (penWidthX / 2))) ||
+          (point.Y < (Math.Min(Start.Y, End.Y) - (penWidthY / 2))) ||
+          (point.X > (Math.Max(Start.X, End.X) + (penWidthX / 2))) ||
+          (point.Y > (Math.Max(Start.Y, End.Y) + (penWidthY / 2)))) {
+        return false;
+      }
+
+      // calculate distance between point P(X,Y) and line
+      // d(P,g) = |AP.n|/|n|
+      Offset start_end = End - Start;
+      Offset n = new Offset(start_end.DY, -1 * start_end.DX);
+      Offset start_point = point - Start;
+      double d = Math.Abs(start_point.DX * n.DX + start_point.DY * n.DY) / n.Length;
+
+      return d <= Math.Max(penWidthX, penWidthY) / 2;
+    }
+
+    public override void Draw(Graphics graphics) {
+      graphics.DrawLine(Pen, Chart.TransformWorldToPixel(Start), Chart.TransformWorldToPixel(End));
+      base.Draw(graphics);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/LinearPrimitiveBase.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/LinearPrimitiveBase.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/LinearPrimitiveBase.cs	(revision 4773)
@@ -0,0 +1,126 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public abstract class LinearPrimitiveBase : PrimitiveBase {
+    protected IGroup selectionRectangles;
+
+    private PointD myStart;
+    public virtual PointD Start {
+      get { return myStart; }
+    }
+    private PointD myEnd;
+    public virtual PointD End {
+      get { return myEnd; }
+    }
+    public virtual SizeD Size {
+      get { return new SizeD(End.X - Start.X, End.Y - Start.Y); }
+    }
+    public virtual double Length {
+      get { return (Start - End).Length; }
+    }
+
+    protected LinearPrimitiveBase(IChart chart, PointD start, PointD end)
+      : base(chart) {
+      selectionRectangles = new Group(chart);
+      myStart = start;
+      myEnd = end;
+    }
+    protected LinearPrimitiveBase(IChart chart, double x1, double y1, double x2, double y2)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+    protected LinearPrimitiveBase(IChart chart, PointD start, PointD end, Pen pen, Brush brush)
+      : base(chart, pen, brush) {
+      selectionRectangles = new Group(chart);
+      myStart = start;
+      myEnd = end;
+    }
+    protected LinearPrimitiveBase(IChart chart, double x1, double y1, double x2, double y2, Pen pen, Brush brush)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen, brush) {
+    }
+
+    public virtual void SetPosition(PointD start, PointD end) {
+      myStart = start;
+      myEnd = end;
+      OnUpdate();
+    }
+    public void SetPosition(double x1, double y1, double x2, double y2) {
+      SetPosition(new PointD(x1, y1), new PointD(x2, y2));
+    }
+    public override void Move(Offset delta) {
+      SetPosition(Start + delta, End + delta);
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      if (Selected) {
+        if (selectionRectangles.GetPrimitive(point) != null) return true;
+      }
+      return false;
+    }
+
+    public override void MouseDrag(PointD point, Offset offset, MouseButtons button) {
+      if (button == MouseButtons.Left) {
+        if (Selected) {
+          if (selectionRectangles.ContainsPoint(point)) {
+            SelectionRectangle rect = (SelectionRectangle)selectionRectangles.GetPrimitive(point);
+            if (rect.Point == Start) {
+              SetPosition(Start + offset, End);
+            } else if (rect.Point == End) {
+              SetPosition(Start, End + offset);
+            }
+          } else {
+            base.MouseDrag(point, offset, button);
+          }
+        }
+      }
+    }
+
+    public override Cursor GetCursor(PointD point) {
+      if (Selected) {
+        Cursor cursor = selectionRectangles.GetCursor(point);
+        if (cursor != null) return cursor;
+      }
+      return base.GetCursor(point);
+    }
+
+    public override void PostDraw(Graphics graphics) {
+      selectionRectangles.Clear();
+      if (Selected) {
+        Pen pen = new Pen(Color.LightGray, 3);
+        pen.DashStyle = DashStyle.Dash;
+        graphics.DrawLine(pen,
+                          Chart.TransformWorldToPixel(Start),
+                          Chart.TransformWorldToPixel(End));
+        selectionRectangles.Add(new SelectionRectangle(Chart, Start, Cursors.SizeAll));
+        selectionRectangles.Add(new SelectionRectangle(Chart, End, Cursors.SizeAll));
+
+        selectionRectangles.Draw(graphics);
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/PrimitiveBase.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/PrimitiveBase.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/PrimitiveBase.cs	(revision 4773)
@@ -0,0 +1,182 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public abstract class PrimitiveBase : IPrimitive {
+    private IChart myChart;
+    public IChart Chart {
+      get { return myChart; }
+    }
+    private IGroup myGroup;
+    public IGroup Group {
+      get { return myGroup; }
+      set { myGroup = value; }
+    }
+
+    private Pen myPen;
+    public virtual Pen Pen {
+      get { return myPen; }
+      set {
+        myPen = value;
+        OnUpdate();
+      }
+    }
+    private Brush myBrush;
+    public virtual Brush Brush {
+      get { return myBrush; }
+      set {
+        myBrush = value;
+        OnUpdate();
+      }
+    }
+
+    private bool myUpdateEnabled;
+    public bool UpdateEnabled {
+      get { return myUpdateEnabled; }
+      set { myUpdateEnabled = value; }
+    }
+
+    private bool mySelected;
+    public virtual bool Selected {
+      get { return mySelected; }
+      set {
+        mySelected = value;
+        OnUpdate();
+      }
+    }
+
+    private string myToolTipText;
+    public string ToolTipText {
+      get { return myToolTipText; }
+      set { myToolTipText = value; }
+    }
+
+    private object myTag;
+    public object Tag {
+      get { return myTag; }
+      set { myTag = value; }
+    }
+
+    protected PrimitiveBase(IChart chart) {
+      myChart = chart;
+      myGroup = null;
+      myPen = Pens.Black;
+      myBrush = Brushes.White;
+      myUpdateEnabled = true;
+      mySelected = false;
+      myToolTipText = null;
+      myTag = null;
+    }
+    protected PrimitiveBase(IChart chart, Pen pen, Brush brush)
+      : this(chart) {
+      myPen = pen;
+      myBrush = brush;
+    }
+
+    public abstract void Move(Offset delta);
+    public void Move(double dx, double dy) {
+      Move(new Offset(dx, dy));
+    }
+
+    public abstract bool ContainsPoint(PointD point);
+    public bool ContainsPoint(double x, double y) {
+      return ContainsPoint(new PointD(x, y));
+    }
+
+    public virtual Cursor GetCursor(PointD point) {
+      return null;
+    }
+    public Cursor GetCursor(double x, double y) {
+      return GetCursor(new PointD(x, y));
+    }
+    public virtual string GetToolTipText(PointD point) {
+      return ToolTipText;
+    }
+    public string GetToolTipText(double x, double y) {
+      return GetToolTipText(new PointD(x, y));
+    }
+
+    public void OneLayerUp() {
+      Group.OneLayerUp(this);
+    }
+    public void OneLayerDown() {
+      Group.OneLayerDown(this);
+    }
+    public void IntoForeground() {
+      Group.IntoForeground(this);
+    }
+    public void IntoBackground() {
+      Group.IntoBackground(this);
+    }
+
+    public virtual void MouseClick(PointD point, MouseButtons button) {
+      if (button == MouseButtons.Left) {
+        Selected = true;
+      }
+    }
+    public void MouseClick(double x, double y, MouseButtons button) {
+      MouseClick(new PointD(x, y), button);
+    }
+    public virtual void MouseDoubleClick(PointD point, MouseButtons button) {
+    }
+    public void MouseDoubleClick(double x, double y, MouseButtons button) {
+      MouseDoubleClick(new PointD(x, y), button);
+    }
+    public virtual void MouseMove(PointD point, Offset offset) {
+    }
+    public void MouseMove(double x, double y, double dx, double dy) {
+      MouseMove(new PointD(x, y), new Offset(dx, dy));
+    }
+    public virtual void MouseDrag(PointD point, Offset offset, MouseButtons button) {
+      if (button == MouseButtons.Left) {
+        Move(offset);
+      }
+    }
+    public void MouseDrag(double x, double y, double dx, double dy, MouseButtons button) {
+      MouseDrag(new PointD(x, y), new Offset(dx, dy), button);
+    }
+
+    public virtual void PreDraw(Graphics graphics) {
+    }
+    public virtual void Draw(Graphics graphics) {
+    }
+    public virtual void PostDraw(Graphics graphics) {
+    }
+
+    public event EventHandler Update;
+    public void EnforceUpdate() {
+      if (Update != null) {
+        Update(this, new EventArgs());
+      }
+    }
+    protected virtual void OnUpdate() {
+      if ((UpdateEnabled) && (Update != null)) {
+        Update(this, new EventArgs());
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Rectangle.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Rectangle.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/Rectangle.cs	(revision 4773)
@@ -0,0 +1,57 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public class Rectangle : RectangularPrimitiveBase {
+    public Rectangle(IChart chart, PointD lowerLeft, PointD upperRight)
+      : base(chart, lowerLeft, upperRight) {
+    }
+    public Rectangle(IChart chart, double x1, double y1, double x2, double y2)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+    public Rectangle(IChart chart, PointD lowerLeft, PointD upperRight, Pen pen, Brush brush)
+      : base(chart, lowerLeft, upperRight, pen, brush) {
+    }
+    public Rectangle(IChart chart, double x1, double y1, double x2, double y2, Pen pen, Brush brush)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen, brush) {
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      if (base.ContainsPoint(point)) return true;
+      return (point.X >= LowerLeft.X) && (point.X <= UpperRight.X) &&
+             (point.Y >= LowerLeft.Y) && (point.Y <= UpperRight.Y);
+    }
+
+    public override void Draw(Graphics graphics) {
+      Point p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height));
+      Size s = Chart.TransformWorldToPixel(Size);
+      if (Brush != null)
+        graphics.FillRectangle(Brush, p.X, p.Y, s.Width, s.Height);
+      graphics.DrawRectangle(Pen, p.X, p.Y, s.Width, s.Height);
+      base.Draw(graphics);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/RectangularPrimitiveBase.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/RectangularPrimitiveBase.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/RectangularPrimitiveBase.cs	(revision 4773)
@@ -0,0 +1,138 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public abstract class RectangularPrimitiveBase : PrimitiveBase {
+    protected IGroup selectionRectangles;
+
+    private PointD myLowerLeft;
+    public virtual PointD LowerLeft {
+      get { return myLowerLeft; }
+    }
+    private PointD myUpperRight;
+    public virtual PointD UpperRight {
+      get { return myUpperRight; }
+    }
+    public virtual SizeD Size {
+      get { return new SizeD(UpperRight.X - LowerLeft.X, UpperRight.Y - LowerLeft.Y); }
+    }
+
+    protected RectangularPrimitiveBase(IChart chart, PointD lowerLeft, PointD upperRight)
+      : base(chart) {
+      selectionRectangles = new Group(chart);
+      SetPosition(lowerLeft, upperRight);
+    }
+    protected RectangularPrimitiveBase(IChart chart, double x1, double y1, double x2, double y2)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2)) {
+    }
+    protected RectangularPrimitiveBase(IChart chart, PointD lowerLeft, PointD upperRight, Pen pen, Brush brush)
+      : base(chart, pen, brush) {
+      selectionRectangles = new Group(chart);
+      SetPosition(lowerLeft, upperRight);
+    }
+    protected RectangularPrimitiveBase(IChart chart, double x1, double y1, double x2, double y2, Pen pen, Brush brush)
+      : this(chart, new PointD(x1, y1), new PointD(x2, y2), pen, brush) {
+    }
+
+    public virtual void SetPosition(PointD lowerLeft, PointD upperRight) {
+      if ((lowerLeft.X > upperRight.X) || (lowerLeft.Y > upperRight.Y))
+        throw new ArgumentException("Lower left point is greater than upper right point");
+
+      myLowerLeft = lowerLeft;
+      myUpperRight = upperRight;
+      OnUpdate();
+    }
+    public void SetPosition(double x1, double y1, double x2, double y2) {
+      SetPosition(new PointD(x1, y1), new PointD(x2, y2));
+    }
+    public override void Move(Offset delta) {
+      SetPosition(LowerLeft + delta, UpperRight + delta);
+    }
+
+    public override bool ContainsPoint(PointD point) {
+      if (Selected) {
+        if (selectionRectangles.ContainsPoint(point)) return true;
+      }
+      return false;
+    }
+
+    public override void MouseDrag(PointD point, Offset offset, MouseButtons button) {
+      if (button == MouseButtons.Left) {
+        if (Selected) {
+          if (selectionRectangles.ContainsPoint(point)) {
+            SelectionRectangle rect = (SelectionRectangle)selectionRectangles.GetPrimitive(point);
+            PointD point1 = PointD.Empty;
+            PointD point2 = PointD.Empty;
+            if (rect.Point == LowerLeft) {
+              point1 = LowerLeft + offset;
+              point2 = UpperRight;
+            } else if (rect.Point == UpperRight) {
+              point1 = LowerLeft;
+              point2 = UpperRight + offset;
+            } else if ((rect.Point.X == LowerLeft.X) && (rect.Point.Y == UpperRight.Y)) {
+              point1 = new PointD(LowerLeft.X + offset.DX, LowerLeft.Y);
+              point2 = new PointD(UpperRight.X, UpperRight.Y + offset.DY);
+            } else if ((rect.Point.X == UpperRight.X) && (rect.Point.Y == LowerLeft.Y)) {
+              point1 = new PointD(LowerLeft.X, LowerLeft.Y + offset.DY);
+              point2 = new PointD(UpperRight.X + offset.DX, UpperRight.Y);
+            }
+            SetPosition(Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y),
+                        Math.Max(point1.X, point2.X), Math.Max(point1.Y, point2.Y));
+          } else {
+            base.MouseDrag(point, offset, button);
+          }
+        }
+      }
+    }
+
+    public override Cursor GetCursor(PointD point) {
+      if (Selected) {
+        Cursor cursor = selectionRectangles.GetCursor(point);
+        if (cursor != null) return cursor;
+      }
+      return base.GetCursor(point);
+    }
+
+    public override void PostDraw(Graphics graphics) {
+      selectionRectangles.Clear();
+      if (Selected) {
+        Pen pen = new Pen(Color.LightGray, 3);
+        pen.DashStyle = DashStyle.Dash;
+        Point p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height));
+        Size s = Chart.TransformWorldToPixel(Size);
+        graphics.DrawRectangle(pen, p.X, p.Y, s.Width, s.Height);
+        selectionRectangles.Add(new SelectionRectangle(Chart, UpperRight.X, LowerLeft.Y, Cursors.SizeNWSE));
+        selectionRectangles.Add(new SelectionRectangle(Chart, LowerLeft.X, LowerLeft.Y, Cursors.SizeNESW));
+        selectionRectangles.Add(new SelectionRectangle(Chart, UpperRight.X, UpperRight.Y, Cursors.SizeNESW));
+        selectionRectangles.Add(new SelectionRectangle(Chart, LowerLeft.X, UpperRight.Y, Cursors.SizeNWSE));
+
+        selectionRectangles.Draw(graphics);
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/SelectionRectangle.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/SelectionRectangle.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Primitives/SelectionRectangle.cs	(revision 4773)
@@ -0,0 +1,47 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public class SelectionRectangle : FixedSizeRectangle {
+    private static int size = 6;
+    private Cursor cursor;
+
+    public SelectionRectangle(IChart chart, PointD point, Cursor cursor)
+      : base(chart, point, new Size(size, size)) {
+      this.cursor = cursor;
+      Pen = Pens.Black;
+      Brush = Brushes.LightGray;
+    }
+    public SelectionRectangle(IChart chart, double x, double y, Cursor cursor)
+      : this(chart, new PointD(x, y), cursor) {
+    }
+
+    public override Cursor GetCursor(PointD point) {
+      return cursor;
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Properties/AssemblyInfo.frame
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Properties/AssemblyInfo.frame	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Properties/AssemblyInfo.frame	(revision 4773)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.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.Drawing")]
+[assembly: AssemblyDescription("Core classes of the HeuristicLab drawing framework")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2010 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("d68ae989-7286-4f29-a237-852547e5701d")]
+
+// 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 Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.1.$WCREV$")]
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.Designer.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.Designer.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.Designer.cs	(revision 4773)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Drawing {
+  partial class PropertiesDialog {
+    /// <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 Windows Form 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.okButton = new System.Windows.Forms.Button();
+      this.propertyGrid = new System.Windows.Forms.PropertyGrid();
+      this.SuspendLayout();
+      // 
+      // okButton
+      // 
+      this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+      this.okButton.Location = new System.Drawing.Point(419, 271);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 0;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      // 
+      // propertyGrid
+      // 
+      this.propertyGrid.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.propertyGrid.Location = new System.Drawing.Point(12, 12);
+      this.propertyGrid.Name = "propertyGrid";
+      this.propertyGrid.Size = new System.Drawing.Size(482, 253);
+      this.propertyGrid.TabIndex = 1;
+      // 
+      // PropertiesDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(506, 306);
+      this.Controls.Add(this.propertyGrid);
+      this.Controls.Add(this.okButton);
+      this.Name = "PropertiesDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Properties";
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button okButton;
+    protected System.Windows.Forms.PropertyGrid propertyGrid;
+
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.cs	(revision 4773)
@@ -0,0 +1,45 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Drawing {
+  public partial class PropertiesDialog : Form {
+    public object SelectedObject {
+      get { return propertyGrid.SelectedObject; }
+      set { propertyGrid.SelectedObject = value; }
+    }
+
+    public PropertiesDialog() {
+      InitializeComponent();
+    }
+    public PropertiesDialog(object selectedObject)
+      : this() {
+      SelectedObject = selectedObject;
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.resx
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.resx	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/PropertiesDialog.resx	(revision 4773)
@@ -0,0 +1,120 @@
+<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/Offset.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/Offset.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/Offset.cs	(revision 4773)
@@ -0,0 +1,101 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public struct Offset {
+    public static readonly Offset Empty;
+
+    private double myDX;
+    public double DX {
+      get { return myDX; }
+      set { myDX = value; }
+    }
+    private double myDY;
+    public double DY {
+      get { return myDY; }
+      set { myDY = value; }
+    }
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+    public double Length {
+      get { return Math.Sqrt(DX * DX + DY * DY); }
+    }
+
+    public Offset(double dx, double dy) {
+      myDX = dx;
+      myDY = dy;
+    }
+    public Offset(PointD point) {
+      myDX = point.X;
+      myDY = point.Y;
+    }
+    public Offset(SizeD size) {
+      myDX = size.Width;
+      myDY = size.Height;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is Offset) {
+        return ((Offset)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+    public override int GetHashCode() {
+      return (int)Math.Pow(DX, DY);
+    }
+    public override string ToString() {
+      return "(" + DX.ToString() + ";" + DY.ToString() + ")";
+    }
+
+    public static Offset operator +(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
+    }
+    public static Offset operator -(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
+    }
+    public static bool operator ==(Offset offset1, Offset offset2) {
+      return (offset1.DX == offset2.DX) && (offset1.DY == offset2.DY);
+    }
+    public static bool operator !=(Offset offset1, Offset offset2) {
+      return (offset1.DX != offset2.DX) && (offset1.DY != offset2.DY);
+    }
+    public static explicit operator PointD(Offset offset) {
+      return new PointD(offset.DX, offset.DY);
+    }
+    public static explicit operator SizeD(Offset offset) {
+      return new SizeD(offset.DX, offset.DY);
+    }
+
+    public static Offset Add(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX + offset2.DX, offset1.DY + offset2.DY);
+    }
+    public static Offset Subtract(Offset offset1, Offset offset2) {
+      return new Offset(offset1.DX - offset2.DX, offset1.DY - offset2.DY);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/PointD.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/PointD.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/PointD.cs	(revision 4773)
@@ -0,0 +1,110 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public struct PointD {
+    public static readonly PointD Empty;
+
+    private double myX;
+    public double X {
+      get { return myX; }
+      set { myX = value; }
+    }
+    private double myY;
+    public double Y {
+      get { return myY; }
+      set { myY = value; }
+    }
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+
+    public PointD(double x, double y) {
+      myX = x;
+      myY = y;
+    }
+    public PointD(SizeD size) {
+      myX = size.Width;
+      myY = size.Height;
+    }
+    public PointD(Offset offset) {
+      myX = offset.DX;
+      myY = offset.DY;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is PointD) {
+        return ((PointD)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+    public override int GetHashCode() {
+      return (int)Math.Pow(X, Y);
+    }
+    public override string ToString() {
+      return "(" + X.ToString() + ";" + Y.ToString() + ")";
+    }
+
+    public static PointD operator +(PointD point, Offset offset) {
+      return new PointD(point.X + offset.DX, point.Y + offset.DY);
+    }
+    public static PointD operator -(PointD point, Offset offset) {
+      return new PointD(point.X - offset.DX, point.Y - offset.DY);
+    }
+    public static Offset operator +(PointD point1, PointD point2) {
+      return new Offset(point1.X + point2.X, point1.Y + point2.Y);
+    }
+    public static Offset operator -(PointD point1, PointD point2) {
+      return new Offset(point1.X - point2.X, point1.Y - point2.Y);
+    }
+    public static bool operator ==(PointD point1, PointD point2) {
+      return (point1.X == point2.X) && (point1.Y == point2.Y);
+    }
+    public static bool operator !=(PointD point1, PointD point2) {
+      return (point1.X != point2.X) && (point1.Y != point2.Y);
+    }
+    public static explicit operator SizeD(PointD point) {
+      return new SizeD(point.X, point.Y);
+    }
+    public static explicit operator Offset(PointD point) {
+      return new Offset(point.X, point.Y);
+    }
+    public static implicit operator PointD(Point point) {
+      return new PointD(point.X, point.Y);
+    }
+    public static implicit operator PointD(PointF point) {
+      return new PointD(point.X, point.Y);
+    }
+
+    public static PointD Add(PointD point, Offset offset) {
+      return new PointD(point.X + offset.DX, point.Y + offset.DY);
+    }
+    public static PointD Subtract(PointD point, Offset offset) {
+      return new PointD(point.X - offset.DX, point.Y - offset.DY);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/SizeD.cs
===================================================================
--- branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/SizeD.cs	(revision 4773)
+++ branches/HeuristicLab.Drawing/HeuristicLab.Drawing/3.3/Structs/SizeD.cs	(revision 4773)
@@ -0,0 +1,104 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Drawing {
+  public struct SizeD {
+    public static readonly SizeD Empty;
+
+    private double myWidth;
+    public double Width {
+      get { return myWidth; }
+      set { myWidth = value; }
+    }
+    private double myHeight;
+    public double Height {
+      get { return myHeight; }
+      set { myHeight = value; }
+    }
+    public bool IsEmpty {
+      get { return this == Empty; }
+    }
+
+    public SizeD(double width, double height) {
+      myWidth = width;
+      myHeight = height;
+    }
+    public SizeD(PointD point) {
+      myWidth = point.X;
+      myHeight = point.Y;
+    }
+    public SizeD(Offset offset) {
+      myWidth = offset.DX;
+      myHeight = offset.DY;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is SizeD) {
+        return ((SizeD)obj) == this;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+    public override int GetHashCode() {
+      return (int)Math.Pow(Width, Height);
+    }
+    public override string ToString() {
+      return "(" + Width.ToString() + ";" + Height.ToString() + ")";
+    }
+
+    public static SizeD operator +(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
+    }
+    public static SizeD operator -(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
+    }
+    public static bool operator ==(SizeD size1, SizeD size2) {
+      return (size1.Width == size2.Width) && (size1.Height == size2.Height);
+    }
+    public static bool operator !=(SizeD size1, SizeD size2) {
+      return (size1.Width != size2.Width) && (size1.Height != size2.Height);
+    }
+    public static explicit operator PointD(SizeD size) {
+      return new PointD(size.Width, size.Height);
+    }
+    public static explicit operator Offset(SizeD size) {
+      return new Offset(size.Width, size.Height);
+    }
+    public static implicit operator SizeD(Size size) {
+      return new SizeD(size.Width, size.Height);
+    }
+    public static implicit operator SizeD(SizeF size) {
+      return new SizeD(size.Width, size.Height);
+    }
+
+    public static SizeD Add(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width + size2.Width, size1.Height + size2.Height);
+    }
+    public static SizeD Subtract(SizeD size1, SizeD size2) {
+      return new SizeD(size1.Width - size2.Width, size1.Height - size2.Height);
+    }
+  }
+}
Index: branches/HeuristicLab.Drawing/PreBuildEvent.cmd
===================================================================
--- branches/HeuristicLab.Drawing/PreBuildEvent.cmd	(revision 4773)
+++ branches/HeuristicLab.Drawing/PreBuildEvent.cmd	(revision 4773)
@@ -0,0 +1,2 @@
+SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
