Index: branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.Designer.cs
===================================================================
--- branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.Designer.cs	(revision 10042)
+++ branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.Designer.cs	(revision 10042)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.MainForm.WindowsForms {
+  partial class BreadcrumbControl {
+    /// <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();
+      // 
+      // BreadcrumbControl
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.DoubleBuffered = true;
+      this.Name = "BreadcrumbControl";
+      this.Resize += new System.EventHandler(this.BreadcrumbControl_Resize);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.cs
===================================================================
--- branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.cs	(revision 10042)
+++ branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/BreadcrumbControl.cs	(revision 10042)
@@ -0,0 +1,152 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.MainForm.WindowsForms {
+  public partial class BreadcrumbControl : UserControl {
+    private LinkedList<IContent> breadcrumbs;
+    public IEnumerable<IContent> Breadcrumbs {
+      get { return breadcrumbs; }
+      set {
+        breadcrumbs = new LinkedList<IContent>(value);
+        BuildBreadcrumbTrail();
+      }
+    }
+
+    public ViewHost ViewHost { get; set; }
+
+    public BreadcrumbControl() {
+      InitializeComponent();
+      breadcrumbs = new LinkedList<IContent>();
+    }
+
+    private void BuildBreadcrumbTrail() {
+      var curLoc = new Point(3, 0);
+      int idx = 0;
+      var labels = new List<Label>();
+      foreach (var bc in breadcrumbs) {
+        Label label;
+        if (bc == breadcrumbs.Last.Value) {
+          label = new Label {
+            Location = curLoc,
+            AutoSize = true,
+            Font = new Font("Microsoft Sans Serif", 7f),
+            Text = bc.ToString()
+          };
+        } else {
+          label = new LinkLabel {
+            Location = curLoc,
+            AutoSize = true,
+            Font = new Font("Microsoft Sans Serif", 7f),
+            Text = bc.ToString(),
+            Tag = bc
+          };
+          label.Click += label_Click;
+        }
+        labels.Add(label);
+        label.Size = label.GetPreferredSize(Size.Empty);
+        curLoc.X += label.Size.Width;
+        if (++idx < breadcrumbs.Count) {
+          var separator = new Label {
+            Location = curLoc,
+            AutoSize = true,
+            Font = new Font("Microsoft Sans Serif", 7f),
+            Text = ">>"
+          };
+          labels.Add(separator);
+          separator.Size = separator.GetPreferredSize(Size.Empty);
+          curLoc.X += separator.Size.Width;
+        }
+      }
+      Controls.Clear();
+      if (curLoc.X <= Width)
+        Controls.AddRange(labels.ToArray());
+      else
+        AddLabelsRightToLeft(labels);
+    }
+
+    private void AddLabelsRightToLeft(List<Label> labels) {
+      if (!labels.Any()) return;
+      var curLoc = new Point(3, 0);
+      var ellipsis = new Label {
+        Location = curLoc,
+        AutoSize = true,
+        Font = new Font("Microsoft Sans Serif", 7f),
+        Text = "..."
+      };
+      ellipsis.Location = curLoc;
+      Controls.Add(ellipsis);
+      curLoc.X += ellipsis.Size.Width;
+      int x = Width;
+      int i = labels.Count - 1;
+      while (i >= 0) {
+        x -= labels[i].Size.Width;
+        if (x < curLoc.X) break;
+        x -= labels[--i].Size.Width;
+        if (x < curLoc.X) break;
+        i--;
+      }
+      if (i == labels.Count - 1) return;
+      i += 1 + i % 2;
+      while (i < labels.Count) {
+        var l = labels[i++];
+        l.Location = curLoc;
+        Controls.Add(l);
+        curLoc.X += l.Size.Width;
+      }
+    }
+
+    private void label_Click(object sender, EventArgs e) {
+      var label = (LinkLabel)sender;
+      var content = (IContent)label.Tag;
+      int crumbCount = breadcrumbs.Count;
+      while (breadcrumbs.Any()) {
+        var item = breadcrumbs.Last.Value;
+        if (item == content) break;
+        breadcrumbs.RemoveLast();
+      }
+      var targetViewHost = ViewHost;
+      if (crumbCount - breadcrumbs.Count > 0) {
+        for (var parent = Parent; parent != null; parent = parent.Parent) {
+          var vh = parent as ViewHost;
+          if (vh != null) targetViewHost = vh;
+        }
+      }
+      bool showBreadcrumbs = targetViewHost.ShowBreadcrumbs;
+      targetViewHost.Content = null;
+      var viewType = MainFormManager.GetDefaultViewType(content.GetType());
+      targetViewHost.ViewType = viewType;
+      targetViewHost.Content = content;
+      targetViewHost.UpdateBreadcrumbTrail(targetViewHost.Breadcrumbs, breadcrumbs);
+      targetViewHost.ShowBreadcrumbs = showBreadcrumbs;
+    }
+
+    private void BreadcrumbControl_Resize(object sender, EventArgs e) {
+      BuildBreadcrumbTrail();
+    }
+  }
+}
Index: branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewContextMenuStrip.cs
===================================================================
--- branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewContextMenuStrip.cs	(revision 10041)
+++ branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewContextMenuStrip.cs	(revision 10042)
@@ -30,22 +30,25 @@
     public ViewContextMenuStrip() {
       InitializeComponent();
-      this.menuItems = new Dictionary<Type, ToolStripMenuItem>();
-      this.ignoredViewTypes = new List<Type>();
+      menuItems = new Dictionary<Type, ToolStripMenuItem>();
+      ignoredViewTypes = new List<Type>();
     }
 
     public ViewContextMenuStrip(IContainer container)
       : base(container) {
-        InitializeComponent();
-      this.menuItems = new Dictionary<Type, ToolStripMenuItem>();
-      this.ignoredViewTypes = new List<Type>();
+      InitializeComponent();
+      menuItems = new Dictionary<Type, ToolStripMenuItem>();
+      ignoredViewTypes = new List<Type>();
+      ShowBreadcrumbsToolStripMenuItem = new ToolStripMenuItem("Show Breadcrumbs");
+      ShowBreadcrumbsToolStripMenuItem.Click += ShowBreadcrumbsToolStripMenuItem_Click;
+      ShowBreadcrumbsToolStripMenuItem.CheckedChanged += ShowBreadcrumbsToolStripMenuItem_CheckedChanged;
     }
 
     private object item;
     public object Item {
-      get { return this.item; }
+      get { return item; }
       set {
-        if (this.item != value) {
-          this.item = value;
-          this.RefreshMenuItems();
+        if (item != value) {
+          item = value;
+          RefreshMenuItems();
         }
       }
@@ -54,12 +57,14 @@
     private List<Type> ignoredViewTypes;
     public IEnumerable<Type> IgnoredViewTypes {
-      get { return this.ignoredViewTypes; }
-      set { this.ignoredViewTypes = new List<Type>(value); RefreshMenuItems(); }
+      get { return ignoredViewTypes; }
+      set { ignoredViewTypes = new List<Type>(value); RefreshMenuItems(); }
     }
 
     private Dictionary<Type, ToolStripMenuItem> menuItems;
     public IEnumerable<KeyValuePair<Type, ToolStripMenuItem>> MenuItems {
-      get { return this.menuItems; }
+      get { return menuItems; }
     }
+
+    public ToolStripMenuItem ShowBreadcrumbsToolStripMenuItem { get; private set; }
 
     private void RefreshMenuItems() {
@@ -68,8 +73,8 @@
         foreach (ToolStripMenuItem m in menuItems.Values)
           m.Dispose();
-        this.Items.Clear();
-        this.menuItems.Clear();
+        Items.Clear();
+        menuItems.Clear();
 
-        if (this.item != null) {
+        if (item != null) {
           ToolStripMenuItem menuItem;
           IEnumerable<Type> types = MainFormManager.GetViewTypes(item.GetType(), true);
@@ -79,10 +84,27 @@
             menuItem.Text = ViewAttribute.GetViewName(t);
 
-            this.menuItems.Add(t, menuItem);
-            this.Items.Add(menuItem);
+            menuItems.Add(t, menuItem);
+            Items.Add(menuItem);
           }
+          if (Items.Count > 0)
+            Items.Add(new ToolStripSeparator());
+          Items.Add(ShowBreadcrumbsToolStripMenuItem);
         }
       }
     }
+
+    public event EventHandler ShowBreadcrumbsChanged;
+    private void OnShowBreadcrumbsChanged() {
+      var handler = ShowBreadcrumbsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void ShowBreadcrumbsToolStripMenuItem_CheckedChanged(object sender, EventArgs e) {
+      OnShowBreadcrumbsChanged();
+    }
+
+    private void ShowBreadcrumbsToolStripMenuItem_Click(object sender, EventArgs e) {
+      ShowBreadcrumbsToolStripMenuItem.Checked = !ShowBreadcrumbsToolStripMenuItem.Checked;
+    }
   }
 }
Index: branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.Designer.cs
===================================================================
--- branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.Designer.cs	(revision 10041)
+++ branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.Designer.cs	(revision 10042)
@@ -52,4 +52,5 @@
       this.configurationLabel = new System.Windows.Forms.Label();
       this.helpLabel = new System.Windows.Forms.Label();
+      this.breadcrumbControl = new HeuristicLab.MainForm.WindowsForms.BreadcrumbControl();
       this.SuspendLayout();
       // 
@@ -86,4 +87,5 @@
       this.viewContextMenuStrip.Name = "viewContextMenuStrip";
       this.viewContextMenuStrip.Size = new System.Drawing.Size(61, 4);
+      this.viewContextMenuStrip.ShowBreadcrumbsChanged += new System.EventHandler(this.viewContextMenuStrip_ShowBreadcrumbsChanged);
       this.viewContextMenuStrip.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.viewContextMenuStrip_ItemClicked);
       // 
@@ -114,8 +116,18 @@
       this.helpLabel.DoubleClick += new System.EventHandler(this.helpLabel_DoubleClick);
       // 
+      // breadcrumbControl
+      // 
+      this.breadcrumbControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.breadcrumbControl.Location = new System.Drawing.Point(0, 0);
+      this.breadcrumbControl.Name = "breadcrumbControl";
+      this.breadcrumbControl.Size = new System.Drawing.Size(202, 15);
+      this.breadcrumbControl.TabIndex = 4;
+      this.breadcrumbControl.ViewHost = null;
+      // 
       // ViewHost
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.breadcrumbControl);
       this.Controls.Add(this.helpLabel);
       this.Controls.Add(this.viewsLabel);
