Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ants.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ants.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ants.cs	(revision 2781)
@@ -0,0 +1,85 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing.Drawing2D;
+using System.Drawing;
+using Netron.Diagramming.Core;
+
+namespace HeuristicLab.Netron {
+  internal static class AntsFactory {
+    private static RectAnts mRectangular;
+    public readonly static Pen Pen = new Pen(Color.Black, 1f);
+    static AntsFactory() {
+      Pen.DashStyle = DashStyle.Dash;
+    }
+    public static IAnts GetAnts(object pars, AntTypes type) {
+      switch (type) {
+        case AntTypes.Rectangle:
+          if (mRectangular == null)
+            mRectangular = new RectAnts();
+          Point[] points = (Point[])pars;
+          mRectangular.Start = points[0];
+          mRectangular.End = points[1];
+          return mRectangular;
+        default:
+          return null;
+      }
+    }
+
+    internal class RectAnts : AbstractAnt {
+      public RectAnts(Point s, Point e)
+        : this() {
+        this.Start = s;
+        this.End = e;
+
+      }
+
+      public RectAnts()
+        : base() {
+        Pen.DashStyle = DashStyle.Dash;
+      }
+
+      public override void Paint(Graphics g) {
+        if (g == null)
+          return;
+        g.DrawRectangle(AntsFactory.Pen, Start.X, Start.Y, End.X - Start.X, End.Y - Start.Y);
+
+      }
+    }
+
+    internal abstract class AbstractAnt : IAnts {
+      private Point mStart;
+      public Point Start {
+        get {
+          return mStart;
+        }
+        set {
+          mStart = value;
+        }
+      }
+      private Point mEnd;
+      public Point End {
+        get {
+          return mEnd;
+        }
+        set {
+          mEnd = value;
+        }
+      }
+
+      public Rectangle Rectangle {
+        get { return new Rectangle(mStart.X, mStart.Y, mEnd.X - mStart.X, mEnd.Y - mStart.Y); }
+        set {
+          mStart = new Point(value.X, value.Y);
+          mEnd = new Point(value.Right, value.Bottom);
+        }
+      }
+
+      public abstract void Paint(Graphics g);
+    }
+  }
+  internal enum AntTypes {
+    Rectangle
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Controller.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Controller.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Controller.cs	(revision 2781)
@@ -0,0 +1,23 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Netron.Diagramming.Core;
+
+namespace HeuristicLab.Netron {
+  public class Controller : ControllerBase {
+
+    public const string TextToolName = "Text Tool";
+    public const string TextEditorToolName = "Text Editor Tool";
+
+    public Controller(IDiagramControl surface)
+      : base(surface) {
+    }
+
+    public override bool ActivateTextEditor(ITextProvider textProvider) {
+      TextEditor.GetEditor(textProvider);
+      TextEditor.Show();
+      return true;
+    }  
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ghosts.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ghosts.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/Ghosts.cs	(revision 2781)
@@ -0,0 +1,215 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Netron.Diagramming.Core;
+using System.Drawing;
+
+namespace HeuristicLab.Netron {
+  internal static class GhostsFactory {
+    private static RectGhost mRectangular;
+    private static LineGhost mLine;
+    private static EllipticGhost mEllipse;
+    private static MultiLineGhost mMultiLine;
+    private static CurvedLineGhost mCurvedLine;
+    private static PolygonGhost mPolygon;
+
+    private static IView mView;
+    public static IView View {
+      get { return mView; }
+      set { mView = value; }
+    }
+
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+    public static IGhost GetGhost(object pars, GhostTypes type) {
+      Point[] points;
+      switch (type) {
+        case GhostTypes.Rectangle:
+          if (mRectangular == null)
+            mRectangular = new RectGhost(View);
+          points = (Point[])pars;
+          mRectangular.Start = points[0];
+          mRectangular.End = points[1];
+          return mRectangular;
+        case GhostTypes.Ellipse:
+          if (mEllipse == null)
+            mEllipse = new EllipticGhost(View);
+          points = (Point[])pars;
+          mEllipse.Start = points[0];
+          mEllipse.End = points[1];
+          return mEllipse;
+        case GhostTypes.Line:
+          if (mLine == null)
+            mLine = new LineGhost(View);
+          points = (Point[])pars;
+          mLine.Start = points[0];
+          mLine.End = points[1];
+          return mLine;
+        case GhostTypes.MultiLine:
+          if (mMultiLine == null)
+            mMultiLine = new MultiLineGhost(View);
+          points = (Point[])pars;
+          mMultiLine.Points = points;
+          return mMultiLine;
+        case GhostTypes.CurvedLine:
+          if (mCurvedLine == null)
+            mCurvedLine = new CurvedLineGhost(View);
+          points = (Point[])pars;
+          mCurvedLine.Points = points;
+          return mCurvedLine;
+        case GhostTypes.Polygon:
+          if (mPolygon == null)
+            mPolygon = new PolygonGhost(View);
+          points = (Point[])pars;
+          mPolygon.Points = points;
+          return mPolygon;
+        default:
+          return null;
+      }
+    }
+  }
+
+  internal class PolygonGhost : MultiLineGhost {
+    public PolygonGhost(IView view) : base(view) { }
+    public override void Paint(Graphics g) {
+      g.Transform = View.ViewMatrix;
+      g.DrawPolygon(ArtPalette.GhostPen, Points);
+    }
+  }
+
+  internal class CurvedLineGhost : MultiLineGhost {
+    public CurvedLineGhost(IView view)
+      : base(view) { }
+    public override void Paint(Graphics g) {
+      g.Transform = View.ViewMatrix;
+      g.DrawCurve(ArtPalette.GhostPen, Points);
+    }
+  }
+
+  internal class MultiLineGhost : AbstractGhost {
+    private Point[] points;
+    public Point[] Points {
+      get {
+        return points;
+      }
+      set {
+        points = value;
+        Start = value[0];
+        End = value[value.Length - 1];
+      }
+    }
+    public MultiLineGhost(IView view, Point[] points)
+      : base(view) {
+      this.points = points;
+    }
+    public MultiLineGhost(IView view)
+      : base(view) {
+
+    }
+    public override void Paint(Graphics g) {
+      if (g == null)
+        return;
+      g.Transform = View.ViewMatrix;
+      g.DrawLines(ArtPalette.GhostPen, points);
+    }
+  }
+
+  internal class RectGhost : AbstractGhost {
+    public RectGhost(IView view, Point s, Point e)
+      : base(view, s, e) { }
+    public RectGhost(IView view)
+      : base(view) {
+    }
+    public override void Paint(Graphics g) {
+      if (g == null)
+        return;
+      g.FillRectangle(ArtPalette.GhostBrush, Rectangle);
+      g.DrawRectangle(ArtPalette.GhostPen, Rectangle);
+    }
+  }
+
+  internal class EllipticGhost : AbstractGhost {
+    public EllipticGhost(IView view, Point s, Point e)
+      : base(view, s, e) {
+    }
+    public EllipticGhost(IView view)
+      : base(view) {
+    }
+    public override void Paint(Graphics g) {
+      if (g == null)
+        return;
+      g.Transform = View.ViewMatrix;
+      g.FillEllipse(ArtPalette.GhostBrush, Rectangle);
+      g.DrawEllipse(ArtPalette.GhostPen, Rectangle);
+    }
+  }
+
+  internal class LineGhost : AbstractGhost {
+    public LineGhost(IView view, Point s, Point e)
+      : base(view, s, e) {
+    }
+    public LineGhost(IView view)
+      : base(view) {
+    }
+
+    public override void Paint(Graphics g) {
+      if (g == null)
+        return;
+      g.Transform = View.ViewMatrix;
+      g.DrawLine(ArtPalette.GhostPen, Start, End);
+    }
+  }
+
+  internal abstract class AbstractGhost : IGhost {
+    private Point mStart;
+    private Point mEnd;
+    private IView mView;
+    public IView View {
+      get { return mView; }
+      set { mView = value; }
+    }
+    public Rectangle Rectangle {
+      get {
+        return Rectangle.FromLTRB(Math.Min(mStart.X, mEnd.X), Math.Min(mStart.Y, mEnd.Y), Math.Max(mStart.X, mEnd.X), Math.Max(mStart.Y, mEnd.Y));
+      }
+      set { 
+        //was orginally empty
+        throw new NotImplementedException();
+      }
+    }
+    public Point Start {
+      get {
+        return mStart;
+      }
+      set {
+        mStart = value;
+      }
+    }
+    public Point End {
+      get {
+        return mEnd;
+      }
+      set {
+        mEnd = value;
+      }
+    }
+    protected AbstractGhost(IView view, Point s, Point e)
+      : this(view) {
+      this.mStart = s;
+      this.mEnd = e;
+    }
+    protected AbstractGhost(IView view) {
+      mView = view;
+    }
+    public abstract void Paint(Graphics g);
+  }
+
+  internal enum GhostTypes {
+    Rectangle,
+    Ellipse,
+    Line,
+    MultiLine,
+    CurvedLine,
+    Polygon
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446.csproj
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446.csproj	(revision 2777)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446.csproj	(revision 2781)
@@ -38,4 +38,6 @@
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml.Linq">
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -48,6 +50,17 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="NetronVisualization.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="NetronVisualization.Designer.cs">
+      <DependentUpon>NetronVisualization.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Ants.cs" />
+    <Compile Include="Controller.cs" />
+    <Compile Include="Ghosts.cs" />
     <Compile Include="HeuristicLabNetronPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TextEditor.cs" />
+    <Compile Include="View.cs" />
   </ItemGroup>
   <ItemGroup>
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.Designer.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.Designer.cs	(revision 2781)
@@ -0,0 +1,36 @@
+﻿namespace HeuristicLab.Netron {
+  partial class NetronVisualization {
+    /// <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.SuspendLayout();
+      // 
+      // AlgorithmVisualization
+      // 
+      this.Name = "AlgorithmVisualization";
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/NetronVisualization.cs	(revision 2781)
@@ -0,0 +1,62 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+using Netron.Diagramming.Core;
+
+namespace HeuristicLab.Netron {
+  [ToolboxItem(true)]
+  public partial class NetronVisualization : DiagramControlBase {
+    public NetronVisualization()
+      : base() {
+      InitializeComponent();
+
+      SetStyle(ControlStyles.AllPaintingInWmPaint, true);
+      SetStyle(ControlStyles.DoubleBuffer, true);
+      SetStyle(ControlStyles.UserPaint, true);
+      SetStyle(ControlStyles.ResizeRedraw, true);
+
+      if (!DesignMode) {
+        this.Controller = new Controller(this);
+        this.View = new View(this);
+
+        this.Document = new Document();
+        this.AttachToDocument(Document);
+        this.Controller.View = View;
+        TextEditor.Init(this);
+
+        View.OnCursorChange += new EventHandler<CursorEventArgs>(mView_OnCursorChange);
+        View.OnBackColorChange += new EventHandler<ColorEventArgs>(View_OnBackColorChange);
+
+        this.SizeChanged += new EventHandler(AlgorithmVisualization_SizeChanged);
+        this.AllowDrop = true;
+      }
+    }
+
+    void AlgorithmVisualization_SizeChanged(object sender, EventArgs e) {
+      Size newSize = new Size((int) (this.Size.Width * this.View.Magnification.Width),
+        (int) (this.Size.Height * this.View.Magnification.Height));
+      this.View.PageSize = newSize;
+    }
+
+    protected override void OnScroll(ScrollEventArgs se) {
+      //base.OnScroll(se);
+      if (se.ScrollOrientation == ScrollOrientation.HorizontalScroll) {
+        Origin = new Point(se.NewValue, Origin.Y);
+        //System.Diagnostics.Trace.WriteLine(se.NewValue);
+      } else {
+        Origin = new Point(Origin.X, se.NewValue);
+        //System.Diagnostics.Trace.WriteLine(se.NewValue);
+      } 
+    }
+
+    private void mView_OnCursorChange(object sender, CursorEventArgs e) {
+      this.Cursor = e.Cursor;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/TextEditor.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/TextEditor.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/TextEditor.cs	(revision 2781)
@@ -0,0 +1,113 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Netron.Diagramming.Core;
+using System.Windows.Forms;
+using System.Drawing;
+
+namespace HeuristicLab.Netron {
+  public static class TextEditor {
+
+    private static TextEditorControl editor = null;
+    private static ITextProvider myTextProvider;
+    private static IDiagramControl diagramControl;
+
+    private static EventHandler<MouseEventArgs> onescape =
+           new EventHandler<MouseEventArgs>(Controller_OnMouseDown);
+
+    private static ITextProvider TextProvider {
+      get { return myTextProvider; }
+    }
+
+    private static TextEditorControl Editor {
+      get {
+        if (editor == null)
+          editor = new TextEditorControl();
+        return editor;
+      }
+    }
+
+    public static void Init(DiagramControlBase parent) {
+      diagramControl = parent;
+      parent.Controls.Add(Editor);
+      Editor.Visible = false;
+      Editor.BackColor = Color.White;
+    }
+
+    public static TextEditorControl GetEditor(ITextProvider textProvider) {
+      if (textProvider == null) {
+        throw new InconsistencyException(
+            "Cannot assign an editor to a 'null' text provider.");
+      }
+
+      // Adjust the editor's location and size by the current scroll 
+      // position and zoom factor.
+      Point location = Point.Round(diagramControl.View.WorldToView(
+          textProvider.TextArea.Location));
+
+      Size size = Size.Round(diagramControl.View.WorldToView(
+          textProvider.TextArea.Size));
+
+      myTextProvider = textProvider;
+      Editor.Location = location;
+      Editor.Width = size.Width;
+      Editor.Height = size.Height;
+      Editor.Font = textProvider.TextStyle.Font;
+      Editor.Visible = false;
+      return Editor;
+    }
+
+    public static void Show() {
+      if (myTextProvider == null)
+        return;
+      Selection.Clear();
+      diagramControl.View.ResetTracker();
+      diagramControl.Controller.SuspendAllTools();
+      diagramControl.Controller.Enabled = false;
+      diagramControl.Controller.OnMouseDown += onescape;
+      Editor.Visible = true;
+      Editor.Text = myTextProvider.Text;
+
+      if (myTextProvider.TextStyle.HorizontalAlignment == StringAlignment.Center)
+        Editor.TextAlign = HorizontalAlignment.Center;
+      else if (myTextProvider.TextStyle.HorizontalAlignment == StringAlignment.Far)
+        Editor.TextAlign = HorizontalAlignment.Right;
+      else
+        Editor.TextAlign = HorizontalAlignment.Left;
+
+      Editor.SelectionLength = Editor.Text.Length;
+      Editor.ScrollToCaret();
+      Editor.Focus();
+    }
+
+    static void Controller_OnMouseDown(object sender, MouseEventArgs e) {
+      Hide();
+      diagramControl.Controller.OnMouseDown -= onescape;
+    }
+
+    public static void Hide() {
+      if (myTextProvider == null)
+        return;
+      diagramControl.Controller.Enabled = true;
+      diagramControl.Focus();
+      Editor.Visible = false;
+      myTextProvider.Text = Editor.Text;
+      diagramControl.Controller.UnsuspendAllTools();
+      myTextProvider = null;
+    }
+
+    public class TextEditorControl : TextBox {
+      public TextEditorControl()
+        : base() {
+        this.BorderStyle = BorderStyle.FixedSingle;
+        this.Multiline = true;
+        this.ScrollBars = ScrollBars.None;
+        this.WordWrap = true;
+        this.BackColor = Color.White;
+      }
+
+    }
+
+  }
+}
Index: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/View.cs
===================================================================
--- trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/View.cs	(revision 2781)
+++ trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/HeuristicLab.Netron-3.0.2672.12446/View.cs	(revision 2781)
@@ -0,0 +1,218 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Netron.Diagramming.Core;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Netron {
+  public class View : ViewBase {
+
+    public View(IDiagramControl control)
+      : base(control) {
+      Selection.OnNewSelection += new EventHandler(Selection_OnNewSelection);
+      // this.Model.OnEntityAdded += new EventHandler<EntityEventArgs>(Model_OnEntityAdded);
+      this.HorizontalRuler.Visible = true;
+      this.VerticalRuler.Visible = true;
+      GhostsFactory.View = this;
+    }
+
+    void Model_OnEntityAdded(object sender, EntityEventArgs e) {
+
+    }
+
+    void Selection_OnNewSelection(object sender, EventArgs e) {
+      ShowTracker();
+    }
+
+    public override void Paint(Graphics g) {
+      base.Paint(g);
+      //Rectangle rectangle = WorkArea;
+      //g.SetClip(WorkArea);
+      g.Transform = ViewMatrix;
+      //draw the ghost and ants on top of the diagram
+      if (Ants != null)
+        Ants.Paint(g);
+      if (Ghost != null)
+        Ghost.Paint(g);
+      if (Tracker != null)
+        Tracker.Paint(g);
+
+      g.Transform.Reset();
+      //g.PageUnit = GraphicsUnit.Pixel;
+      //g.PageScale = 1.0F;
+    }
+
+    protected virtual void InvalidateGhostArea() {
+      if (Ghost != null) {
+        Rectangle area = Ghost.Rectangle;
+        // Inflate it a little so we make sure to get everything.
+        area.Inflate(20, 20);
+        this.Invalidate(area);
+      }
+    }
+
+    protected virtual void InvalidateTrackerArea() {
+      if (Tracker != null) {
+        Rectangle area = Tracker.Rectangle;
+        // Inflate it a little so we make sure to get everything.
+        area.Inflate(20, 20);
+        this.Invalidate(area);
+      }
+    }
+
+    protected virtual void InvalidateAntsArea() {
+      if (Ants != null) {
+        Rectangle area = Ants.Rectangle;
+        // Inflate it a little so we make sure to get everything.
+        area.Inflate(20, 20);
+        this.Invalidate(area);
+      }
+    }
+
+    public override void PaintGhostEllipse(
+        Point ltPoint,
+        Point rbPoint) {
+      // Refresh the old ghost area if needed.
+      this.InvalidateGhostArea();
+
+      Ghost = GhostsFactory.GetGhost(
+          new Point[] { ltPoint, rbPoint },
+              GhostTypes.Ellipse);
+    }
+    public override void PaintGhostRectangle(
+        Point ltPoint,
+        Point rbPoint) {
+      // Refresh the old ghost area if needed.
+      this.InvalidateGhostArea();
+
+      Ghost = GhostsFactory.GetGhost(
+          new Point[] { ltPoint, rbPoint },
+          GhostTypes.Rectangle);
+    }
+    public override void PaintAntsRectangle(
+        Point ltPoint,
+        Point rbPoint) {
+      // Refresh the old area if needed.
+      this.InvalidateAntsArea();
+      Ants = AntsFactory.GetAnts(
+          new Point[] { ltPoint, rbPoint },
+          AntTypes.Rectangle);
+    }
+    public override void PaintGhostLine(Point ltPoint, Point rbPoint) {
+      // Refresh the old ghost area if needed.
+      this.InvalidateGhostArea();
+
+      Ghost = GhostsFactory.GetGhost(
+          new Point[] { ltPoint, rbPoint },
+          GhostTypes.Line);
+    }
+    public override void PaintGhostLine(
+        MultiPointType curveType,
+        Point[] points) {
+      // Refresh the old ghost area if needed.
+      this.InvalidateGhostArea();
+
+      switch (curveType) {
+        case MultiPointType.Straight:
+          Ghost = GhostsFactory.GetGhost(points, GhostTypes.MultiLine);
+          break;
+        case MultiPointType.Polygon:
+          Ghost = GhostsFactory.GetGhost(points, GhostTypes.Polygon);
+          break;
+        case MultiPointType.Curve:
+          Ghost = GhostsFactory.GetGhost(points, GhostTypes.CurvedLine);
+          break;
+
+      }
+    }
+
+    public override void PaintTracker(Rectangle rectangle, bool showHandles) {
+      // Refresh the old area if needed.
+      this.InvalidateTrackerArea();
+      Tracker = TrackerFactory.GetTracker(rectangle, TrackerTypes.Default, showHandles);
+      rectangle.Inflate(20, 20);
+      this.Invalidate(rectangle);
+    }
+
+    #region Tracker
+
+    private enum TrackerTypes {
+      Default
+    }
+
+    private class TrackerFactory {
+
+      private static ITracker defTracker;
+
+      public static ITracker GetTracker(Rectangle rectangle, TrackerTypes type, bool showHandles) {
+        switch (type) {
+          case TrackerTypes.Default:
+            if (defTracker == null) defTracker = new DefaultTracker();
+            defTracker.Transform(rectangle);
+            defTracker.ShowHandles = showHandles;
+            return defTracker;
+          default:
+            return null;
+        }
+
+      }
+    }
+
+    private class DefaultTracker : TrackerBase {
+      private const int gripSize = 4;
+      private const int hitSize = 6;
+      float mx, my, sx, sy;
+
+      public DefaultTracker(Rectangle rectangle)
+        : base(rectangle) {
+      }
+
+      public DefaultTracker()
+        : base() { }
+
+      public override void Transform(Rectangle rectangle) {
+        this.Rectangle = rectangle;
+      }
+
+      public override void Paint(Graphics g) {
+        //the main rectangle
+        g.DrawRectangle(ArtPalette.TrackerPen, Rectangle);
+        #region Recalculate the size and location of the grips
+        mx = Rectangle.X + Rectangle.Width / 2;
+        my = Rectangle.Y + Rectangle.Height / 2;
+        sx = Rectangle.Width / 2;
+        sy = Rectangle.Height / 2;
+        #endregion
+        #region draw the grips
+        if (!ShowHandles) return;
+
+        for (int x = -1; x <= 1; x++) {
+          for (int y = -1; y <= 1; y++) {
+            if (x != 0 || y != 0) //not the middle one
+                        {
+              g.FillRectangle(ArtPalette.GripBrush, mx + x * sx - gripSize / 2, my + y * sy - gripSize / 2, gripSize, gripSize);
+              g.DrawRectangle(ArtPalette.BlackPen, mx + x * sx - gripSize / 2, my + y * sy - gripSize / 2, gripSize, gripSize);
+            }
+          }
+        }
+        #endregion
+      }
+
+      public override Point Hit(Point p) {
+        //no need to test if the handles are not shown
+        if (!ShowHandles) return Point.Empty;
+
+        for (int x = -1; x <= +1; x++)
+          for (int y = -1; y <= +1; y++)
+            if ((x != 0) || (y != 0)) {
+              if (new RectangleF(mx + x * sx - hitSize / 2, my + y * sy - hitSize / 2, hitSize, hitSize).Contains(p))
+                return new Point(x, y);
+            }
+        return Point.Empty;
+      }
+    }
+    #endregion
+  }
+}