@@ -124,4 +136,5 @@
       this.Name = "ViewHost";
       this.Size = new System.Drawing.Size(227, 184);
+      this.VisibleChanged += new System.EventHandler(this.ViewHost_VisibleChanged);
       this.ResumeLayout(false);
 
@@ -135,4 +148,5 @@
     private System.Windows.Forms.Label configurationLabel;
     private System.Windows.Forms.Label helpLabel;
+    private BreadcrumbControl breadcrumbControl;
 
   }
Index: branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.cs
===================================================================
--- branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.cs	(revision 10041)
+++ branches/Breadcrumbs/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ViewHost.cs	(revision 10042)
@@ -33,5 +33,5 @@
       InitializeComponent();
       startDragAndDrop = false;
-      viewContextMenuStrip.IgnoredViewTypes = new List<Type>() { typeof(ViewHost) };
+      viewContextMenuStrip.IgnoredViewTypes = new List<Type> { typeof(ViewHost) };
 
       viewType = null;
@@ -41,4 +41,6 @@
       viewsLabel.Visible = false;
       viewsLabelVisible = true;
+
+      breadcrumbControl.ViewHost = this;
     }
 
@@ -51,5 +53,5 @@
           viewsLabel.Visible = value;
           View view = activeView as View;
-          if (view != null) view.Dock = viewsLabelVisible ? DockStyle.None : DockStyle.Fill;
+          if (view != null) AdjustActiveViewSize();
         }
       }
@@ -87,5 +89,5 @@
             #endregion
 
-            this.Caption = activeView.Caption;
+            Caption = activeView.Caption;
             viewType = activeView.GetType();
             RegisterActiveViewEvents();
@@ -93,8 +95,5 @@
             if (view != null) {
               view.Visible = true;
-              if (ViewsLabelVisible) {
-                view.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
-                view.Size = new Size(Width - this.viewsLabel.Width - this.viewsLabel.Margin.Left - this.viewsLabel.Margin.Right, this.Height);
-              } else view.Dock = DockStyle.Fill;
+              AdjustActiveViewSize();
               if (!Controls.Contains((view))) Controls.Add(view);
               view.OnShown(new ViewShownEventArgs(view, false));
@@ -125,4 +124,12 @@
       }
     }
+
+    public bool ShowBreadcrumbs {
+      get { return viewContextMenuStrip.ShowBreadcrumbsToolStripMenuItem.Checked; }
+      set { viewContextMenuStrip.ShowBreadcrumbsToolStripMenuItem.Checked = value; }
+    }
+
+    private bool isOutmostViewHost;
+    public IEnumerable<IContent> Breadcrumbs { get { return breadcrumbControl.Breadcrumbs; } }
 
     protected override void SetEnabledStateOfControls() {
@@ -151,4 +158,5 @@
       UpdateLabels();
       UpdateActiveMenuItem();
+      UpdateBreadcrumbControl();
     }
 
@@ -201,4 +209,11 @@
       OnChanged();
     }
+    private void ViewHost_VisibleChanged(object sender, EventArgs e) {
+      PerformOuterViewHostDetection();
+    }
+    private void viewContextMenuStrip_ShowBreadcrumbsChanged(object sender, EventArgs e) {
+      UpdateBreadcrumbControl();
+      AdjustActiveViewSize();
+    }
 
     protected override void OnSizeChanged(EventArgs e) {
@@ -263,4 +278,10 @@
     }
 
+    private void UpdateBreadcrumbControl() {
+      breadcrumbControl.Visible = ShowBreadcrumbs;
+      if (ShowBreadcrumbs)
+        UpdateBreadcrumbTrail(breadcrumbControl.Breadcrumbs, BuildBreadcrumbTrail());
+    }
+
     private bool ViewCanShowContent(Type viewType, object content) {
       if (content == null) // every view can display null
@@ -274,6 +295,6 @@
       IContentView view = MainFormManager.MainForm.ShowContent(this.Content, this.ViewType);
       if (view != null) {
-        view.ReadOnly = this.ReadOnly;
-        view.Locked = this.Locked;
+        view.ReadOnly = ReadOnly;
+        view.Locked = Locked;
       }
     }
@@ -285,7 +306,7 @@
     private bool startDragAndDrop;
     private void viewsLabel_MouseDown(object sender, MouseEventArgs e) {
-      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
+      if (e.Button == MouseButtons.Right) {
         Screen screen = Screen.FromControl(viewsLabel);
-        int rightBorder = viewsLabel.PointToScreen(viewsLabel.Location).X + viewContextMenuStrip.Width; //
+        int rightBorder = viewsLabel.PointToScreen(viewsLabel.Location).X + viewContextMenuStrip.Width;
         rightBorder = rightBorder - screen.Bounds.X; //pixel position on active screen
 
@@ -319,4 +340,49 @@
     }
     #endregion
+
+    #region Helpers
+    private void AdjustActiveViewSize() {
+      var view = activeView as View;
+      if (view == null) return;
+      int width = viewsLabelVisible ? Width - viewsLabel.Width - viewsLabel.Margin.Left - viewsLabel.Margin.Right : Width;
+      int height = ShowBreadcrumbs ? Height - viewsLabel.Height - viewsLabel.Margin.Top - viewsLabel.Margin.Bottom : Height;
+      view.Location = new Point(0, Height - height);
+      view.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
+      view.Size = new Size(width, height);
+    }
+
+    private IEnumerable<IContent> BuildBreadcrumbTrail() {
+      var ll = new LinkedList<IContent>();
+      for (var control = (Control)this; control != null; control = control.Parent) {
+        var viewHost = control as ViewHost;
+        if (viewHost != null && viewHost.Content != null)
+          ll.AddFirst(viewHost.Content);
+      }
+      return ll;
+    }
+
+    public void UpdateBreadcrumbTrail(IEnumerable<IContent> oldCrumbs, IEnumerable<IContent> newCrumbs) {
+      if (!newCrumbs.Any()) return;
+      var ll = new LinkedList<IContent>();
+      foreach (var c in oldCrumbs) {
+        if (c != newCrumbs.First())
+          ll.AddLast(c);
+        else break;
+      }
+      foreach (var c in newCrumbs)
+        ll.AddLast(c);
+      breadcrumbControl.Breadcrumbs = ll;
+    }
+
+    private void PerformOuterViewHostDetection() {
+      var outmostViewHost = this;
+      for (var parent = Parent; parent != null; parent = parent.Parent) {
+        var vh = parent as ViewHost;
+        if (vh != null) outmostViewHost = vh;
+      }
+      isOutmostViewHost = outmostViewHost == this;
+      viewContextMenuStrip.ShowBreadcrumbsToolStripMenuItem.Checked = isOutmostViewHost;
+    }
+    #endregion
   }
 }
