changeset 63:536498832a79

Latest version before changing bindings to Listbox
author Steven Hollidge <stevenhollidge@hotmail.com>
date Sun, 22 Apr 2012 13:33:42 +0100
parents 810116cd6b8e
children ba89e36631bc
files .hgignore Glimpse/Glimpse Services/GlimpseService.vb Glimpse/Glimpse.vbproj SilverlightGlimpse/SilverFlow.Controls/Controllers/IResizableElement.cs SilverlightGlimpse/SilverFlow.Controls/Controllers/ISnapinController.cs SilverlightGlimpse/SilverFlow.Controls/Controllers/InertiaController.cs SilverlightGlimpse/SilverFlow.Controls/Controllers/InertialMotion.cs SilverlightGlimpse/SilverFlow.Controls/Controllers/ResizeController.cs SilverlightGlimpse/SilverFlow.Controls/Controllers/SnapinController.cs SilverlightGlimpse/SilverFlow.Controls/Converters/BooleanToVisibilityConverter.cs SilverlightGlimpse/SilverFlow.Controls/Enums/ResizeAnchor.cs SilverlightGlimpse/SilverFlow.Controls/Enums/WindowAction.cs SilverlightGlimpse/SilverFlow.Controls/Extensions/AnimationExtensions.cs SilverlightGlimpse/SilverFlow.Controls/Extensions/ControlExtensions.cs SilverlightGlimpse/SilverFlow.Controls/Extensions/GeometryExtensions.cs SilverlightGlimpse/SilverFlow.Controls/Extensions/MathExtensions.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/ActiveWindowChangedEventArgs.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/BootstrapButton.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindow.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindowHost.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/IconBar.cs SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/WindowIcon.cs SilverlightGlimpse/SilverFlow.Controls/Geometry/Distance.cs SilverlightGlimpse/SilverFlow.Controls/Geometry/Trail.cs SilverlightGlimpse/SilverFlow.Controls/Geometry/Vector2.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/BitmapHelper.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/IBitmapHelper.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/ILocalStorage.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/IVisualHelper.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/LocalStorage.cs SilverlightGlimpse/SilverFlow.Controls/Helpers/VisualHelper.cs SilverlightGlimpse/SilverFlow.Controls/Properties/AssemblyInfo.cs SilverlightGlimpse/SilverFlow.Controls/SilverFlow.Controls.csproj SilverlightGlimpse/SilverFlow.Controls/Themes/generic.xaml SilverlightGlimpse/SilverlightGlimpse.Test/App.xaml.cs SilverlightGlimpse/SilverlightGlimpse.Test/BuggyControl.xaml SilverlightGlimpse/SilverlightGlimpse.Test/BuggyControl.xaml.cs SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml.cs SilverlightGlimpse/SilverlightGlimpse.Test/SilverlightGlimpse.Test.csproj SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml.cs SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml.cs SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml.cs SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml.cs SilverlightGlimpse/SilverlightGlimpse/Services/GlimpseService.cs SilverlightGlimpse/SilverlightGlimpse/SilverlightGlimpse.csproj SilverlightValidation/SilverlightValidation.zip
diffstat 51 files changed, 7721 insertions(+), 230 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Apr 22 09:01:20 2012 +0100
+++ b/.hgignore	Sun Apr 22 13:33:42 2012 +0100
@@ -9,3 +9,4 @@
 */packages/*
 *.stats
 */Bin/*
+*/ClientBin/*
--- a/Glimpse/Glimpse Services/GlimpseService.vb	Sun Apr 22 09:01:20 2012 +0100
+++ b/Glimpse/Glimpse Services/GlimpseService.vb	Sun Apr 22 13:33:42 2012 +0100
@@ -86,9 +86,10 @@
         Me.RootVisual = TryCast(objApp.RootVisual, FrameworkElement)
         Me.HostApplicationName = strHostApplicationName
 
-        Dim fw As New ChildWindow
+        Dim fw As New FloatableWindow()
         fw.Title = Me.HostApplicationName
         fw.Content = New GlimpseViewer
+        fw.ParentLayoutRoot = DirectCast(VisualTreeHelper.GetChild(RootVisual, 0), Panel)
 
         If Double.IsNaN(Me.RootVisual.Width) Then
             'if the host control is autosized (consumes the browser window) then locate Glimpse in the top, left
@@ -103,7 +104,7 @@
                 dblLeft = 0
             End If
 
-            fw.Show()
+            fw.Show(dblLeft, 10)
         End If
 
     End Sub
--- a/Glimpse/Glimpse.vbproj	Sun Apr 22 09:01:20 2012 +0100
+++ b/Glimpse/Glimpse.vbproj	Sun Apr 22 13:33:42 2012 +0100
@@ -158,6 +158,12 @@
       <Install>true</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\SilverlightGlimpse\FloatableWindow\FloatableWindow.csproj">
+      <Project>{D47E6045-91BB-4CD0-942F-FF015F10F7F2}</Project>
+      <Name>FloatableWindow</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.VisualBasic.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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/IResizableElement.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,82 @@
+using System.Windows;
+using System.Windows.Input;
+
+namespace SilverFlow.Controls.Controllers
+{
+    /// <summary>
+    /// This interface shall be implemented by an element to be resized.
+    /// </summary>
+    public interface IResizableElement
+    {
+        /// <summary>
+        /// Gets or sets the width of the element.
+        /// </summary>
+        /// <value>The width.</value>
+        double Width { get; set; }
+
+        /// <summary>
+        /// Gets or sets the height of the element.
+        /// </summary>
+        /// <value>The height.</value>
+        double Height { get; set; }
+
+        /// <summary>
+        /// Gets or sets minimal width of the element.
+        /// </summary>
+        /// <value>Minimal width.</value>
+        double MinWidth { get; set; }
+
+        /// <summary>
+        /// Gets or sets minimal height of the element.
+        /// </summary>
+        /// <value>Minimal height.</value>
+        double MinHeight { get; set; }
+
+        /// <summary>
+        /// Gets or sets maximal width of the element.
+        /// </summary>
+        /// <value>Maximal width.</value>
+        double MaxWidth { get; set; }
+
+        /// <summary>
+        /// Gets or sets maximal height of the element.
+        /// </summary>
+        /// <value>Maximal height.</value>
+        double MaxHeight { get; set; }
+
+        /// <summary>
+        /// Gets the actual width.
+        /// </summary>
+        /// <value>The actual width.</value>
+        double ActualWidth { get; }
+
+        /// <summary>
+        /// Gets the actual height.
+        /// </summary>
+        /// <value>The actual height.</value>
+        double ActualHeight { get; }
+
+        /// <summary>
+        /// Gets or sets the position of the element.
+        /// </summary>
+        /// <value>The position.</value>
+        Point Position { get; set; }
+
+        /// <summary>
+        /// Gets the parent of the element.
+        /// </summary>
+        /// <value>The parent object.</value>
+        DependencyObject Parent { get; }
+
+        /// <summary>
+        /// Gets or sets the cursor of the element.
+        /// </summary>
+        /// <value>The cursor of the element.</value>
+        Cursor Cursor { get; set; }
+
+        /// <summary>
+        /// Snapin controller.
+        /// </summary>
+        ISnapinController SnapinController { get; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/ISnapinController.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,68 @@
+using System.Collections.Generic;
+using System.Windows;
+
+namespace SilverFlow.Controls.Controllers
+{
+    public interface ISnapinController
+    {
+        /// <summary>
+        /// Gets or sets a value indicating whether snap in is enabled.
+        /// </summary>
+        /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value>
+        bool SnapinEnabled { get; set; }
+
+        /// <summary>
+        /// Gets or sets snap in bounds.
+        /// </summary>
+        /// <value>Snap in bounds.</value>
+        IEnumerable<Rect> SnapinBounds { get; set; }
+
+        /// <summary>
+        /// Gets or sets snap in distance.
+        /// </summary>
+        /// <value>Snap in distance.</value>
+        double SnapinDistance { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value snap in margin - distance between adjacent edges.
+        /// </summary>
+        /// <value>Snap in margin.</value>
+        double SnapinMargin { get; set; }
+
+        /// <summary>
+        /// Returns new position of the specified rectangle
+        /// taking into account bounds the rectangle can be attracted to.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        Point SnapRectangle(Rect rect);
+
+        /// <summary>
+        /// Snaps the bottom right corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        Point SnapBottomRightCorner(Rect rect);
+
+        /// <summary>
+        /// Snaps the upper left corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        Point SnapTopLeftCorner(Rect rect);
+
+        /// <summary>
+        /// Snaps the lower left corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        Point SnapBottomLeftCorner(Rect rect);
+
+        /// <summary>
+        /// Snaps the upper right corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        Point SnapTopRightCorner(Rect rect);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/InertiaController.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media.Animation;
+using SilverFlow.Controls.Extensions;
+using SilverFlow.Geometry;
+
+namespace SilverFlow.Controls.Controllers
+{
+    /// <summary>
+    /// Calculates inertial motion of a dragged element.
+    /// </summary>
+    public class InertiaController
+    {
+        private const double SCREEN_DPI = 96;
+        private const double INCH = 0.0254;
+        private const double GRAVITATIONAL_ACCELERATION = 9.81;
+        private const double COEFFICIENT_OF_SLIDING_FRICTION = 0.015;
+        private const double MIN_DELTA = 0.001;
+        private const double DELAY_BEFORE_MOUSE_UP_IN_MILLISECONDS = 100;
+        private const int MAX_LAST_POINTS_TO_COUNT = 4;
+
+        private double pixelsPerMeter = SCREEN_DPI / INCH;
+
+        private Queue<Trail> mouseTrails = new Queue<Trail>();
+
+        /// <summary>
+        /// An element starts its motion.
+        /// </summary>
+        /// <param name="point">The starting point of the motion.</param>
+        public void StartMotion(Point point)
+        {
+            mouseTrails.Clear();
+            mouseTrails.Enqueue(new Trail(point, DateTime.Now));
+        }
+
+        /// <summary>
+        /// Saves the last position of the moved element.
+        /// </summary>
+        /// <param name="point">Current position.</param>
+        public void MoveToPoint(Point point)
+        {
+            while (mouseTrails.Count >= MAX_LAST_POINTS_TO_COUNT)
+            {
+                // Remove all points except the last ones
+                mouseTrails.Dequeue();
+            }
+
+            mouseTrails.Enqueue(new Trail(point, DateTime.Now));
+        }
+
+        /// <summary>
+        /// Gets inertial motion parameters: distance and duration.
+        /// </summary>
+        /// <param name="hostBounds">The host bounds.</param>
+        /// <param name="windowBounds">The window bounds.</param>
+        /// <returns>
+        /// The inertial motion parameters: distance and duration.
+        /// </returns>
+        public InertialMotion GetInertialMotionParameters(Rect hostBounds, Rect windowBounds)
+        {
+            if (mouseTrails.Count < 2) return null;
+
+            var mouseTrailsArray = mouseTrails.ToArray();
+
+            Point startPosition = mouseTrailsArray[0].Position;
+            DateTime startTime = mouseTrailsArray[0].Timestamp;
+            Point endPosition = mouseTrailsArray[mouseTrails.Count - 1].Position;
+            DateTime endTime = mouseTrailsArray[mouseTrails.Count - 1].Timestamp;
+
+            double timeBetweenNowAndLastMove = (DateTime.Now - endTime).TotalMilliseconds;
+            Vector2 vector = new Vector2(startPosition, endPosition);
+
+            if (timeBetweenNowAndLastMove < DELAY_BEFORE_MOUSE_UP_IN_MILLISECONDS && !vector.IsZero)
+            {
+                double time = (endTime - startTime).TotalSeconds;
+                time = (time == 0) ? 0.001 : time;
+
+                double distance = vector.Length / pixelsPerMeter;
+
+                double intialVelocity = distance / time;
+
+                double expectedDistance = ((intialVelocity * intialVelocity) / (2 * COEFFICIENT_OF_SLIDING_FRICTION * GRAVITATIONAL_ACCELERATION));
+                double expectedTime = (2 * expectedDistance) / intialVelocity;
+
+                double shiftX = Math.Round(vector.LengthX * expectedDistance / distance);
+                double shiftY = Math.Round(vector.LengthY * expectedDistance / distance);
+
+                // New Inertial Motion Vector
+                Vector2 imVector = new Vector2(endPosition, shiftX, shiftY).Round();
+                double expectedLength = imVector.Length;
+
+                Rect bounds = hostBounds.Add(-windowBounds.Width, -windowBounds.Height);
+
+                if (bounds.Contains(endPosition))
+                {
+                    imVector = EnsureEndPointInBounds(imVector, bounds).Round();
+                }
+                else if (hostBounds.Contains(endPosition))
+                {
+                    imVector = EnsureEndPointInBounds(imVector, hostBounds).Round();
+                }
+
+                // Reduce expected time if the Inertial Motion Vector was truncated by the bounds
+                double realTime = (expectedLength == 0) ? 0 : (expectedTime * imVector.Length / expectedLength);
+
+                var motion = new InertialMotion()
+                {
+                    Seconds = realTime,
+                    EndPosition = imVector.End,
+                    EasingFunction = new CubicEase()
+                    {
+                        EasingMode = EasingMode.EaseOut
+                    }
+                };
+
+                return motion;
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Ensures the end point is in bounds.
+        /// </summary>
+        /// <param name="vector">The vector to check its ending point.</param>
+        /// <param name="bounds">The bounds.</param>
+        /// <returns>A vector with the ending point within specified bounds.</returns>
+        private Vector2 EnsureEndPointInBounds(Vector2 vector, Rect bounds)
+        {
+            if (!vector.IsZero && !bounds.Contains(vector.End))
+            {
+                if (vector.IsVertical)
+                {
+                    vector.End = vector.End.EnsureInVerticalBounds(bounds);
+                }
+                else if (vector.IsHorizontal)
+                {
+                    vector.End = vector.End.EnsureInHorizontalBounds(bounds);
+                }
+                else
+                {
+                    double k = (vector.LengthY) / (vector.LengthX);
+                    Point point = vector.End;
+
+                    if (vector.End.X < bounds.Left || vector.End.X > bounds.Right)
+                    {
+                        point = point.EnsureInHorizontalBounds(bounds);
+                        point.Y = (k * (point.X - vector.Start.X)) + vector.Start.Y;
+                    }
+
+                    if (point.Y < bounds.Top || point.Y > bounds.Bottom)
+                    {
+                        point = point.EnsureInVerticalBounds(bounds);
+                        point.X = ((point.Y - vector.Start.Y) / k) + vector.Start.X;
+                    }
+
+                    vector.End = point.EnsureInBounds(bounds);
+                }
+            }
+
+            return vector;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/InertialMotion.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,37 @@
+using System.Windows;
+using System.Windows.Media.Animation;
+
+namespace SilverFlow.Controls.Controllers
+{
+    /// <summary>
+    /// Represents a vector and duration of the inertial motion, calculated by the InertiaController.
+    /// </summary>
+    public class InertialMotion
+    {
+        /// <summary>
+        /// Gets or sets ending position of the displaced element.
+        /// </summary>
+        /// <value>The ending position.</value>
+        public Point EndPosition { get; set; }
+
+        /// <summary>
+        /// Gets or sets duration of the inertial motion in seconds.
+        /// </summary>
+        /// <value>Duration of the inertial motion in seconds.</value>
+        public double Seconds { get; set; }
+
+        /// <summary>
+        /// Gets or sets the Easing Function applied to the animation.
+        /// </summary>
+        /// <value>The Easing Function.</value>
+        public IEasingFunction EasingFunction { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="InertialMotion"/> class.
+        /// </summary>
+        public InertialMotion()
+        {
+            this.Seconds = 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/ResizeController.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,453 @@
+using System;
+using System.Windows;
+using System.Windows.Input;
+using SilverFlow.Controls.Enums;
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Controls.Controllers
+{
+    /// <summary>
+    /// Calculates resizing element position and size.
+    /// </summary>
+    public class ResizeController
+    {
+        /// <summary>
+        /// Thickness of resizing area.
+        /// </summary>
+        private const double ResizingAreaDefaultValue = 6;
+
+        /// <summary>
+        /// Minimal width of the resized window if MinWidth is set to 0.
+        /// </summary>
+        private const double MinResizedWidth = 20;
+
+        /// <summary>
+        /// Resizing bounds, i.e. an area within which the resizing cursor can move.
+        /// </summary>
+        private Rect bounds;
+
+        /// <summary>
+        /// Initial element size when resizing started.
+        /// </summary>
+        private Size initialSize;
+
+        /// <summary>
+        /// Initial position of the element when resizing started.
+        /// </summary>
+        private Point initialPosition;
+
+        /// <summary>
+        /// A corner or edge of the element used for resizing.
+        /// </summary>
+        private ResizeAnchor anchor;
+
+        /// <summary>
+        /// An element implementing IResizableElement interface.
+        /// </summary>
+        private IResizableElement element;
+
+        /// <summary>
+        /// Gets a framework element hosting resizing element.
+        /// </summary>
+        /// <value>The host.</value>
+        private FrameworkElement Host
+        {
+            get
+            {
+                return element.Parent as FrameworkElement;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the resizing can be started.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if resizing can be started; otherwise, <c>false</c>.
+        /// </value>
+        public bool CanResize
+        {
+            get
+            {
+                return anchor != ResizeAnchor.None;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the width of the resizing area.
+        /// </summary>
+        /// <value>The width of the resizing area. Default value is 6.</value>
+        public double ResizingArea { get; set; }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance can be resized horizontally.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if this instance can be resized horizontally; otherwise, <c>false</c>.
+        /// </value>
+        private bool CanResizeHorizontally
+        {
+            get
+            {
+                return !(element.MinWidth == element.MaxWidth && element.MinWidth != 0);
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance can be resized vertically.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if this instance can be resized vertically; otherwise, <c>false</c>.
+        /// </value>
+        private bool CanResizeVertically
+        {
+            get
+            {
+                return !(element.MinHeight == element.MaxHeight && element.MinHeight != 0);
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ResizeController"/> class.
+        /// </summary>
+        /// <param name="resizableElement">The resizable element.</param>
+        public ResizeController(IResizableElement resizableElement)
+        {
+            if (resizableElement == null)
+                throw new ArgumentNullException("resizableElement");
+
+            element = resizableElement;
+            anchor = ResizeAnchor.None;
+            ResizingArea = ResizingAreaDefaultValue;
+        }
+
+        /// <summary>
+        /// Starts resizing of the element.
+        /// </summary>
+        public void StartResizing()
+        {
+            initialSize = new Size(element.ActualWidth, element.ActualHeight);
+            initialPosition = element.Position;
+
+            CalculateBoundsForResizing();
+        }
+
+        /// <summary>
+        /// Resizes the element.
+        /// </summary>
+        /// <param name="dx">Displacement by X-coordinate.</param>
+        /// <param name="dy">Displacement by Y-coordinate.</param>
+        public void Resize(double dx, double dy)
+        {
+            switch (anchor)
+            {
+                case ResizeAnchor.BottomRight:
+                    ResizeBottomRight(dx, dy);
+                    break;
+
+                case ResizeAnchor.Right:
+                    ResizeBottomRight(dx, 0);
+                    break;
+
+                case ResizeAnchor.Bottom:
+                    ResizeBottomRight(0, dy);
+                    break;
+
+                case ResizeAnchor.TopLeft:
+                    ResizeTopLeft(dx, dy);
+                    break;
+
+                case ResizeAnchor.Top:
+                    ResizeTopLeft(0, dy);
+                    break;
+
+                case ResizeAnchor.Left:
+                    ResizeTopLeft(dx, 0);
+                    break;
+
+                case ResizeAnchor.BottomLeft:
+                    ResizeBottomLeft(dx, dy);
+                    break;
+
+                case ResizeAnchor.TopRight:
+                    ResizeTopRight(dx, dy);
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Determines resizing anchor and sets appropriate Cursor.
+        /// </summary>
+        /// <param name="p">Coordinates of the mouse pointer.</param>
+        public void SetCursor(Point p)
+        {
+            if (p.Y < ResizingArea && p.X < ResizingArea)
+            {
+                anchor = ResizeAnchor.TopLeft;
+                element.Cursor = Cursors.SizeNWSE;
+            }
+            else if (p.Y < ResizingArea && p.X >= (element.ActualWidth - ResizingArea))
+            {
+                anchor = ResizeAnchor.TopRight;
+                element.Cursor = Cursors.SizeNESW;
+            }
+            else if (p.Y < ResizingArea)
+            {
+                if (CanResizeVertically)
+                {
+                    anchor = ResizeAnchor.Top;
+                    element.Cursor = Cursors.SizeNS;
+                }
+            }
+            else if (p.X < ResizingArea && p.Y >= (element.ActualHeight - ResizingArea))
+            {
+                anchor = ResizeAnchor.BottomLeft;
+                element.Cursor = Cursors.SizeNESW;
+            }
+            else if (p.X < ResizingArea)
+            {
+                if (CanResizeHorizontally)
+                {
+                    anchor = ResizeAnchor.Left;
+                    element.Cursor = Cursors.SizeWE;
+                }
+            }
+            else if (p.X >= (element.ActualWidth - ResizingArea) && p.Y >= (element.ActualHeight - ResizingArea))
+            {
+                anchor = ResizeAnchor.BottomRight;
+                element.Cursor = Cursors.SizeNWSE;
+            }
+            else if (p.X >= (element.ActualWidth - ResizingArea))
+            {
+                if (CanResizeHorizontally)
+                {
+                    anchor = ResizeAnchor.Right;
+                    element.Cursor = Cursors.SizeWE;
+                }
+            }
+            else if (p.Y >= (element.ActualHeight - ResizingArea))
+            {
+                if (CanResizeVertically)
+                {
+                    anchor = ResizeAnchor.Bottom;
+                    element.Cursor = Cursors.SizeNS;
+                }
+            }
+            else
+            {
+                anchor = ResizeAnchor.None;
+                element.Cursor = null;
+            }
+        }
+
+        /// <summary>
+        /// Calculates bounds for resizing.
+        /// </summary>
+        private void CalculateBoundsForResizing()
+        {
+            switch (anchor)
+            {
+                case ResizeAnchor.BottomRight:
+                case ResizeAnchor.Right:
+                case ResizeAnchor.Bottom:
+                    bounds = GetBoundsForLowerRightCorner();
+                    break;
+
+                case ResizeAnchor.TopLeft:
+                case ResizeAnchor.Top:
+                case ResizeAnchor.Left:
+                    bounds = GetBoundsForUpperLeftCorner();
+                    break;
+
+                case ResizeAnchor.BottomLeft:
+                    bounds = GetBoundsForLowerLeftCorner();
+                    break;
+
+                case ResizeAnchor.TopRight:
+                    bounds = GetBoundsForUpperRightCorner();
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// Calculates bounds for resizing by the lower right corner.
+        /// </summary>
+        /// <returns>Bounding rectangle.</returns>
+        private Rect GetBoundsForLowerRightCorner()
+        {
+            double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth;
+            double minHeight = element.MinHeight;
+
+            double maxWidth = Host.ActualWidth - initialPosition.X;
+
+            if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0)
+                maxWidth = Math.Min(maxWidth, element.MaxWidth);
+
+            double maxHeight = Host.ActualHeight - initialPosition.Y;
+            if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0)
+                maxHeight = Math.Min(maxHeight, element.MaxHeight);
+
+            Point p1 = initialPosition.Add(minWidth, minHeight);
+            Point p2 = initialPosition.Add(maxWidth, maxHeight);
+
+            return new Rect(p1, p2);
+        }
+
+        /// <summary>
+        /// Calculates bounds for resizing by the upper left corner.
+        /// </summary>
+        /// <returns>Bounding rectangle.</returns>
+        private Rect GetBoundsForUpperLeftCorner()
+        {
+            double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth;
+            double minHeight = element.MinHeight;
+
+            Point point = initialPosition.Add(initialSize);
+            double maxWidth = point.X;
+            double maxHeight = point.Y;
+
+            if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0)
+                maxWidth = Math.Min(maxWidth, element.MaxWidth);
+
+            if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0)
+                maxHeight = Math.Min(maxHeight, element.MaxHeight);
+
+            Point p1 = point.Add(-maxWidth, -maxHeight);
+            Point p2 = point.Add(-minWidth, -minHeight);
+
+            return new Rect(p1, p2);
+        }
+
+        /// <summary>
+        /// Calculates bounds for resizing by the lower left corner.
+        /// </summary>
+        /// <returns>Bounding rectangle.</returns>
+        private Rect GetBoundsForLowerLeftCorner()
+        {
+            double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth;
+            double minHeight = element.MinHeight;
+
+            Point point = initialPosition.Add(initialSize.Width, 0);
+            double maxWidth = point.X;
+
+            if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0)
+                maxWidth = Math.Min(maxWidth, element.MaxWidth);
+
+            double maxHeight = Host.ActualHeight - initialPosition.Y;
+            if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0)
+                maxHeight = Math.Min(maxHeight, element.MaxHeight);
+
+            Point p1 = point.Add(-maxWidth, minHeight);
+            Point p2 = point.Add(-minWidth, maxHeight);
+
+            return new Rect(p1, p2);
+        }
+
+        /// <summary>
+        /// Calculates bounds for resizing by the upper right corner.
+        /// </summary>
+        /// <returns>Bounding rectangle.</returns>
+        private Rect GetBoundsForUpperRightCorner()
+        {
+            double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth;
+            double minHeight = element.MinHeight;
+
+            Point point = initialPosition.Add(0, initialSize.Height);
+            double maxWidth = Host.ActualWidth - initialPosition.X;
+
+            if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0)
+                maxWidth = Math.Min(maxWidth, element.MaxWidth);
+
+            double maxHeight = point.Y;
+            if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0)
+                maxHeight = Math.Min(maxHeight, element.MaxHeight);
+
+            Point p1 = point.Add(minWidth, -maxHeight);
+            Point p2 = point.Add(maxWidth, -minHeight);
+
+            return new Rect(p1, p2);
+        }
+
+        /// <summary>
+        /// Resizes the window by the bottom right corner of the window.
+        /// </summary>
+        /// <param name="dx">Increment by X-coordinate.</param>
+        /// <param name="dy">Increment by Y-coordinate.</param>
+        private void ResizeBottomRight(double dx, double dy)
+        {
+            Rect newBounds = new Rect(initialPosition, initialSize.Add(dx, dy));
+            Point point = element.SnapinController.SnapBottomRightCorner(newBounds);
+
+            // If only one coordinate was changed - restore the other after snap in
+            if (dx == 0)
+                point.X = newBounds.BottomRight().X;
+
+            if (dy == 0)
+                point.Y = newBounds.BottomRight().Y;
+
+            point = point.EnsureInBounds(bounds);
+
+            element.Width = point.X - initialPosition.X;
+            element.Height = point.Y - initialPosition.Y;
+        }
+
+        /// <summary>
+        /// Resizes the window by the top left corner of the window.
+        /// </summary>
+        /// <param name="dx">Increment by X-coordinate.</param>
+        /// <param name="dy">Increment by Y-coordinate.</param>
+        private void ResizeTopLeft(double dx, double dy)
+        {
+            Rect newBounds = new Rect(initialPosition.Add(dx, dy), initialSize);
+            Point point = element.SnapinController.SnapTopLeftCorner(newBounds).EnsureInBounds(bounds);
+
+            // If only one coordinate was changed - restore the other after snap in
+            if (dx == 0)
+                point.X = newBounds.Position().X;
+
+            if (dy == 0)
+                point.Y = newBounds.Position().Y;
+
+            element.Position = point;
+
+            Point lowerRight = initialPosition.Add(initialSize);
+            element.Width = lowerRight.X - point.X;
+            element.Height = lowerRight.Y - point.Y;
+        }
+
+        /// <summary>
+        /// Resizes the window by the lower left corner of the window.
+        /// </summary>
+        /// <param name="dx">Increment by X-coordinate.</param>
+        /// <param name="dy">Increment by Y-coordinate.</param>
+        private void ResizeBottomLeft(double dx, double dy)
+        {
+            Rect newBounds = new Rect(initialPosition.Add(dx, 0), initialSize.Add(-dx, dy));
+
+            Point lowerLeft = element.SnapinController.SnapBottomLeftCorner(newBounds).EnsureInBounds(bounds);
+            Point topLeft = new Point(lowerLeft.X, initialPosition.Y);
+
+            element.Position = topLeft;
+
+            element.Width = initialSize.Width + initialPosition.X - topLeft.X;
+            element.Height = lowerLeft.Y - initialPosition.Y;
+        }
+
+        /// <summary>
+        /// Resizes the window by the top right corner of the window.
+        /// </summary>
+        /// <param name="dx">Increment by X-coordinate.</param>
+        /// <param name="dy">Increment by Y-coordinate.</param>
+        private void ResizeTopRight(double dx, double dy)
+        {
+            Rect newBounds = new Rect(initialPosition.Add(0, dy), initialSize.Add(dx, -dy));
+
+            Point topRight = element.SnapinController.SnapTopRightCorner(newBounds).EnsureInBounds(bounds);
+            Point topLeft = new Point(initialPosition.X, topRight.Y);
+
+            element.Position = topLeft;
+
+            element.Width = topRight.X - initialPosition.X;
+            element.Height = initialSize.Height + initialPosition.Y - topRight.Y;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Controllers/SnapinController.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,333 @@
+using System.Collections.Generic;
+using System.Windows;
+using SilverFlow.Controls.Extensions;
+using SilverFlow.Geometry;
+
+namespace SilverFlow.Controls.Controllers
+{
+    /// <summary>
+    /// Provides helpers methods for calculating window position 
+    /// during movement and resizing.
+    /// </summary>
+    public class SnapinController : ISnapinController
+    {
+        /// <summary>
+        /// Distance on which snapping works.
+        /// </summary>
+        private const double SnapinDistanceDefaultValue = 5;
+
+        /// <summary>
+        /// Gets or sets a value indicating whether snap in is enabled.
+        /// </summary>
+        /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value>
+        public bool SnapinEnabled { get; set; }
+
+        /// <summary>
+        /// Gets or sets snap in bounds.
+        /// </summary>
+        /// <value>Snap in bounds.</value>
+        public IEnumerable<Rect> SnapinBounds { get; set; }
+
+        /// <summary>
+        /// Gets or sets snap in distance.
+        /// </summary>
+        /// <value>Snap in distance.</value>
+        public double SnapinDistance { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value snap in margin - distance between adjacent edges.
+        /// </summary>
+        /// <value>Snap in margin.</value>
+        public double SnapinMargin { get; set; }
+
+        /// <summary>
+        /// Gets calculations accuracy.
+        /// </summary>
+        /// <value>Accuracy.</value>
+        private double Accuracy 
+        {
+            get { return SnapinDistance + SnapinMargin;  }
+        }
+
+        /// <summary>
+        /// Returns new position of the specified rectangle
+        /// taking into account bounds the rectangle can be attracted to.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        public Point SnapRectangle(Rect rect)
+        {
+            Point point = rect.Position();
+
+            if (SnapinEnabled)
+            {
+                Distance minDistance = new Distance();
+                foreach (var bound in SnapinBounds)
+                {
+                    Distance distance = DistanceBetweenRectangles(rect, bound);
+                    minDistance = Distance.Min(distance, minDistance);
+                }
+
+                point = point.Add(minDistance);
+            }
+
+            return point;
+        }
+
+        /// <summary>
+        /// Snaps the bottom right corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        public Point SnapBottomRightCorner(Rect rect)
+        {
+            Point point = rect.BottomRight();
+
+            if (SnapinEnabled)
+            {
+                Distance minDistance = new Distance();
+                foreach (var bound in SnapinBounds)
+                {
+                    Distance distance = new Distance()
+                    {
+                        X = DistanceBetweenRightEdgeAndRectangle(rect, bound),
+                        Y = DistanceBetweenBottomEdgeAndRectangle(rect, bound)
+                    };
+
+                    minDistance = Distance.Min(distance, minDistance);
+                }
+
+                point = point.Add(minDistance);
+            }
+
+            return point;
+        }
+
+        /// <summary>
+        /// Snaps the upper left corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        public Point SnapTopLeftCorner(Rect rect)
+        {
+            Point point = rect.Position();
+
+            if (SnapinEnabled)
+            {
+                Distance minDistance = new Distance();
+                foreach (var bound in SnapinBounds)
+                {
+                    Distance distance = new Distance()
+                    {
+                        X = DistanceBetweenLeftEdgeAndRectangle(rect, bound),
+                        Y = DistanceBetweenTopEdgeAndRectangle(rect, bound)
+                    };
+
+                    minDistance = Distance.Min(distance, minDistance);
+                }
+
+                point = point.Add(minDistance);
+            }
+
+            return point;
+        }
+
+        /// <summary>
+        /// Snaps the lower left corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        public Point SnapBottomLeftCorner(Rect rect)
+        {
+            Point point = rect.BottomLeft();
+
+            if (SnapinEnabled)
+            {
+                Distance minDistance = new Distance();
+                foreach (var bound in SnapinBounds)
+                {
+                    Distance distance = new Distance()
+                    {
+                        X = DistanceBetweenLeftEdgeAndRectangle(rect, bound),
+                        Y = DistanceBetweenBottomEdgeAndRectangle(rect, bound)
+                    };
+
+                    minDistance = Distance.Min(distance, minDistance);
+                }
+
+                point = point.Add(minDistance);
+            }
+
+            return point;
+        }
+
+        /// <summary>
+        /// Snaps the upper right corner of the specified rectangle to the nearest bounds.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <returns>New position.</returns>
+        public Point SnapTopRightCorner(Rect rect)
+        {
+            Point point = rect.TopRight();
+
+            if (SnapinEnabled)
+            {
+                Distance minDistance = new Distance();
+                foreach (var bound in SnapinBounds)
+                {
+                    Distance distance = new Distance()
+                    {
+                        X = DistanceBetweenRightEdgeAndRectangle(rect, bound),
+                        Y = DistanceBetweenTopEdgeAndRectangle(rect, bound)
+                    };
+
+                    minDistance = Distance.Min(distance, minDistance);
+                }
+
+                point = point.Add(minDistance);
+            }
+
+            return point;
+        }
+
+        /// <summary>
+        /// Returns mininal distance between two rectangles.
+        /// </summary>
+        /// <param name="first">First rectangle.</param>
+        /// <param name="second">Second rectangle.</param>
+        /// <returns>Minimal distance.</returns>
+        private Distance DistanceBetweenRectangles(Rect first, Rect second)
+        {
+            double x1 = DistanceBetweenRightEdgeAndRectangle(first, second);
+            double x2 = DistanceBetweenLeftEdgeAndRectangle(first, second);
+            double y1 = DistanceBetweenBottomEdgeAndRectangle(first, second);
+            double y2 = DistanceBetweenTopEdgeAndRectangle(first, second);
+
+            Distance distance = new Distance()
+            {
+                X = MathExtensions.AbsMin(x1, x2),
+                Y = MathExtensions.AbsMin(y1, y2)
+            };
+
+            return distance;
+        }
+
+        /// <summary>
+        /// Returns distance between the right edge of the rectangle and another rectangle.
+        /// </summary>
+        /// <param name="first">First rectangle.</param>
+        /// <param name="second">Second rectangle.</param>
+        /// <returns>Minimal distance.</returns>
+        private double DistanceBetweenRightEdgeAndRectangle(Rect first, Rect second)
+        {
+            double snap;
+            double distance = double.NaN;
+            double x = first.X + first.Width - 1;
+
+            if (first.OverlapsVertically(second, Accuracy))
+            {
+                snap = second.X - 1 - SnapinMargin;
+                if (x.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - x, distance);
+                }
+
+                snap = second.X + second.Width - 1;
+                if (x.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - x, distance);
+                }
+            }
+
+            return distance;
+        }
+
+        /// <summary>
+        /// Returns distance between the left edge of the rectangle and another rectangle.
+        /// </summary>
+        /// <param name="first">First rectangle.</param>
+        /// <param name="second">Second rectangle.</param>
+        /// <returns>Minimal distance.</returns>
+        private double DistanceBetweenLeftEdgeAndRectangle(Rect first, Rect second)
+        {
+            double snap;
+            double distance = double.NaN;
+
+            if (first.OverlapsVertically(second, Accuracy))
+            {
+                snap = second.X;
+                if (first.X.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - first.X, distance);
+                }
+
+                snap = second.X + second.Width + SnapinMargin;
+                if (first.X.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - first.X, distance);
+                }
+            }
+
+            return distance;
+        }
+
+        /// <summary>
+        /// Returns distance between the bottom edge of the rectangle and another rectangle.
+        /// </summary>
+        /// <param name="first">First rectangle.</param>
+        /// <param name="second">Second rectangle.</param>
+        /// <returns>Minimal distance.</returns>
+        private double DistanceBetweenBottomEdgeAndRectangle(Rect first, Rect second)
+        {
+            double snap;
+            double distance = double.NaN;
+            double y = first.Y + first.Height - 1;
+
+            if (first.OverlapsHorizontally(second, Accuracy))
+            {
+                snap = second.Y - 1 - SnapinMargin;
+                if (y.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - y, distance);
+                }
+
+                snap = second.Y + second.Height - 1;
+                if (y.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - y, distance);
+                }
+            }
+
+            return distance;
+        }
+
+        /// <summary>
+        /// Returns distance between the top edge of the rectangle and another rectangle.
+        /// </summary>
+        /// <param name="first">First rectangle.</param>
+        /// <param name="second">Second rectangle.</param>
+        /// <returns>Minimal distance.</returns>
+        private double DistanceBetweenTopEdgeAndRectangle(Rect first, Rect second)
+        {
+            double snap;
+            double distance = double.NaN;
+
+            if (first.OverlapsHorizontally(second, Accuracy))
+            {
+                snap = second.Y;
+                if (first.Y.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - first.Y, distance);
+                }
+
+                snap = second.Y + second.Height + SnapinMargin;
+                if (first.Y.IsNear(snap, SnapinDistance))
+                {
+                    distance = MathExtensions.AbsMin(snap - first.Y, distance);
+                }
+            }
+
+            return distance;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Converters/BooleanToVisibilityConverter.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,32 @@
+using System;
+using System.Windows;
+using System.Windows.Data;
+
+namespace SilverFlow.Controls.Converters
+{
+    public class BooleanToVisibilityConverter : IValueConverter
+    {
+        /// <summary>
+        /// Converts a boolean value to the display state of an element.
+        /// </summary>
+        /// <param name="value">The source data being passed to the target.</param>
+        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
+        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
+        /// <param name="culture">The culture of the conversion.</param>
+        /// <returns>
+        /// The value to be passed to the target dependency property.
+        /// </returns>
+        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            if (value == null)
+                throw new ArgumentNullException("value");
+
+            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Enums/ResizeAnchor.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,19 @@
+namespace SilverFlow.Controls.Enums
+{
+    /// <summary>
+    /// Defines window's border or a corner where the user 
+    /// clicked the mouse to start resizing.
+    /// </summary>
+    public enum ResizeAnchor
+    {
+        None = 0,
+        TopLeft = 1,
+        Top = 2,
+        TopRight = 3,
+        Right = 4,
+        BottomRight = 5,
+        Bottom = 6,
+        BottomLeft = 7,
+        Left = 9
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Enums/WindowAction.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,23 @@
+namespace SilverFlow.Controls.Enums
+{
+    /// <summary>
+    /// Defines mouse action.
+    /// </summary>
+    internal enum WindowAction
+    {
+        /// <summary>
+        /// Default
+        /// </summary>
+        None = 0,
+
+        /// <summary>
+        /// Moving the window
+        /// </summary>
+        Move = 1,
+
+        /// <summary>
+        /// Resizing the window
+        /// </summary>
+        Resize = 2
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Extensions/AnimationExtensions.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,163 @@
+using System;
+using System.Windows;
+using System.Windows.Media.Animation;
+
+namespace SilverFlow.Controls.Extensions
+{
+    /// <summary>
+    /// Useful Silverlight animation extensions
+    /// </summary>
+    public static class AnimationExtensions
+    {
+        /// <summary>
+        /// Animates specified property of the object.
+        /// </summary>
+        /// <param name="target">The target object to animate.</param>
+        /// <param name="propertyPath">Property path, e.g. Canvas.Top.</param>
+        /// <param name="from">Animation's starting value.</param>
+        /// <param name="to">Animation's ending value.</param>
+        /// <param name="milliseconds">Duration of the animation in milliseconds.</param>
+        /// <param name="easingFunction">Easing function applied to the animation.</param>
+        /// <param name="completed">Event handler called when animation completed.</param>
+        /// <returns>Returns started storyboard.</returns>
+        public static Storyboard AnimateDoubleProperty(this DependencyObject target, string propertyPath, double? from, double? to, double milliseconds,
+            IEasingFunction easingFunction = null, EventHandler completed = null)
+        {
+            Duration duration = new Duration(TimeSpan.FromMilliseconds(milliseconds));
+            DoubleAnimation doubleAnimation = new DoubleAnimation()
+            {
+                From = from,
+                To = to,
+                Duration = duration,
+                EasingFunction = easingFunction
+            };
+
+            Storyboard storyboard = new Storyboard();
+            storyboard.Duration = duration;
+            storyboard.Children.Add(doubleAnimation);
+
+            Storyboard.SetTarget(doubleAnimation, target);
+            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(propertyPath));
+
+            if (completed != null)
+                storyboard.Completed += completed;
+
+            storyboard.Begin();
+
+            return storyboard;
+        }
+
+        /// <summary>
+        /// Fade in the specified object.
+        /// </summary>
+        /// <param name="target">The target object.</param>
+        /// <param name="milliseconds">Duration of the animation in milliseconds.</param>
+        /// <param name="completed">Event handler called when animation completed.</param>
+        /// <returns>Returns started storyboard.</returns>
+        public static Storyboard FadeIn(this DependencyObject target, double milliseconds, EventHandler completed = null)
+        {
+            return AnimateDoubleProperty(target, "Opacity", 0, 1, milliseconds, null, completed);
+        }
+
+        /// <summary>
+        /// Fade out the specified object.
+        /// </summary>
+        /// <param name="target">The target object.</param>
+        /// <param name="milliseconds">Duration of the animation in milliseconds.</param>
+        /// <param name="completed">Event handler called when animation completed.</param>
+        /// <returns>Returns started storyboard.</returns>
+        public static Storyboard FadeOut(this DependencyObject target, double milliseconds, EventHandler completed = null)
+        {
+            return AnimateDoubleProperty(target, "Opacity", 1, 0, milliseconds, null, completed);
+        }
+
+        /// <summary>
+        /// Moves and resizes the object.
+        /// </summary>
+        /// <param name="target">The target object.</param>
+        /// <param name="position">Ending position.</param>
+        /// <param name="width">New width.</param>
+        /// <param name="height">New height.</param>
+        /// <param name="milliseconds">Duration of the animation in milliseconds.</param>
+        /// <param name="completed">Event handler called when animation completed.</param>
+        public static void MoveAndResize(this DependencyObject target, Point position, double width, double height,
+            double milliseconds, EventHandler completed = null)
+        {
+            Duration duration = new Duration(TimeSpan.FromMilliseconds(milliseconds));
+            DoubleAnimation doubleAnimation1 = new DoubleAnimation();
+            DoubleAnimation doubleAnimation2 = new DoubleAnimation();
+            PointAnimation pointAnimation = new PointAnimation();
+
+            doubleAnimation1.Duration = duration;
+            doubleAnimation2.Duration = duration;
+            pointAnimation.Duration = duration;
+
+            Storyboard storyboard = new Storyboard();
+            storyboard.Duration = duration;
+
+            storyboard.Children.Add(doubleAnimation1);
+            storyboard.Children.Add(doubleAnimation2);
+            storyboard.Children.Add(pointAnimation);
+
+            Storyboard.SetTarget(doubleAnimation1, target);
+            Storyboard.SetTarget(doubleAnimation2, target);
+            Storyboard.SetTarget(pointAnimation, target);
+
+            Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("(Width)"));
+            Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("(Height)"));
+            Storyboard.SetTargetProperty(pointAnimation, new PropertyPath("(Position)"));
+
+            doubleAnimation1.To = width;
+            if (!height.IsNotSet())
+                doubleAnimation2.To = height;
+
+            pointAnimation.To = position;
+
+            if (completed != null)
+                storyboard.Completed += completed;
+
+            storyboard.Begin();
+        }
+
+        /// <summary>
+        /// Animates the translate transform object, responsible for displacement of the target.
+        /// </summary>
+        /// <param name="target">The target object.</param>
+        /// <param name="storyboard">The storyboard.</param>
+        /// <param name="to">Animation's ending value.</param>
+        /// <param name="seconds">Duration of the animation in seconds.</param>
+        /// <param name="easingFunction">Easing function applied to the animation.</param>
+        public static void AnimateTranslateTransform(this DependencyObject target, Storyboard storyboard, Point to,
+            double seconds, IEasingFunction easingFunction = null)
+        {
+            Duration duration = new Duration(TimeSpan.FromSeconds(seconds));
+
+            DoubleAnimation doubleAnimationX = new DoubleAnimation()
+            {
+                To = to.X,
+                Duration = duration,
+                EasingFunction = easingFunction
+            };
+
+            DoubleAnimation doubleAnimationY = new DoubleAnimation()
+            {
+                To = to.Y,
+                Duration = duration,
+                EasingFunction = easingFunction
+            };
+
+            storyboard.Stop();
+            storyboard.Children.Clear();
+            storyboard.Duration = duration;
+            storyboard.Children.Add(doubleAnimationX);
+            storyboard.Children.Add(doubleAnimationY);
+
+            Storyboard.SetTarget(doubleAnimationX, target);
+            Storyboard.SetTarget(doubleAnimationY, target);
+            Storyboard.SetTargetProperty(doubleAnimationX, (target as UIElement).GetPropertyPathForTranslateTransformX());
+            Storyboard.SetTargetProperty(doubleAnimationY, (target as UIElement).GetPropertyPathForTranslateTransformY());
+
+            storyboard.Begin();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Extensions/ControlExtensions.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,230 @@
+using System;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace SilverFlow.Controls.Extensions
+{
+    /// <summary>
+    /// Useful Silverlight controls extensions
+    /// </summary>
+    public static class ControlExtensions
+    {
+        /// <summary>
+        /// Sets the visible of the UIElement.
+        /// </summary>
+        /// <param name="uiElement">The UI element.</param>
+        /// <param name="visible">Set Visible if <c>true</c>; otherwise - Collapsed.</param>
+        public static void SetVisible(this UIElement uiElement, bool visible = true)
+        {
+            if (uiElement != null)
+            {
+                uiElement.Visibility = (visible) ? Visibility.Visible : Visibility.Collapsed;
+            }
+        }
+
+        /// <summary>
+        /// Determines whether the specified UI element is visible.
+        /// </summary>
+        /// <param name="uiElement">The UI element.</param>
+        /// <returns><c>true</c> if the specified UI element is visible; otherwise, <c>false</c>.</returns>
+        public static bool IsVisible(this UIElement uiElement)
+        {
+            return uiElement != null && uiElement.Visibility == Visibility.Visible;
+        }
+
+        /// <summary>
+        /// Determines whether the specified element contains the point.
+        /// </summary>
+        /// <param name="element">This FrameworkElement.</param>
+        /// <param name="point">The point to check.</param>
+        /// <param name="origin">Relative origin (optional).</param>
+        /// <returns><c>true</c> if the specified element contains the point; otherwise, <c>false</c>.</returns>
+        public static bool ContainsPoint(this FrameworkElement element, Point point, UIElement origin = null)
+        {
+            bool result = false;
+
+            if (element != null)
+            {
+                Point elementOrigin = (origin == null) ? new Point(0, 0) : element.GetRelativePosition(origin);
+                Rect rect = new Rect(elementOrigin, new Size(element.ActualWidth, element.ActualHeight));
+                result = rect.Contains(point);
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// Gets position of the element relative to another specified (root) element.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <param name="rootElement">The root element.</param>
+        /// <returns>Relative position.</returns>
+        /// <exception cref="ArgumentNullException">Input parameter is null.</exception>
+        public static Point GetRelativePosition(this UIElement element, UIElement rootElement)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            if (rootElement == null)
+                throw new ArgumentNullException("rootElement");
+
+            var transformFromClientToRoot = element.TransformToVisual(rootElement);
+            return transformFromClientToRoot.Transform(new Point(0, 0));
+        }
+
+        /// <summary>
+        /// Gets total horizontal value of the specified thickness.
+        /// </summary>
+        /// <param name="thickness">The thickness.</param>
+        /// <returns>Horizontal thickness.</returns>
+        /// <exception cref="ArgumentNullException">Input parameter is null.</exception>
+        public static double Horizontal(this Thickness thickness)
+        {
+            if (thickness == null)
+                throw new ArgumentNullException("thickness");
+
+            return thickness.Left + thickness.Right;
+        }
+
+        /// <summary>
+        /// Gets total vertical value of the specified thickness.
+        /// </summary>
+        /// <param name="thickness">The thickness.</param>
+        /// <returns>Vertical thickness.</returns>
+        /// <exception cref="ArgumentNullException">Input parameter is null.</exception>
+        public static double Vertical(this Thickness thickness)
+        {
+            if (thickness == null)
+                throw new ArgumentNullException("thickness");
+
+            return thickness.Top + thickness.Bottom;
+        }
+
+        /// <summary>
+        /// Gets the actual bounding rectangle of the FrameworkElement.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <returns>Actual bounding rectangle.</returns>
+        public static Rect GetActualBoundingRectangle(this FrameworkElement element)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            return new Rect(0, 0, element.ActualWidth, element.ActualHeight);
+        }
+
+        /// <summary>
+        /// Gets a PropertyPath for the TranslateTransform.X property.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <returns>A path to the property.</returns>
+        public static PropertyPath GetPropertyPathForTranslateTransformX(this UIElement element)
+        {
+            return element.GetPropertyPathForTranslateTransform("X");
+        }
+
+        /// <summary>
+        /// Gets a PropertyPath for the TranslateTransform.Y property.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <returns>A path to the property.</returns>
+        public static PropertyPath GetPropertyPathForTranslateTransformY(this UIElement element)
+        {
+            return element.GetPropertyPathForTranslateTransform("Y");
+        }
+
+        /// <summary>
+        /// Gets scale factor to fit the element to the specified size.
+        /// </summary>
+        /// <param name="element">The element to scale.</param>
+        /// <param name="maxWidth">Maximal width of the element.</param>
+        /// <param name="maxHeight">Maximal height of the element.</param>
+        /// <returns>Scale factor required to fit the element to the specified size.</returns>
+        public static double GetScaleFactorToFit(this FrameworkElement element, double maxWidth, double maxHeight)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            double width = element.Width.IsNotSet() ? element.ActualWidth : element.Width;
+            double height = element.Height.IsNotSet() ? element.ActualHeight : element.Height;
+
+            double scaleX = maxWidth / width;
+            double scaleY = maxHeight / height;
+            double minScale = Math.Min(scaleX, scaleY);
+
+            return minScale;
+        }
+
+        /// <summary>
+        /// Moves the element to the new container. The container can be a Panel or a Border derived class.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <param name="newContainer">The new container of the element.</param>
+        /// <exception cref="ArgumentNullException">New Container is null.</exception>
+        public static void MoveToContainer(this FrameworkElement element, FrameworkElement newContainer)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            if (newContainer == null)
+                throw new ArgumentNullException("newContainer");
+
+            // Remove the element from the old container
+            element.RemoveFromContainer();
+
+            if (newContainer is Panel)
+            {
+                var container = newContainer as Panel;
+                if (!container.Children.Contains(element))
+                    container.Children.Add(element);
+            }
+            else if (newContainer is Border)
+            {
+                (newContainer as Border).Child = element;
+            }
+        }
+
+        /// <summary>
+        /// Removes the element from its container. The container can be a Panel or a Border derived class.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        public static void RemoveFromContainer(this FrameworkElement element)
+        {
+            if (element != null && element.Parent != null)
+            {
+                // Remove the element from the old container
+                if (element.Parent is Panel)
+                {
+                    (element.Parent as Panel).Children.Remove(element);
+                }
+                else if (element.Parent is Border)
+                {
+                    (element.Parent as Border).Child = null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets a PropertyPath for the TranslateTransform property.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        /// <param name="translateBy">"X" or "Y" TranslateTransform property.</param>
+        /// <returns>A path to the property.</returns>
+        private static PropertyPath GetPropertyPathForTranslateTransform(this UIElement element, string translateBy)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            var transformGroup = element.RenderTransform as TransformGroup;
+            var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
+            int translateTransformIndex = transformGroup.Children.IndexOf(translateTransform);
+
+            string path = string.Format("(FrameworkElement.RenderTransform).(TransformGroup.Children)[{0}].(TranslateTransform.{1})",
+                translateTransformIndex, translateBy);
+
+            return new PropertyPath(path);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Extensions/GeometryExtensions.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,292 @@
+using System;
+using System.Windows;
+using SilverFlow.Geometry;
+
+namespace SilverFlow.Controls.Extensions
+{
+    /// <summary>
+    /// Geometry extensions
+    /// </summary>
+    public static class GeometryExtensions
+    {
+        /// <summary>
+        /// Rounds the specified point to the nearest integer coordinates.
+        /// </summary>
+        /// <param name="point">The point to round coordinates.</param>
+        /// <returns>New point with rounded coordinates.</returns>
+        public static Point Round(this Point point)
+        {
+            return new Point(Math.Round(point.X), Math.Round(point.Y));
+        }
+
+        /// <summary>
+        /// Ensures that coordinates are positive.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <returns>Point with positive coordinates.</returns>
+        public static Point EnsurePositive(this Point point)
+        {
+            return new Point()
+            {
+                X = (point.X < 0) ? 0 : point.X,
+                Y = (point.Y < 0) ? 0 : point.Y
+            };
+        }
+
+        /// <summary>
+        /// Gets position of the specified rectangle.
+        /// </summary>
+        /// <param name="rect">Rectangle.</param>
+        /// <returns>Upper left corner of the rectangle.</returns>
+        public static Point Position(this Rect rect)
+        {
+            return new Point(rect.X, rect.Y);
+        }
+
+        /// <summary>
+        /// Gets position the lower right corner of the rectangle.
+        /// </summary>
+        /// <param name="rect">Rectangle.</param>
+        /// <returns>Lower right corner of the rectangle.</returns>
+        public static Point BottomRight(this Rect rect)
+        {
+            return new Point(rect.Right, rect.Bottom);
+        }
+
+        /// <summary>
+        /// Gets position the lower left corner of the rectangle.
+        /// </summary>
+        /// <param name="rect">Rectangle.</param>
+        /// <returns>Lower left corner of the rectangle.</returns>
+        public static Point BottomLeft(this Rect rect)
+        {
+            return new Point(rect.X, rect.Bottom);
+        }
+
+        /// <summary>
+        /// Gets position the upper right corner of the rectangle.
+        /// </summary>
+        /// <param name="rect">Rectangle.</param>
+        /// <returns>Upper right corner of the rectangle.</returns>
+        public static Point TopRight(this Rect rect)
+        {
+            return new Point(rect.Right, rect.Y);
+        }
+
+        /// <summary>
+        /// Ensures that coordinates of the point are in the specified bounds.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="bounds">The bounds.</param>
+        /// <returns>Point within the boinds.</returns>
+        public static Point EnsureInBounds(this Point point, Rect bounds)
+        {
+            return new Point()
+            {
+                X = point.X.EnsureInRange(bounds.X, bounds.Right),
+                Y = point.Y.EnsureInRange(bounds.Y, bounds.Bottom)
+            };
+        }
+
+        /// <summary>
+        /// Ensures that the X-coordinate of the point is in the specified horizontal bounds.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="bounds">The bounds.</param>
+        /// <returns>Point with the X-coordinate within the boinds.</returns>
+        public static Point EnsureInHorizontalBounds(this Point point, Rect bounds)
+        {
+            return new Point()
+            {
+                X = point.X.EnsureInRange(bounds.X, bounds.Right),
+                Y = point.Y
+            };
+        }
+
+        /// <summary>
+        /// Ensures that the Y-coordinate of the point is in the specified vertical bounds.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="bounds">The bounds.</param>
+        /// <returns>Point with the Y-coordinate within the boinds.</returns>
+        public static Point EnsureInVerticalBounds(this Point point, Rect bounds)
+        {
+            return new Point()
+            {
+                X = point.X,
+                Y = point.Y.EnsureInRange(bounds.Y, bounds.Bottom)
+            };
+        }
+
+        /// <summary>
+        /// Determines whether coordinates of the point are Not a Number (NaN).
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <returns>
+        /// <c>true</c> if coordinates are not specified; otherwise, <c>false</c>.
+        /// </returns>
+        public static bool IsNotSet(this Point point)
+        {
+            return double.IsNaN(point.X) || double.IsNaN(point.Y);
+        }
+
+        /// <summary>
+        /// Adds an offset to the specified point.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="x">Distance along X-coordinate.</param>
+        /// <param name="y">Distance along Y-coordinate.</param>
+        /// <returns>New point.</returns>
+        public static Point Add(this Point point, double x, double y)
+        {
+            return new Point(point.X + x, point.Y + y);
+        }
+
+        /// <summary>
+        /// Adds an offset specified by the Size to the specified point.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="size">Distance to add.</param>
+        /// <returns>New point</returns>
+        public static Point Add(this Point point, Size size)
+        {
+            return new Point(point.X + size.Width, point.Y + size.Height);
+        }
+
+        /// <summary>
+        /// Determines whether dimensions are Not a Number (NaN).
+        /// </summary>
+        /// <param name="size">The size.</param>
+        /// <returns>
+        /// <c>true</c> if dimensions are not specified; otherwise, <c>false</c>.
+        /// </returns>
+        public static bool IsNotSet(this Size size)
+        {
+            return double.IsNaN(size.Width) || double.IsNaN(size.Height);
+        }
+
+        /// <summary>
+        /// Increments size to the specified values.
+        /// </summary>
+        /// <param name="size">The size.</param>
+        /// <param name="x">Increment by X-coordinate.</param>
+        /// <param name="y">Increment by Y-coordinate.</param>
+        /// <returns>New size.</returns>
+        public static Size Add(this Size size, double x, double y)
+        {
+            double width = size.Width + x;
+            double height = size.Height + y;
+
+            return new Size()
+            {
+                Width = width < 0 ? 0 : width,
+                Height = height < 0 ? 0 : height
+            };
+        }
+
+        /// <summary>
+        /// Increases size if the rectangle to the specified width and height.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <param name="width">Value to add to the width of the rectangle.</param>
+        /// <param name="height">Value to add to the height of the rectangle.</param>
+        /// <returns>New rectangle.</returns>
+        public static Rect Add(this Rect rect, double width, double height)
+        {
+            return new Rect
+            {
+                X = rect.X,
+                Y = rect.Y,
+                Width = Math.Max(0, rect.Width + width),
+                Height = Math.Max(0, rect.Height + height)
+            };
+        }
+
+        /// <summary>
+        /// Shifts the point to the specified distance.
+        /// </summary>
+        /// <param name="point">The point.</param>
+        /// <param name="distance">The distance.</param>
+        /// <returns>Point shifted to the specified distance.</returns>
+        public static Point Add(this Point point, Distance distance)
+        {
+            return new Point()
+            {
+                X = distance.X.IsNotSet() ? point.X : point.X + distance.X,
+                Y = distance.Y.IsNotSet() ? point.Y : point.Y + distance.Y
+            };
+        }
+
+        /// <summary>
+        /// Tests whether the rectangle overlaps with another one vertically.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <param name="testRect">Test rectangle.</param>
+        /// <param name="accuracy">Accuracy.</param>
+        /// <returns><c>true</c> if overlaps vertically; otherwise, <c>false</c>.</returns>
+        public static bool OverlapsVertically(this Rect rect, Rect testRect, double accuracy = 0)
+        {
+            double y1 = rect.Y + rect.Height - 1;
+            double y2 = testRect.Y + testRect.Height - 1;
+
+            if (rect.Y <= testRect.Y)
+            {
+                return y1 >= (testRect.Y - accuracy); 
+            }
+            else if (rect.Y <= (y2 + accuracy))
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Tests whether the rectangle overlaps with another one horizontally.
+        /// </summary>
+        /// <param name="rect">The rectangle.</param>
+        /// <param name="testRect">Test rectangle.</param>
+        /// <param name="accuracy">Accuracy.</param>
+        /// <returns><c>true</c> if overlaps horizontally; otherwise, <c>false</c>.</returns>
+        public static bool OverlapsHorizontally(this Rect rect, Rect testRect, double accuracy = 0)
+        {
+            double x1 = rect.X + rect.Width - 1;
+            double x2 = testRect.X + testRect.Width - 1;
+
+            if (rect.X <= testRect.X)
+            {
+                return x1 >= (testRect.X - accuracy);
+            }
+            else if (rect.X <= (x2 + accuracy))
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Tests whether the point overlaps with the rectangle vertically.
+        /// </summary>
+        /// <param name="point">Test point.</param>
+        /// <param name="rect">Test rectangle.</param>
+        /// <param name="accuracy">Accuracy.</param>
+        /// <returns><c>true</c> if overlaps vertically; otherwise, <c>false</c>.</returns>
+        public static bool OverlapsVertically(this Point point, Rect rect, double accuracy = 0)
+        {
+            return (point.Y >= (rect.Y - accuracy) && point.Y <= (rect.Y + rect.Height - 1 + accuracy));
+        }
+
+        /// <summary>
+        /// Tests whether the point overlaps with the rectangle horizontally.
+        /// </summary>
+        /// <param name="point">Test point.</param>
+        /// <param name="rect">Test rectangle.</param>
+        /// <param name="accuracy">Accuracy.</param>
+        /// <returns><c>true</c> if overlaps horizontally; otherwise, <c>false</c>.</returns>
+        public static bool OverlapsHorizontally(this Point point, Rect rect, double accuracy = 0)
+        {
+            return (point.X >= (rect.X - accuracy) && point.X <= (rect.X + rect.Width - 1 + accuracy));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Extensions/MathExtensions.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,85 @@
+using System;
+
+namespace SilverFlow.Controls.Extensions
+{
+    /// <summary>
+    /// Math extensions
+    /// </summary>
+    public static class MathExtensions
+    {
+        /// <summary>
+        /// Determines whether the number is NaN.
+        /// </summary>
+        /// <param name="number">The number.</param>
+        /// <returns>
+        /// <c>true</c> if is NaN; otherwise, <c>false</c>.
+        /// </returns>
+        public static bool IsNotSet(this double number)
+        {
+            return double.IsNaN(number);
+        }
+
+        /// <summary>
+        /// Determines whether the specified number is near the test number.
+        /// </summary>
+        /// <param name="number">The number.</param>
+        /// <param name="testNumber">The test number.</param>
+        /// <param name="accuracy">Accuracy.</param>
+        /// <returns>
+        /// <c>true</c> if the specified number is near the testing one; otherwise, <c>false</c>.
+        /// </returns>
+        public static bool IsNear(this double number, double testNumber, double accuracy)
+        {
+            return number >= (testNumber - accuracy) && number <= (testNumber + accuracy);
+        }
+
+        /// <summary>
+        /// Compares two numbers without their signs and gets absolutely minimal value.
+        /// </summary>
+        /// <param name="num1">First number.</param>
+        /// <param name="num2">Second number.</param>
+        /// <returns>Absolutely minimal value.</returns>
+        public static double AbsMin(double num1, double num2)
+        {
+            if (num1.IsNotSet() && num2.IsNotSet())
+                return double.NaN;
+
+            if (num1.IsNotSet()) return num2;
+            if (num2.IsNotSet()) return num1;
+
+            double abs1 = Math.Abs(num1);
+            double abs2 = Math.Abs(num2);
+
+            if (abs1 < abs2) return num1;
+            if (abs2 < abs1) return num2;
+
+            // Abs. values are equal. Return first number
+            return num1;
+        }
+
+        /// <summary>
+        /// Ensures the given number is in the specified range.
+        /// </summary>
+        /// <param name="number">The number.</param>
+        /// <param name="low">The lower limit.</param>
+        /// <param name="high">The upper limit.</param>
+        /// <returns>A number in the specified range.</returns>
+        public static double EnsureInRange(this double number, double low, double high)
+        {
+            if (number.IsNotSet()) return double.NaN;
+
+            double result = Math.Max(number, low);
+            return Math.Min(result, high);
+        }
+
+        /// <summary>
+        /// Returns a double value if it is not a NAN, or zero.
+        /// </summary>
+        /// <param name="number">The number.</param>
+        /// <returns>Double value if it is not a NAN, or zero.</returns>
+        public static double ValueOrZero(this double number)
+        {
+            return double.IsNaN(number) ? 0 : number;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/ActiveWindowChangedEventArgs.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,31 @@
+using System;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// ActiveWindowChanged event arguments class.
+    /// </summary>
+    public class ActiveWindowChangedEventArgs : EventArgs
+    {
+        public FloatingWindow Old { get; set; }
+        public FloatingWindow New { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ActiveWindowChangedEventArgs"/> class.
+        /// </summary>
+        public ActiveWindowChangedEventArgs()
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ActiveWindowChangedEventArgs"/> class.
+        /// </summary>
+        /// <param name="oldWindow">The old active FloatingWindow.</param>
+        /// <param name="newWindow">The new active FloatingWindow.</param>
+        public ActiveWindowChangedEventArgs(FloatingWindow oldWindow, FloatingWindow newWindow)
+        {
+            this.Old = oldWindow;
+            this.New = newWindow;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/BootstrapButton.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,72 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// Two-state button with an up/down arrow.
+    /// </summary>
+    [TemplateVisualState(Name = VSMSTATE_StateClose, GroupName = VSMGROUP_ButtonStates)]
+    [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_ButtonStates)]
+    public class BootstrapButton : Button
+    {
+        // VSM groups
+        private const string VSMGROUP_ButtonStates = "ButtonStates";
+
+        // VSM states
+        private const string VSMSTATE_StateOpen = "Open";
+        private const string VSMSTATE_StateClose = "Close";
+
+        #region public bool IsOpen
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the bootstrap button is in the "Open" state.
+        /// </summary>
+        /// <value><c>true</c> if the bootstrap button is in the "Open" state; otherwise, <c>false</c>.</value>
+        public bool IsOpen
+        {
+            get { return (bool)GetValue(IsOpenProperty); }
+            set { SetValue(IsOpenProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="BootstrapButton.IsOpen" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="BootstrapButton.IsOpen" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IsOpenProperty =
+            DependencyProperty.Register(
+            "IsOpen",
+            typeof(bool),
+            typeof(BootstrapButton),
+            new PropertyMetadata(false, IsOpenPropertyChanged));
+
+        /// <summary>
+        /// IsOpenProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">BootstrapButton object whose IsOpenProperty property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void IsOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            BootstrapButton button = (BootstrapButton)d;
+            VisualStateManager.GoToState(
+                button,
+                (bool)e.NewValue ? VSMSTATE_StateClose : VSMSTATE_StateOpen, 
+                true);
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Raises the <see cref="E:System.Windows.Controls.Primitives.ButtonBase.Click"/> event.
+        /// </summary>
+        protected override void OnClick()
+        {
+            // Toggle open/closed state
+            IsOpen = !IsOpen;
+
+            base.OnClick();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindow.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,2210 @@
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using SilverFlow.Controls.Controllers;
+using SilverFlow.Controls.Enums;
+using SilverFlow.Controls.Extensions;
+using SilverFlow.Controls.Helpers;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// Provides a window that can be displayed over a parent window not blocking
+    /// interaction with the parent window.
+    /// </summary>
+    [TemplatePart(Name = PART_Chrome, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_TitleContent, Type = typeof(ContentControl))]
+    [TemplatePart(Name = PART_CloseButton, Type = typeof(ButtonBase))]
+    [TemplatePart(Name = PART_ContentPresenter, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_ContentBorder, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_Root, Type = typeof(FrameworkElement))]
+    [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_Window)]
+    [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_Window)]
+    [TemplateVisualState(Name = VSMSTATE_StateMinimized, GroupName = VSMGROUP_Window)]
+    [TemplateVisualState(Name = VSMSTATE_StateRestored, GroupName = VSMGROUP_Window)]
+    [TemplateVisualState(Name = VSMSTATE_StateNormal, GroupName = VSMGROUP_Button)]
+    [StyleTypedProperty(Property = PROPERTY_TitleStyle, StyleTargetType = typeof(ContentControl))]
+    [StyleTypedProperty(Property = PROPERTY_CloseButtonStyle, StyleTargetType = typeof(Button))]
+    [StyleTypedProperty(Property = PROPERTY_MinimizeButtonStyle, StyleTargetType = typeof(Button))]
+    [StyleTypedProperty(Property = PROPERTY_MaximizeButtonStyle, StyleTargetType = typeof(Button))]
+    [StyleTypedProperty(Property = PROPERTY_RestoreButtonStyle, StyleTargetType = typeof(Button))]
+    public class FloatingWindow : ContentControl, IResizableElement, IDisposable
+    {
+        #region Constants
+
+        // Template parts
+        private const string PART_Chrome = "Chrome";
+        private const string PART_TitleContent = "TitleContent";
+        private const string PART_CloseButton = "CloseButton";
+        private const string PART_MaximizeButton = "MaximizeButton";
+        private const string PART_RestoreButton = "RestoreButton";
+        private const string PART_MinimizeButton = "MinimizeButton";
+        private const string PART_ContentPresenter = "ContentPresenter";
+        private const string PART_ContentRoot = "ContentRoot";
+        private const string PART_ContentBorder = "ContentBorder";
+        private const string PART_Root = "Root";
+
+        // VSM groups
+        private const string VSMGROUP_Window = "WindowStates";
+        private const string VSMGROUP_Button = "CommonStates";
+
+        // VSM states
+        private const string VSMSTATE_StateNormal = "Normal";
+        private const string VSMSTATE_StateClosed = "Closed";
+        private const string VSMSTATE_StateOpen = "Open";
+        private const string VSMSTATE_StateMinimized = "Minimized";
+        private const string VSMSTATE_StateRestored = "Restored";
+
+        // Style typed properties
+        private const string PROPERTY_TitleStyle = "TitleStyle";
+        private const string PROPERTY_CloseButtonStyle = "CloseButtonStyle";
+        private const string PROPERTY_MinimizeButtonStyle = "MinimizeButtonStyle";
+        private const string PROPERTY_MaximizeButtonStyle = "MaximizeButtonStyle";
+        private const string PROPERTY_RestoreButtonStyle = "RestoreButtonStyle";
+
+        // Thickness of resizing area
+        private const double ResizingAreaDefaultValue = 6;
+
+        // Animation duration in milliseconds
+        private const double MaximizingDurationInMilliseconds = 20;
+        private const double MinimizingDurationInMilliseconds = 200;
+        private const double RestoringDurationInMilliseconds = 20;
+
+        #endregion
+
+        #region public bool ShowCloseButton
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show Close button.
+        /// </summary>
+        /// <value><c>true</c> if to show Close button; otherwise, <c>false</c>.</value>
+        public bool ShowCloseButton
+        {
+            get { return (bool)GetValue(ShowCloseButtonProperty); }
+            set { SetValue(ShowCloseButtonProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ShowCloseButton" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ShowCloseButton" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowCloseButtonProperty =
+            DependencyProperty.Register(
+            "ShowCloseButton",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, OnShowCloseButtonPropertyChanged));
+
+        /// <summary>
+        /// ShowCloseButtonProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose ShowCloseButton property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void OnShowCloseButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+
+            if (window.closeButton != null)
+                window.closeButton.SetVisible((bool)e.NewValue);
+        }
+
+        #endregion
+
+        #region public bool ShowMaximizeButton
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show Maximize button.
+        /// </summary>
+        /// <value><c>true</c> if to show Maximize button; otherwise, <c>false</c>.</value>
+        public bool ShowMaximizeButton
+        {
+            get { return (bool)GetValue(ShowMaximizeButtonProperty); }
+            set { SetValue(ShowMaximizeButtonProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ShowMaximizeButton" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ShowMaximizeButton" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowMaximizeButtonProperty =
+            DependencyProperty.Register(
+            "ShowMaximizeButton",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, ShowMaximizeButtonPropertyChanged));
+
+        /// <summary>
+        /// ShowMaximizeButtonProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose ShowMaximizeButton property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void ShowMaximizeButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+            bool visible = window.IsModal ? false : (bool)e.NewValue;
+
+            if (window.maximizeButton != null)
+                window.maximizeButton.SetVisible(visible);
+        }
+
+        #endregion
+
+        #region public bool ShowMinimizeButton
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show Minimize button.
+        /// </summary>
+        /// <value><c>true</c> if to show Minimize button; otherwise, <c>false</c>.</value>
+        public bool ShowMinimizeButton
+        {
+            get { return (bool)GetValue(ShowMinimizeButtonProperty); }
+            set { SetValue(ShowMinimizeButtonProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ShowMinimizeButton" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ShowMinimizeButton" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowMinimizeButtonProperty =
+            DependencyProperty.Register(
+            "ShowMinimizeButton",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, ShowMinimizeButtonPropertyChanged));
+
+        /// <summary>
+        /// ShowMinimizeButtonProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose ShowMinimizeButton property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void ShowMinimizeButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+            bool visible = window.IsModal ? false : (bool)e.NewValue;
+
+            if (window.minimizeButton != null)
+                window.minimizeButton.SetVisible(visible);
+        }
+
+        #endregion
+
+        #region public bool ShowRestoreButton
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show Restore button.
+        /// </summary>
+        /// <value><c>true</c> if to show Restore button; otherwise, <c>false</c>.</value>
+        public bool ShowRestoreButton
+        {
+            get { return (bool)GetValue(ShowRestoreButtonProperty); }
+            set { SetValue(ShowRestoreButtonProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ShowRestoreButton" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ShowRestoreButton" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowRestoreButtonProperty =
+            DependencyProperty.Register(
+            "ShowRestoreButton",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, ShowRestoreButtonPropertyChanged));
+
+        /// <summary>
+        /// ShowRestoreButtonProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose ShowRestoreButton property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void ShowRestoreButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+            bool visible = window.IsModal ? false : (bool)e.NewValue;
+
+            if (window.restoreButton != null)
+                window.restoreButton.SetVisible(visible);
+        }
+
+        #endregion
+
+        #region public object Title
+
+        /// <summary>
+        /// Gets or sets title content that is displayed on the top of the window. 
+        /// Can contain any UI elements - not only a text.
+        /// </summary>
+        /// <value>
+        /// The title displayed at the top of the window. The default is null.
+        /// </value>
+        public object Title
+        {
+            get { return GetValue(TitleProperty); }
+            set { SetValue(TitleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.Title" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.Title" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty TitleProperty =
+            DependencyProperty.Register(
+            "Title",
+            typeof(object),
+            typeof(FloatingWindow),
+            null);
+
+        #endregion
+
+        #region public object Icon
+
+        /// <summary>
+        /// Gets or sets content that is displayed as an icon of the window on the iconbar. 
+        /// </summary>
+        /// <value>
+        /// The content displayed as an icon of the window on the iconbar. The default is null.
+        /// </value>
+        public object Icon
+        {
+            get { return GetValue(IconProperty); }
+            set { SetValue(IconProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.Icon" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.Icon" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconProperty =
+            DependencyProperty.Register(
+            "Icon",
+            typeof(object),
+            typeof(FloatingWindow),
+            null);
+
+        #endregion
+
+        #region public string IconText
+
+        /// <summary>
+        /// Gets or sets a text displayed on the icon of the minimized window.
+        /// </summary>
+        /// <value>
+        /// The text displayed on the icon.
+        /// </value>
+        public string IconText
+        {
+            get { return (string)GetValue(IconTextProperty); }
+            set { SetValue(IconTextProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.IconText" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.IconText" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconTextProperty =
+            DependencyProperty.Register(
+            "IconText",
+            typeof(string),
+            typeof(FloatingWindow),
+            null);
+
+        #endregion
+
+        #region public Brush TitleBackground
+
+        /// <summary>
+        /// Gets or sets the title background.
+        /// </summary>
+        /// <value>The title background.</value>
+        public Brush TitleBackground
+        {
+            get { return (Brush)GetValue(TitleBackgroundProperty); }
+            set { SetValue(TitleBackgroundProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.TitleBackground" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.TitleBackground" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty TitleBackgroundProperty =
+            DependencyProperty.Register(
+            "TitleBackground",
+            typeof(Brush),
+            typeof(FloatingWindow),
+            new PropertyMetadata(new SolidColorBrush(Colors.Transparent), null));
+
+        #endregion
+
+        #region public bool ResizeEnabled
+
+        /// <summary>
+        /// Gets or sets a value indicating whether resizing is enabled.
+        /// </summary>
+        /// <value><c>true</c> if resizing is enabled; otherwise, <c>false</c>.</value>
+        public bool ResizeEnabled
+        {
+            get { return (bool)GetValue(ResizeEnabledProperty); }
+            set { SetValue(ResizeEnabledProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ResizeEnabled" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ResizeEnabled" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ResizeEnabledProperty =
+            DependencyProperty.Register(
+            "ResizeEnabled",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, null));
+
+        #endregion
+
+        #region public double ResizingAreaThickness
+
+        /// <summary>
+        /// Gets or sets the width of the resizing area.
+        /// </summary>
+        /// <value>The width of the resizing area.</value>
+        public double ResizingAreaThickness
+        {
+            get { return (double)GetValue(ResizingAreaThicknessProperty); }
+            set { SetValue(ResizingAreaThicknessProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ResizingAreaThickness" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ResizingAreaThickness" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ResizingAreaThicknessProperty =
+            DependencyProperty.Register(
+            "ResizingAreaThickness",
+            typeof(double),
+            typeof(FloatingWindow),
+            new PropertyMetadata(ResizingAreaDefaultValue, OnResizingAreaThicknessPropertyChanged));
+
+        /// <summary>
+        /// ResizingAreaThicknessProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose ResizingAreaThickness property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void OnResizingAreaThicknessPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+            window.resizeController.ResizingArea = (double)e.NewValue;
+        }
+
+        #endregion
+
+        #region public Point Position
+
+        /// <summary>
+        /// Gets or sets current window position.
+        /// </summary>
+        /// <value>Current position.</value>
+        public Point Position
+        {
+            get { return (Point)GetValue(PositionProperty); }
+            set { SetValue(PositionProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.Position" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.Position" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty PositionProperty =
+            DependencyProperty.Register(
+            "Position",
+            typeof(Point),
+            typeof(FloatingWindow),
+            new PropertyMetadata(new Point(double.NaN, double.NaN), OnPositionPropertyChanged));
+
+        /// <summary>
+        /// PositionProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose Position property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void OnPositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+
+            if (window != null)
+            {
+                if (window.FloatingWindowHost.IsLayoutUpdated)
+                    window.MoveWindow((Point)e.NewValue);
+            }
+        }
+
+        #endregion
+
+        #region public bool ShowInIconbar
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show minimized window in the iconbar.
+        /// </summary>
+        /// <value><c>true</c> if to show minimized window in the iconbar; otherwise, <c>false</c>.</value>
+        public bool ShowInIconbar
+        {
+            get { return (bool)GetValue(ShowInIconbarProperty); }
+            set { SetValue(ShowInIconbarProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.ShowInIconbar" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.ShowInIconbar" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowInIconbarProperty =
+            DependencyProperty.Register(
+            "ShowInIconbar",
+            typeof(bool),
+            typeof(FloatingWindow),
+            new PropertyMetadata(true, null));
+
+        #endregion
+
+        #region public FlowDirection FlowDirection
+
+        /// <summary>
+        /// Gets or sets the direction that title text flows within window's icon.
+        /// </summary>
+        /// <value>A constant name from the FlowDirection enumeration, either LeftToRight or RightToLeft.</value>
+        public FlowDirection FlowDirection
+        {
+            get { return (FlowDirection)GetValue(FlowDirectionProperty); }
+            set { SetValue(FlowDirectionProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.FlowDirection" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindow.FlowDirection" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty FlowDirectionProperty =
+            DependencyProperty.Register(
+            "FlowDirection",
+            typeof(FlowDirection),
+            typeof(FloatingWindow),
+            new PropertyMetadata(FlowDirection.LeftToRight, null));
+
+        #endregion
+
+        #region public Style TitleStyle
+
+        /// <summary>
+        /// Gets or sets the style that is used when rendering the Title of the window.
+        /// </summary>
+        public Style TitleStyle
+        {
+            get { return GetValue(TitleStyleProperty) as Style; }
+            set { SetValue(TitleStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.TitleStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty TitleStyleProperty =
+            DependencyProperty.Register(
+                "TitleStyle",
+                typeof(Style),
+                typeof(FloatingWindow),
+                new PropertyMetadata(OnTitleStylePropertyChanged));
+
+        /// <summary>
+        /// TitleStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose TitleStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void OnTitleStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindow window = (FloatingWindow)d;
+            if (window != null && window.titleContent != null)
+            {
+                Style style = e.NewValue as Style;
+                window.titleContent.Style = style;
+            }
+        }
+
+        #endregion
+
+        #region public Style CloseButtonStyle
+
+        /// <summary>
+        /// Gets or sets the style of the Close button.
+        /// </summary>
+        public Style CloseButtonStyle
+        {
+            get { return GetValue(CloseButtonStyleProperty) as Style; }
+            set { SetValue(CloseButtonStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.CloseButtonStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty CloseButtonStyleProperty =
+            DependencyProperty.Register(
+                "CloseButtonStyle",
+                typeof(Style),
+                typeof(FloatingWindow),
+                new PropertyMetadata(OnCloseButtonStylePropertyChanged));
+
+        /// <summary>
+        /// CloseButtonStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose CloseButtonStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void OnCloseButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var window = (FloatingWindow)d;
+            if (window != null)
+            {
+                Style style = e.NewValue as Style;
+                window.CloseButtonStyle = style;
+
+                if (window.closeButton != null)
+                    window.closeButton.Style = style;
+            }
+        }
+
+        #endregion
+
+        #region public Style MinimizeButtonStyle
+
+        /// <summary>
+        /// Gets or sets the style of the Minimize button.
+        /// </summary>
+        public Style MinimizeButtonStyle
+        {
+            get { return GetValue(MinimizeButtonStyleProperty) as Style; }
+            set { SetValue(MinimizeButtonStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.MinimizeButtonStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty MinimizeButtonStyleProperty =
+            DependencyProperty.Register(
+                "MinimizeButtonStyle",
+                typeof(Style),
+                typeof(FloatingWindow),
+                new PropertyMetadata(OnMinimizeButtonStylePropertyChanged));
+
+        /// <summary>
+        /// CloseButtonStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose MinimizeButtonStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void OnMinimizeButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var window = (FloatingWindow)d;
+            if (window != null)
+            {
+                Style style = e.NewValue as Style;
+                window.CloseButtonStyle = style;
+
+                if (window.minimizeButton != null)
+                    window.minimizeButton.Style = style;
+            }
+        }
+
+        #endregion
+
+        #region public Style MaximizeButtonStyle
+
+        /// <summary>
+        /// Gets or sets the style of the Maximize button.
+        /// </summary>
+        public Style MaximizeButtonStyle
+        {
+            get { return GetValue(MaximizeButtonStyleProperty) as Style; }
+            set { SetValue(MaximizeButtonStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.MaximizeButtonStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty MaximizeButtonStyleProperty =
+            DependencyProperty.Register(
+                "MaximizeButtonStyle",
+                typeof(Style),
+                typeof(FloatingWindow),
+                new PropertyMetadata(OnMaximizeButtonStylePropertyChanged));
+
+        /// <summary>
+        /// MaximizeButtonStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose MaximizeButtonStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void OnMaximizeButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var window = (FloatingWindow)d;
+            if (window != null)
+            {
+                Style style = e.NewValue as Style;
+                window.CloseButtonStyle = style;
+
+                if (window.maximizeButton != null)
+                    window.maximizeButton.Style = style;
+            }
+        }
+
+        #endregion
+
+        #region public Style RestoreButtonStyle
+
+        /// <summary>
+        /// Gets or sets the style of the Restore button.
+        /// </summary>
+        public Style RestoreButtonStyle
+        {
+            get { return GetValue(RestoreButtonStyleProperty) as Style; }
+            set { SetValue(RestoreButtonStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindow.RestoreButtonStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty RestoreButtonStyleProperty =
+            DependencyProperty.Register(
+                "RestoreButtonStyle",
+                typeof(Style),
+                typeof(FloatingWindow),
+                new PropertyMetadata(OnRestoreButtonStylePropertyChanged));
+
+        /// <summary>
+        /// RestoreButtonStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindow object whose RestoreButtonStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void OnRestoreButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var window = (FloatingWindow)d;
+            if (window != null)
+            {
+                Style style = e.NewValue as Style;
+                window.CloseButtonStyle = style;
+
+                if (window.restoreButton != null)
+                    window.restoreButton.Style = style;
+            }
+        }
+
+        #endregion
+
+        #region public bool? DialogResult
+
+        /// <summary>
+        /// Gets or sets a value that indicates whether the FloatingWindow was accepted or canceled.
+        /// </summary>
+        /// <value>true if the FloatingWindow was accepted; false - if canceled. The default is null.</value>
+        [TypeConverter(typeof(NullableBoolConverter))]
+        public bool? DialogResult { get; set; }
+
+        #endregion
+
+        #region Member Fields
+
+        // Mouse click point
+        private Point clickPoint;
+
+        // Window position when the mouse was clicked
+        private Point clickWindowPosition;
+
+        // Window position, size and state when it was maximized or minimized
+        private Point previousPosition;
+        private Size previousSize;
+        private WindowState previousWindowState;
+
+        private Thickness contentBorderThickness;
+        private CornerRadius contentBorderCornerRadius;
+        private CornerRadius chromeBorderCornerRadius;
+
+        private Storyboard openingStoryboard;
+        private Storyboard closingStoryboard;
+        private Storyboard inertialMotionStoryboard;
+
+        private FrameworkElement root;
+        private FrameworkElement contentPresenter;
+        private FrameworkElement contentRoot;
+        private FrameworkElement chrome;
+        private ContentControl titleContent;
+        private Border contentBorder;
+
+        private ButtonBase closeButton;
+        private ButtonBase maximizeButton;
+        private ButtonBase restoreButton;
+        private ButtonBase minimizeButton;
+
+        private bool isAppExit;
+        private bool isMouseCaptured;
+
+        private ResizeController resizeController;
+        private ISnapinController snapinController;
+        private InertiaController inertiaController;
+        private ILocalStorage localStorage;
+        private IBitmapHelper bitmapHelper;
+
+        // Current window state
+        private WindowState windowState = WindowState.Normal;
+
+        // Specifies whether the window is moving or resizing
+        private WindowAction windowAction;
+
+        // Bitmap containing thumbnail image
+        private ImageSource minimizedWindowThumbnail;
+
+        #endregion Member Fields
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FloatingWindow" /> class.
+        /// </summary>
+        public FloatingWindow()
+        {
+            DefaultStyleKey = typeof(FloatingWindow);
+
+            resizeController = new ResizeController(this);
+            resizeController.ResizingArea = ResizingAreaThickness;
+            snapinController = new SnapinController();
+            inertiaController = new InertiaController();
+            localStorage = new LocalStorage();
+            bitmapHelper = new BitmapHelper();
+
+            this.SetVisible(false);
+        }
+
+        #region Events
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is activated.
+        /// </summary>
+        /// <remarks>Not visible <see cref="FloatingWindow" /> cannot be the active. </remarks>
+        public event EventHandler Activated;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is deactivated.
+        /// </summary>
+        public event EventHandler Deactivated;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is closed.
+        /// </summary>
+        public event EventHandler Closed;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is maximized.
+        /// </summary>
+        public event EventHandler Maximized;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is minimized.
+        /// </summary>
+        public event EventHandler Minimized;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is restored.
+        /// </summary>
+        public event EventHandler Restored;
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindow" /> is closing.
+        /// </summary>
+        public event EventHandler<CancelEventArgs> Closing;
+
+        #endregion Events
+
+        #region Properties
+
+        /// <summary>
+        /// Gets or sets a reference to the FloatingWindowHost, containing the window.
+        /// </summary>
+        /// <value>The floating window host.</value>
+        public FloatingWindowHost FloatingWindowHost { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the window is always displayed in front of other windows.
+        /// </summary>
+        /// <value><c>true</c> if top most; otherwise, <c>false</c>.</value>
+        public bool TopMost { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this window is open.
+        /// </summary>
+        /// <value><c>true</c> if this window is open; otherwise, <c>false</c>.</value>
+        public bool IsOpen { get; private set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this window is modal.
+        /// </summary>
+        /// <value><c>true</c> if this window is modal; otherwise, <c>false</c>.</value>
+        public bool IsModal { get; private set; }
+
+        /// <summary>
+        /// Gets the window thumbnail.
+        /// </summary>
+        /// <value>The window thumbnail.</value>
+        public ImageSource WindowThumbnail
+        {
+            get
+            {
+                return (windowState == WindowState.Minimized) ? minimizedWindowThumbnail : GetThumbnailImage();
+            }
+        }
+
+        /// <summary>
+        /// Gets the state of the window.
+        /// </summary>
+        /// <value>Current state of the window.</value>
+        public WindowState WindowState
+        {
+            get { return windowState; }
+        }
+
+        /// <summary>
+        /// Gets or sets the minimum height constraint of a <see cref="T:System.Windows.FrameworkElement"/>.
+        /// </summary>
+        /// <value>he minimum height of the window.</value>
+        /// <returns>The minimum height of the window, in pixels. The default is 0. 
+        /// This value can be any value equal to or greater than 0. 
+        /// However, <see cref="F:System.Double.PositiveInfinity"/> is not valid.</returns>
+        public new double MinHeight
+        {
+            get
+            {
+                double minHeight = base.MinHeight;
+
+                if ((base.MinHeight.IsNotSet() || base.MinHeight == 0) &&
+                    (chrome != null && contentRoot != null))
+                {
+                    // Set minimal height to the height of the chrome element of the window
+                    minHeight = chrome.GetRelativePosition(contentRoot).Y + chrome.ActualHeight;
+                }
+
+                return minHeight;
+            }
+
+            set
+            {
+                base.MinHeight = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets a bounding rectangle of the window.
+        /// </summary>
+        /// <value>Bounding rectangle.</value>
+        public Rect BoundingRectangle
+        {
+            get { return new Rect(Position.X, Position.Y, ActualWidth, ActualHeight); }
+        }
+
+        /// <summary>
+        /// Gets a Snapin controller.
+        /// </summary>
+        /// <value>Snapin controller.</value>
+        public ISnapinController SnapinController
+        {
+            get { return snapinController; }
+        }
+
+        /// <summary>
+        /// Gets the host panel, containing the floating windows.
+        /// </summary>
+        /// <value>The host panel.</value>
+        public Panel HostPanel
+        {
+            get { return this.FloatingWindowHost == null ? null : this.FloatingWindowHost.HostPanel; }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether window size is explicitly set.
+        /// </summary>
+        /// <value><c>true</c> if window size is set; otherwise, <c>false</c>.</value>
+        private bool IsWindowSizeSet
+        {
+            get { return !Width.IsNotSet() && !Height.IsNotSet(); }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the window Tag property is set.
+        /// </summary>
+        /// <value><c>true</c> if the Tag set; otherwise, <c>false</c>.</value>
+        private bool IsWindowTagSet
+        {
+            get
+            {
+                string tag = this.Tag as string;
+                return !string.IsNullOrWhiteSpace(tag);
+            }
+        }
+
+        /// <summary>
+        /// Gets coordinates of the window placed in the center of its host.
+        /// </summary>
+        /// <value>The centered window position.</value>
+        private Point CenteredWindowPosition
+        {
+            get
+            {
+                return new Point((HostPanel.ActualWidth - Width.ValueOrZero()) / 2, (HostPanel.ActualHeight - Height.ValueOrZero()) / 2);
+            }
+        }
+
+        #endregion Properties
+
+        /// <summary>
+        /// Shows the window as a modal one.
+        /// </summary>
+        public void ShowModal()
+        {
+            IsModal = true;
+            Position = new Point(double.NaN, double.NaN);
+            ShowMaximizeButton = false;
+            ShowMinimizeButton = false;
+
+            Show();
+        }
+
+        /// <summary>
+        /// Opens the <see cref="FloatingWindow" /> in previously saved position or
+        /// in the center of the <see cref="FloatingWindowHost" />.
+        /// </summary>
+        public void Show()
+        {
+            Show(Position);
+        }
+
+        /// <summary>
+        /// Shows the window in the specified coordinates, relative to the window's Host.
+        /// </summary>
+        /// <param name="x">X-coordinate.</param>
+        /// <param name="y">Y-coordinate.</param>
+        public void Show(double x, double y)
+        {
+            Show(new Point(x, y));
+        }
+
+        /// <summary>
+        /// Shows a <see cref="FloatingWindow"/> at maximal size taking into account
+        /// specified margins and current <see cref="FloatingWindowHost"/> size.
+        /// </summary>
+        /// <param name="margins">Window margins.</param>
+        public void Show(Thickness margins)
+        {
+            CheckHost();
+            Action<Thickness> action = new Action<Thickness>(ShowWindow);
+            this.FloatingWindowHost.ShowWindow(action, margins);
+        }
+
+        /// <summary>
+        /// Shows the window in the specified coordinates, relative to the window's Host.
+        /// </summary>
+        /// <param name="point">Coordinates of the upper-left corner of the window.</param>
+        public void Show(Point point)
+        {
+            CheckHost();
+            Action<Point> action = new Action<Point>(ShowWindow);
+            this.FloatingWindowHost.ShowWindow(action, point);
+        }
+
+        /// <summary>
+        /// Shows a <see cref="FloatingWindow"/> at maximal size taking into account
+        /// specified margins and current <see cref="FloatingWindowHost"/> size.
+        /// </summary>
+        /// <param name="margins">Window margins.</param>
+        private void ShowWindow(Thickness margins)
+        {
+            Width = Math.Max(MinWidth, HostPanel.ActualWidth - margins.Horizontal());
+            Height = Math.Max(MinHeight, HostPanel.ActualHeight - margins.Vertical());
+
+            ShowWindow(new Point(margins.Left, margins.Top));
+        }
+
+        /// <summary>
+        /// Shows the window in the specified coordinates, relative to the window's Host.
+        /// </summary>
+        /// <param name="point">Coordinates of the upper-left corner of the window.</param>
+        /// <exception cref="System.InvalidOperationException">"The FloatingWindow was not added to the host.</exception>
+        private void ShowWindow(Point point)
+        {
+            if (!IsOpen)
+            {
+                if (IsModal)
+                    this.FloatingWindowHost.ShowWindowAsModal(this);
+
+                SubscribeToEvents();
+                SubscribeToTemplatePartEvents();
+                SubscribeToStoryBoardEvents();
+
+                // Guarantee that the visual tree of an element is complete
+                ApplyTemplate();
+
+                // Brings current window to the front
+                SetTopmost();
+
+                Point position = point;
+
+                if (point.IsNotSet())
+                    position = CenteredWindowPosition;
+
+                MoveWindow(position);
+                this.SetVisible(true);
+
+                if (!IsWindowSizeSet && point.IsNotSet())
+                {
+                    // If window size is not set explicitly we should wait
+                    // when the window layout is updated and update its position
+                    contentRoot.SizeChanged += new SizeChangedEventHandler(ContentRoot_SizeChanged);
+                }
+
+                VisualStateManager.GoToState(this, VSMSTATE_StateOpen, true);
+                IsOpen = true;
+            }
+            else
+            {
+                MoveWindow(point);
+                this.SetVisible(true);
+            }
+        }
+
+        /// <summary>
+        /// Handles the SizeChanged event of the ContentRoot control to update window position 
+        /// only once when the window is opened.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void ContentRoot_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            contentRoot.SizeChanged -= new SizeChangedEventHandler(ContentRoot_SizeChanged);
+            double dx = -(e.NewSize.Width.ValueOrZero() - e.PreviousSize.Width.ValueOrZero()) / 2;
+            double dy = -(e.NewSize.Height.ValueOrZero() - e.PreviousSize.Height.ValueOrZero()) / 2;
+            Point point = Position.Add(dx, dy);
+            MoveWindow(point);
+        }
+
+        /// <summary>
+        /// Restores window state, size and its position.
+        /// </summary>
+        public void RestoreWindow()
+        {
+            switch (windowState)
+            {
+                case WindowState.Minimized:
+                    if (previousWindowState == WindowState.Maximized)
+                    {
+                        Width = HostPanel.ActualWidth;
+                        Height = HostPanel.ActualHeight;
+                    }
+
+                    SetTopmost();
+                    windowState = previousWindowState;
+                    VisualStateManager.GoToState(this, VSMSTATE_StateRestored, true);
+                    OnRestored(EventArgs.Empty);
+                    break;
+
+                case WindowState.Normal:
+                    SetTopmost();
+                    EnsureVisible();
+                    break;
+
+                case WindowState.Maximized:
+                    SetTopmost();
+                    break;
+            }
+
+            Focus();
+        }
+
+        /// <summary>
+        /// Makes the window topmost and tries to set focus on it.
+        /// </summary>
+        public void Activate()
+        {
+            SetTopmost();
+        }
+
+        /// <summary>
+        /// Brings current window to the front.
+        /// </summary>
+        private void SetTopmost()
+        {
+            if (this.FloatingWindowHost != null)
+                this.FloatingWindowHost.SetTopmostWindow(this);
+        }
+
+        /// <summary>
+        /// Ensures the window is visible.
+        /// </summary>
+        private void EnsureVisible()
+        {
+            if (HostPanel != null && (Position.X >= HostPanel.ActualWidth || Position.Y >= HostPanel.ActualHeight))
+            {
+                Position = CenteredWindowPosition;
+            }
+        }
+
+        /// <summary>
+        /// Executed when the application is exited.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">Event args.</param>
+        private void Application_Exit(object sender, EventArgs e)
+        {
+            if (IsOpen)
+            {
+                isAppExit = true;
+                try
+                {
+                    Close();
+                }
+                finally
+                {
+                    isAppExit = false;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Closes a <see cref="FloatingWindow" />.
+        /// </summary>
+        public void Close()
+        {
+            SaveSizeAndPosition();
+
+            CancelEventArgs e = new CancelEventArgs();
+            OnClosing(e);
+
+            // On ApplicationExit, Close() cannot be cancelled
+            if (IsOpen && (!e.Cancel || isAppExit))
+            {
+                IsOpen = false;
+
+                if (IsModal)
+                    this.FloatingWindowHost.RemoveOverlay();
+
+                if (closingStoryboard != null)
+                {
+                    VisualStateManager.GoToState(this, VSMSTATE_StateClosed, true);
+                }
+                else
+                {
+                    this.Visibility = Visibility.Collapsed;
+                    OnClosed(EventArgs.Empty);
+                }
+
+                UnSubscribeFromEvents();
+                UnsubscribeFromTemplatePartEvents();
+            }
+        }
+
+        /// <summary>
+        /// Restores the size and position stored in the IsolatedStorage on closing.
+        /// </summary>
+        public void RestoreSizeAndPosition()
+        {
+            if (IsWindowTagSet)
+            {
+                string positionKey = GetAppSettingsKey("Position");
+                string sizeKey = GetAppSettingsKey("Size");
+
+                if (localStorage.Contains(positionKey))
+                    Position = (Point)localStorage[positionKey];
+
+                if (localStorage.Contains(sizeKey))
+                {
+                    Size size = (Size)localStorage[sizeKey];
+                    Width = size.Width == 0 ? double.NaN : size.Width;
+                    Height = size.Height == 0 ? double.NaN : size.Height;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Executed when the Close button is clicked.
+        /// </summary>
+        /// <param name="sender">Sender object.</param>
+        /// <param name="e">Routed event args.</param>
+        private void CloseButton_Click(object sender, RoutedEventArgs e)
+        {
+            Close();
+        }
+
+        /// <summary>
+        /// Executed when the Closing storyboard ends.
+        /// </summary>
+        /// <param name="sender">Sender object.</param>
+        /// <param name="e">Event args.</param>
+        private void Closing_Completed(object sender, EventArgs e)
+        {
+            if (closingStoryboard != null)
+                closingStoryboard.Completed -= new EventHandler(Closing_Completed);
+
+            this.Visibility = Visibility.Collapsed;
+            OnClosed(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Builds the visual tree for the <see cref="FloatingWindow" /> control 
+        /// when a new template is applied.
+        /// </summary>
+        public override void OnApplyTemplate()
+        {
+            UnsubscribeFromTemplatePartEvents();
+            UnsubscribeFromStoryBoardEvents();
+
+            base.OnApplyTemplate();
+
+            root = GetTemplateChild(PART_Root) as FrameworkElement;
+            contentRoot = GetTemplateChild(PART_ContentRoot) as FrameworkElement;
+            contentBorder = GetTemplateChild(PART_ContentBorder) as Border;
+            chrome = GetTemplateChild(PART_Chrome) as FrameworkElement;
+            titleContent = GetTemplateChild(PART_TitleContent) as ContentControl;
+            contentPresenter = GetTemplateChild(PART_ContentPresenter) as FrameworkElement;
+            closeButton = GetTemplateChild(PART_CloseButton) as ButtonBase;
+            maximizeButton = GetTemplateChild(PART_MaximizeButton) as ButtonBase;
+            minimizeButton = GetTemplateChild(PART_MinimizeButton) as ButtonBase;
+            restoreButton = GetTemplateChild(PART_RestoreButton) as ButtonBase;
+
+            if (root == null)
+                throw new NotImplementedException("Template Part PART_Root is required to display FloatingWindow.");
+
+            if (contentRoot == null)
+                throw new NotImplementedException("Template Part PART_ContentRoot is required to display FloatingWindow.");
+
+            if (contentPresenter == null)
+                throw new NotImplementedException("Template Part PART_ContentPresenter is required to display FloatingWindow.");
+
+            SetStyles();
+            GetStoryboards();
+            SetInitialRootPosition();
+            InitializeContentRootTransformGroup();
+
+            if (closeButton != null)
+                closeButton.SetVisible(ShowCloseButton);
+
+            if (minimizeButton != null)
+                minimizeButton.SetVisible(ShowMinimizeButton);
+
+            if (maximizeButton != null)
+                maximizeButton.SetVisible(ShowMaximizeButton);
+
+            SubscribeToTemplatePartEvents();
+            SubscribeToStoryBoardEvents();
+        }
+
+        /// <summary>
+        /// Sets styles that are applied for different template parts.
+        /// </summary>
+        private void SetStyles()
+        {
+            if (titleContent != null && this.TitleStyle != null)
+                titleContent.Style = this.TitleStyle;
+
+            if (minimizeButton != null && this.MinimizeButtonStyle != null)
+                minimizeButton.Style = this.MinimizeButtonStyle;
+
+            if (maximizeButton != null && this.MaximizeButtonStyle != null)
+                maximizeButton.Style = this.MaximizeButtonStyle;
+
+            if (restoreButton != null && this.RestoreButtonStyle != null)
+                restoreButton.Style = this.RestoreButtonStyle;
+
+            if (closeButton != null && this.CloseButtonStyle != null)
+                closeButton.Style = this.CloseButtonStyle;
+        }
+
+        /// <summary>
+        /// Gets the storyboards defined in the <see cref="FloatingWindow" /> style.
+        /// </summary>
+        private void GetStoryboards()
+        {
+            if (root != null)
+            {
+                var groups = VisualStateManager.GetVisualStateGroups(root) as Collection<VisualStateGroup>;
+                if (groups != null)
+                {
+                    var states = (from stategroup in groups
+                                  where stategroup.Name == FloatingWindow.VSMGROUP_Window
+                                  select stategroup.States).FirstOrDefault() as Collection<VisualState>;
+
+                    if (states != null)
+                    {
+                        closingStoryboard = (from state in states
+                                             where state.Name == FloatingWindow.VSMSTATE_StateClosed
+                                             select state.Storyboard).FirstOrDefault();
+
+                        openingStoryboard = (from state in states
+                                             where state.Name == FloatingWindow.VSMSTATE_StateOpen
+                                             select state.Storyboard).FirstOrDefault();
+                    }
+                }
+
+                if (inertialMotionStoryboard == null)
+                    inertialMotionStoryboard = new Storyboard();
+            }
+        }
+
+        /// <summary>
+        /// Shift the root of the window to compensate its margins.
+        /// </summary>
+        private void SetInitialRootPosition()
+        {
+            double x = Math.Round(-this.Margin.Left);
+            double y = Math.Round(-this.Margin.Top);
+
+            var transformGroup = root.RenderTransform as TransformGroup;
+            if (transformGroup == null)
+            {
+                transformGroup = new TransformGroup();
+                transformGroup.Children.Add(root.RenderTransform);
+                root.RenderTransform = transformGroup;
+            }
+
+            var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
+            if (translateTransform == null)
+            {
+                transformGroup.Children.Add(new TranslateTransform() { X = x, Y = y });
+            }
+            else
+            {
+                translateTransform.X = x;
+                translateTransform.Y = y;
+            }
+        }
+
+        /// <summary>
+        /// Checks the TransformGroup of the content root or creates it if necesary.
+        /// </summary>
+        private void InitializeContentRootTransformGroup()
+        {
+            var transformGroup = contentRoot.RenderTransform as TransformGroup;
+            if (transformGroup == null)
+            {
+                transformGroup = new TransformGroup();
+                transformGroup.Children.Add(contentRoot.RenderTransform);
+                contentRoot.RenderTransform = transformGroup;
+            }
+
+            // Check that ScaleTransform exists in the TransformGroup
+            // ScaleTransform is used as a target in Storyboards 
+            var scaleTransform = transformGroup.Children.OfType<ScaleTransform>().FirstOrDefault();
+
+            if (scaleTransform == null)
+                transformGroup.Children.Insert(0, new ScaleTransform());
+
+            var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
+
+            if (translateTransform == null)
+                transformGroup.Children.Add(new TranslateTransform());
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Activated" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnActivated(EventArgs e)
+        {
+            EventHandler handler = Activated;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Deactivated" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnDeactivated(EventArgs e)
+        {
+            EventHandler handler = Deactivated;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Closed" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnClosed(EventArgs e)
+        {
+            this.FloatingWindowHost.Remove(this);
+            this.FloatingWindowHost.ActivateTopmostWindow();
+            UnsubscribeFromStoryBoardEvents();
+
+            EventHandler handler = Closed;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+
+            Dispose();
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Closing" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnClosing(CancelEventArgs e)
+        {
+            EventHandler<CancelEventArgs> handler = Closing;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Maximized" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnMaximized(EventArgs e)
+        {
+            EventHandler handler = Maximized;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Minimized" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnMinimized(EventArgs e)
+        {
+            EventHandler handler = Minimized;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindow.Restored" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnRestored(EventArgs e)
+        {
+            EventHandler handler = Restored;
+            if (handler != null)
+            {
+                handler(this, e);
+            }
+        }
+
+        /// <summary>
+        /// This method is called every time a <see cref="FloatingWindow" /> is displayed.
+        /// </summary>
+        protected virtual void OnOpened()
+        {
+            if (!Focus())
+            {
+                // If the Focus() fails it means there is no focusable element in the window.
+                // In this case we set IsTabStop to true to have the keyboard functionality
+                IsTabStop = true;
+                Focus();
+            }
+        }
+
+        /// <summary>
+        /// Executed when the opening storyboard finishes.
+        /// </summary>
+        /// <param name="sender">Sender object.</param>
+        /// <param name="e">Event args.</param>
+        private void Opening_Completed(object sender, EventArgs e)
+        {
+            if (openingStoryboard != null)
+                openingStoryboard.Completed -= new EventHandler(Opening_Completed);
+
+            this.FloatingWindowHost.UpdateIconBar();
+            IsOpen = true;
+            OnOpened();
+        }
+
+        /// <summary>
+        /// Subscribes to events when the window is opened.
+        /// </summary>
+        private void SubscribeToEvents()
+        {
+            if (Application.Current != null)
+                Application.Current.Exit += new EventHandler(Application_Exit);
+
+            if (this.FloatingWindowHost != null)
+            {
+                this.FloatingWindowHost.SizeChanged += new SizeChangedEventHandler(Host_SizeChanged);
+                this.FloatingWindowHost.ActiveWindowChanged += new EventHandler<ActiveWindowChangedEventArgs>(ActiveWindowChanged);
+            }
+
+            // Attach Mouse event handler to catch already handled events to bring the window to the front
+            this.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(FloatingWindow_MouseLeftButtonDown), true);
+        }
+
+        /// <summary>
+        /// Handles the MouseLeftButtonDown event to bring the window to the front.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
+        private void FloatingWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            // Gets the element with keyboard focus
+            Control elementWithFocus = FocusManager.GetFocusedElement() as Control;
+
+            // Brings current window to the front
+            SetTopmost();
+
+            if (elementWithFocus != null)
+            {
+                if (IsControlInVisualTree(elementWithFocus))
+                {
+                    elementWithFocus.Focus();
+                }
+                else
+                {
+                    // Try to set focus on the window
+                    Focus();
+                }
+            }
+
+            // Stop any inertial motion
+            StopInertialMotion();
+        }
+
+        /// <summary>
+        /// Determines whether the control is in the visual tree of the window.
+        /// </summary>
+        /// <param name="control">The control to test.</param>
+        /// <returns>
+        /// <c>true</c> if the control is in the visual tree; otherwise, <c>false</c>.
+        /// </returns>
+        private bool IsControlInVisualTree(Control control)
+        {
+            if (control != null)
+            {
+                DependencyObject parent = control;
+                do
+                {
+                    parent = VisualTreeHelper.GetParent(parent);
+                    FloatingWindow window = parent as FloatingWindow;
+
+                    if (window != null && window == this)
+                        return true;
+                }
+                while (parent != null);
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Unsubscribe from events when the ChildWindow is closed.
+        /// </summary>
+        private void UnSubscribeFromEvents()
+        {
+            if (Application.Current != null)
+                Application.Current.Exit -= new EventHandler(Application_Exit);
+
+            if (this.FloatingWindowHost != null)
+            {
+                this.FloatingWindowHost.SizeChanged -= new SizeChangedEventHandler(Host_SizeChanged);
+                this.FloatingWindowHost.ActiveWindowChanged -= new EventHandler<ActiveWindowChangedEventArgs>(ActiveWindowChanged);
+            }
+
+            this.RemoveHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(FloatingWindow_MouseLeftButtonDown));
+        }
+
+        /// <summary>
+        /// Subscribes to the events on the storyboards. 
+        /// </summary>
+        private void SubscribeToStoryBoardEvents()
+        {
+            if (closingStoryboard != null)
+                closingStoryboard.Completed += new EventHandler(Closing_Completed);
+
+            if (openingStoryboard != null)
+                openingStoryboard.Completed += new EventHandler(Opening_Completed);
+
+            if (inertialMotionStoryboard != null)
+                inertialMotionStoryboard.Completed += new EventHandler(InertialMotion_Completed);
+        }
+
+        /// <summary>
+        /// Unsubscribe from events that are subscribed on the storyboards. 
+        /// </summary>
+        private void UnsubscribeFromStoryBoardEvents()
+        {
+            if (closingStoryboard != null)
+                closingStoryboard.Completed -= new EventHandler(Closing_Completed);
+
+            if (openingStoryboard != null)
+                openingStoryboard.Completed -= new EventHandler(Opening_Completed);
+
+            if (inertialMotionStoryboard != null)
+                inertialMotionStoryboard.Completed -= new EventHandler(InertialMotion_Completed);
+        }
+
+        /// <summary>
+        /// Subscribes to the events on the template parts.
+        /// </summary>
+        private void SubscribeToTemplatePartEvents()
+        {
+            if (closeButton != null)
+                closeButton.Click += new RoutedEventHandler(CloseButton_Click);
+
+            if (maximizeButton != null)
+                maximizeButton.Click += new RoutedEventHandler(MaximizeButton_Click);
+
+            if (restoreButton != null)
+                restoreButton.Click += new RoutedEventHandler(RestoreButton_Click);
+
+            if (minimizeButton != null)
+                minimizeButton.Click += new RoutedEventHandler(MinimizeButton_Click);
+        }
+
+        /// <summary>
+        /// Unsubscribe from the events that are subscribed on the template part elements.
+        /// </summary>
+        private void UnsubscribeFromTemplatePartEvents()
+        {
+            if (closeButton != null)
+                closeButton.Click -= new RoutedEventHandler(CloseButton_Click);
+
+            if (maximizeButton != null)
+                maximizeButton.Click -= new RoutedEventHandler(MaximizeButton_Click);
+
+            if (restoreButton != null)
+                restoreButton.Click -= new RoutedEventHandler(RestoreButton_Click);
+
+            if (minimizeButton != null)
+                minimizeButton.Click -= new RoutedEventHandler(MinimizeButton_Click);
+        }
+
+        /// <summary>
+        /// Handles the ActiveWindowChanged event of the Host control.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="SilverFlow.Controls.ActiveWindowChangedEventArgs"/> instance containing the event data.</param>
+        private void ActiveWindowChanged(object sender, ActiveWindowChangedEventArgs e)
+        {
+            if (e.Old == this)
+                OnDeactivated(EventArgs.Empty);
+
+            if (e.New == this)
+                OnActivated(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Handles the Click event of the MaximizeButton control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
+        {
+            MaximizeWindow();
+        }
+
+        /// <summary>
+        /// Handles the Click event of the RestoreButton control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+        private void RestoreButton_Click(object sender, RoutedEventArgs e)
+        {
+            RestoreMaximizedWindow();
+        }
+
+        /// <summary>
+        /// Handles the Click event of the MinimizeButton control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
+        {
+            MinimizeWindow();
+        }
+
+        /// <summary>
+        /// Minimizes the window.
+        /// </summary>
+        private void MinimizeWindow()
+        {
+            if (windowState != WindowState.Minimized)
+            {
+                if (minimizeButton != null)
+                    VisualStateManager.GoToState(minimizeButton, VSMSTATE_StateNormal, true);
+
+                if (windowState == WindowState.Normal)
+                {
+                    // Store previous coordinates
+                    previousPosition = Position;
+                    previousSize = new Size(ActualWidth, ActualHeight);
+                }
+
+                minimizedWindowThumbnail = GetThumbnailImage();
+
+                previousWindowState = windowState;
+                VisualStateManager.GoToState(this, VSMSTATE_StateMinimized, true);
+                OnMinimized(EventArgs.Empty);
+            }
+
+            windowState = WindowState.Minimized;
+            OnDeactivated(EventArgs.Empty);
+
+            this.FloatingWindowHost.ActivateTopmostWindow();
+        }
+
+        /// <summary>
+        /// Creates a thumbnail of the window.
+        /// </summary>
+        /// <returns>Bitmap containing thumbnail image.</returns>
+        private ImageSource GetThumbnailImage()
+        {
+            // If an Icon is specified - use it as a thumbnail displayed on the iconbar
+            // Otherwise, display the window itself
+            FrameworkElement icon = (Icon as FrameworkElement) ?? contentRoot;
+            ImageSource bitmap = bitmapHelper.RenderVisual(icon, FloatingWindowHost.IconWidth, FloatingWindowHost.IconHeight);
+
+            return bitmap;
+        }
+
+        /// <summary>
+        /// Maximizes the window.
+        /// </summary>
+        public void MaximizeWindow()
+        {
+            if (windowState != WindowState.Maximized)
+            {
+                if (maximizeButton != null && restoreButton != null && HostPanel != null)
+                {
+                    if (this.ShowMaximizeButton)
+                        maximizeButton.SetVisible(false);
+
+                    if (this.ShowRestoreButton)
+                        restoreButton.SetVisible(true);
+
+                    VisualStateManager.GoToState(restoreButton, VSMSTATE_StateNormal, true);
+
+                    // Store previous coordinates
+                    previousPosition = Position;
+                    previousSize = new Size(ActualWidth, ActualHeight);
+
+                    // Hide the outer border
+                    if (contentBorder != null)
+                    {
+                        contentBorderThickness = contentBorder.BorderThickness;
+                        contentBorderCornerRadius = contentBorder.CornerRadius;
+                        contentBorder.BorderThickness = new Thickness(0);
+                        contentBorder.CornerRadius = new CornerRadius(0);
+                    }
+
+                    Border border = chrome as Border;
+                    if (border != null)
+                    {
+                        chromeBorderCornerRadius = border.CornerRadius;
+                        border.CornerRadius = new CornerRadius(0);
+                    }
+
+                    StartMaximizingAnimation();
+                }
+
+                previousWindowState = windowState;
+                windowState = WindowState.Maximized;
+            }
+        }
+
+        /// <summary>
+        /// Checks if the floating window was added to the FloatingWindowHost.
+        /// </summary>
+        private void CheckHost()
+        {
+            if (this.FloatingWindowHost == null)
+                throw new InvalidOperationException("The FloatingWindow was not added to the FloatingWindowHost.");
+        }
+
+        /// <summary>
+        /// Starts maximizing animation.
+        /// </summary>
+        private void StartMaximizingAnimation()
+        {
+            SaveActualSize();
+
+            this.MoveAndResize(new Point(0, 0), HostPanel.ActualWidth, HostPanel.ActualHeight,
+                MaximizingDurationInMilliseconds, Maximizing_Completed);
+        }
+
+        /// <summary>
+        /// Saves the actual size if it was not set explicitly set. 
+        /// E.g. the Width can be NaN, that means "Auto".
+        /// </summary>
+        private void SaveActualSize()
+        {
+            if (Width.IsNotSet())
+                Width = ActualWidth;
+
+            if (Height.IsNotSet())
+                Height = ActualHeight;
+        }
+
+        /// <summary>
+        /// Handles the Completed event of the Maximizing animation.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        private void Maximizing_Completed(object sender, EventArgs e)
+        {
+            OnMaximized(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Restores maximized window position and size.
+        /// </summary>
+        private void RestoreMaximizedWindow()
+        {
+            if (windowState != WindowState.Normal)
+            {
+                if (maximizeButton != null && restoreButton != null && HostPanel != null)
+                {
+                    if (this.ShowMaximizeButton)
+                        maximizeButton.SetVisible(true);
+
+                    if (this.ShowRestoreButton)
+                        restoreButton.SetVisible(false);
+
+                    VisualStateManager.GoToState(maximizeButton, VSMSTATE_StateNormal, true);
+                }
+
+                // Restore the outer border
+                if (contentBorder != null)
+                {
+                    contentBorder.BorderThickness = contentBorderThickness;
+                    contentBorder.CornerRadius = contentBorderCornerRadius;
+                }
+
+                Border border = chrome as Border;
+
+                if (border != null)
+                    border.CornerRadius = chromeBorderCornerRadius;
+
+                StartRestoringAnimation();
+                windowState = WindowState.Normal;
+            }
+            else
+            {
+                Show(Position);
+            }
+        }
+
+        /// <summary>
+        /// Starts restoring animation.
+        /// </summary>
+        private void StartRestoringAnimation()
+        {
+            SaveActualSize();
+
+            this.MoveAndResize(previousPosition, previousSize.Width, previousSize.Height,
+                RestoringDurationInMilliseconds, Restoring_Completed);
+        }
+
+        /// <summary>
+        /// Handles the Completed event of the Restoring animation.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        private void Restoring_Completed(object sender, EventArgs e)
+        {
+            OnRestored(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Updates clipping region on host SizeChanged event.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void Host_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            if (windowState == WindowState.Maximized)
+            {
+                Width = HostPanel.ActualWidth;
+                Height = double.IsInfinity(MaxHeight) ? HostPanel.ActualHeight : MaxHeight;
+            }
+        }
+
+        /// <summary>
+        /// Executed when mouse left button is down.
+        /// </summary>
+        /// <param name="e">The data for the event.</param>
+        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
+        {
+            base.OnMouseLeftButtonDown(e);
+
+            if (windowState == WindowState.Normal)
+            {
+                // Stop inertial motion before the mouse is captured
+                StopInertialMotion();
+
+                clickPoint = e.GetPosition(HostPanel);
+                clickWindowPosition = Position;
+                snapinController.SnapinDistance = this.FloatingWindowHost.SnapinDistance;
+                snapinController.SnapinMargin = this.FloatingWindowHost.SnapinMargin;
+                snapinController.SnapinEnabled = this.FloatingWindowHost.SnapinEnabled;
+
+                if (ResizeEnabled && resizeController.CanResize)
+                {
+                    snapinController.SnapinBounds = this.FloatingWindowHost.GetSnapinBounds(this);
+                    resizeController.StartResizing();
+                    CaptureMouseCursor();
+                    windowAction = WindowAction.Resize;
+                }
+                else if (chrome != null)
+                {
+                    // If the mouse was clicked on the chrome - start dragging the window
+                    Point point = e.GetPosition(chrome);
+
+                    if (chrome.ContainsPoint(point))
+                    {
+                        snapinController.SnapinBounds = this.FloatingWindowHost.GetSnapinBounds(this);
+                        CaptureMouseCursor();
+                        windowAction = WindowAction.Move;
+                        inertiaController.StartMotion(Position);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Executed when mouse left button is up.
+        /// </summary>
+        /// <param name="e">The data for the event.</param>
+        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
+        {
+            base.OnMouseLeftButtonUp(e);
+
+            if (windowAction == WindowAction.Move)
+            {
+                InertialMotion motion = inertiaController.GetInertialMotionParameters(
+                    this.FloatingWindowHost.HostPanel.GetActualBoundingRectangle(), this.BoundingRectangle);
+
+                if (motion != null)
+                {
+                    contentRoot.AnimateTranslateTransform(inertialMotionStoryboard, motion.EndPosition, motion.Seconds, motion.EasingFunction);
+                }
+            }
+
+            if (isMouseCaptured)
+            {
+                contentRoot.ReleaseMouseCapture();
+                isMouseCaptured = false;
+            }
+
+            windowAction = WindowAction.None;
+        }
+
+        /// <summary>
+        /// Handles the Completed event of the InertialMotionStoryboard.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        private void InertialMotion_Completed(object sender, EventArgs e)
+        {
+            // Save current window position reading it from the TranslateTransform object
+            Position = GetCurrentWindowPosition();
+        }
+
+        /// <summary>
+        /// Stops current inertial motion.
+        /// </summary>
+        private void StopInertialMotion()
+        {
+            if (inertialMotionStoryboard.GetCurrentState() != ClockState.Stopped)
+            {
+                inertialMotionStoryboard.Pause();
+
+                // The Position has rounded coordinates now, but real X and Y coordinates are fractional
+                Position = GetCurrentWindowPosition();
+
+                // Move the window to the rounded coordinates
+                MoveWindow(Position);
+
+                inertialMotionStoryboard.Stop();
+                inertialMotionStoryboard.Children.Clear();
+            }
+        }
+
+        /// <summary>
+        /// Gets current window position taking into account animation effects.
+        /// </summary>
+        /// <returns>Current window position.</returns>
+        private Point GetCurrentWindowPosition()
+        {
+            var transformGroup = contentRoot.RenderTransform as TransformGroup;
+            var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
+            var position = new Point(translateTransform.X, translateTransform.Y);
+
+            // Round coordinates to avoid blured window
+            return position.Round();
+        }
+
+        /// <summary>
+        /// Captures the mouse cursor.
+        /// </summary>
+        private void CaptureMouseCursor()
+        {
+            contentRoot.CaptureMouse();
+            isMouseCaptured = true;
+        }
+
+        /// <summary>
+        /// Executed when mouse moves.
+        /// </summary>
+        /// <param name="e">The data for the event.</param>
+        protected override void OnMouseMove(MouseEventArgs e)
+        {
+            base.OnMouseMove(e);
+
+            if (windowState == WindowState.Normal && ResizeEnabled && windowAction == WindowAction.None)
+            {
+                Point mousePosition = e.GetPosition(contentRoot);
+
+                if (IsMouseOverButtons(mousePosition, contentRoot))
+                    this.Cursor = Cursors.Arrow;
+                else
+                    resizeController.SetCursor(mousePosition);
+            }
+
+            Point p = e.GetPosition(HostPanel);
+            double dx = p.X - clickPoint.X;
+            double dy = p.Y - clickPoint.Y;
+
+            if (windowAction == WindowAction.Resize)
+                resizeController.Resize(dx, dy);
+
+            if (windowAction == WindowAction.Move)
+            {
+                Point point = clickWindowPosition.Add(dx, dy);
+                Rect rect = new Rect(point.X, point.Y, ActualWidth, ActualHeight);
+
+                point = snapinController.SnapRectangle(rect);
+                MoveWindow(point);
+
+                inertiaController.MoveToPoint(Position);
+            }
+        }
+
+        /// <summary>
+        /// Determines whether the mouse is over buttons in the the specified mouse position.
+        /// </summary>
+        /// <param name="position">The mouse position.</param>
+        /// <param name="origin">Relative origin.</param>
+        /// <returns><c>true</c> if mouse is mouse over buttons.</returns>
+        private bool IsMouseOverButtons(Point position, UIElement origin)
+        {
+            return (minimizeButton.IsVisible() && minimizeButton.ContainsPoint(position, origin)) ||
+                   (maximizeButton.IsVisible() && maximizeButton.ContainsPoint(position, origin)) ||
+                   (restoreButton.IsVisible() && restoreButton.ContainsPoint(position, origin)) ||
+                   (closeButton.IsVisible() && closeButton.ContainsPoint(position, origin));
+        }
+
+        /// <summary>
+        /// Moves the window to the specified coordinates.
+        /// </summary>
+        /// <param name="point">Coordinates of the window.</param>
+        private void MoveWindow(Point point)
+        {
+            if (contentRoot != null && !point.IsNotSet())
+            {
+                // Round coordinates to avoid blured window
+                double x = Math.Round(Math.Max(0, point.X));
+                double y = Math.Round(Math.Max(0, point.Y));
+
+                var transformGroup = contentRoot.RenderTransform as TransformGroup;
+                var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault();
+                if (translateTransform == null)
+                {
+                    transformGroup.Children.Add(new TranslateTransform() { X = x, Y = y });
+                }
+                else
+                {
+                    translateTransform.X = x;
+                    translateTransform.Y = y;
+                }
+
+                Point newPosition = new Point(x, y);
+
+                if (Position != newPosition)
+                    Position = newPosition;
+            }
+        }
+
+        /// <summary>
+        /// Saves current size and position of the window in the IsolatedStorage.
+        /// The key of the settings is the Tag of the window (if not null).
+        /// </summary>
+        private void SaveSizeAndPosition()
+        {
+            if (IsWindowTagSet)
+            {
+                string positionKey = GetAppSettingsKey("Position");
+                string sizeKey = GetAppSettingsKey("Size");
+
+                Point point = windowState == WindowState.Normal ? Position : previousPosition;
+                localStorage[positionKey] = point;
+
+                Size size = windowState == WindowState.Normal ? new Size(ActualWidth, ActualHeight) : previousSize;
+                localStorage[sizeKey] = size;
+            }
+        }
+
+        /// <summary>
+        /// Gets the application settings key used to store properties in the IsolatedStorage.
+        /// </summary>
+        /// <param name="key">The key of the property, e.g. "Position".</param>
+        /// <returns>Combined settings key or empty string.</returns>
+        private string GetAppSettingsKey(string key)
+        {
+            string tag = this.Tag as string;
+            return tag + ":" + key;
+        }
+
+        /// <summary>
+        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+        /// </summary>
+        public void Dispose()
+        {
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+            GC.Collect();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindowHost.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,1032 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// A Content Control containing floating windows.
+    /// </summary>
+    [TemplatePart(Name = PART_Root, Type = typeof(Grid))]
+    [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_HostCanvas, Type = typeof(Canvas))]
+    [TemplatePart(Name = PART_ModalCanvas, Type = typeof(Canvas))]
+    [TemplatePart(Name = PART_IconBarContainer, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_Overlay, Type = typeof(Grid))]
+    [TemplatePart(Name = PART_IconBar, Type = typeof(IconBar))]
+    [TemplatePart(Name = PART_BottomBar, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_BootstrapButton, Type = typeof(BootstrapButton))]
+    [TemplatePart(Name = PART_BarContent, Type = typeof(ContentControl))]
+    [TemplateVisualState(Name = VSMSTATE_VisibleOverlay, GroupName = VSMGROUP_Overlay)]
+    [TemplateVisualState(Name = VSMSTATE_HiddenOverlay, GroupName = VSMGROUP_Overlay)]
+    [StyleTypedProperty(Property = PROPERTY_BottomBarStyle, StyleTargetType = typeof(Border))]
+    [StyleTypedProperty(Property = PROPERTY_BootstrapButtonStyle, StyleTargetType = typeof(BootstrapButton))]
+    [StyleTypedProperty(Property = PROPERTY_WindowIconStyle, StyleTargetType = typeof(WindowIcon))]
+    public class FloatingWindowHost : ContentControl
+    {
+        #region Constants
+
+        // Template parts
+        private const string PART_Root = "PART_Root";
+        private const string PART_ContentRoot = "PART_ContentRoot";
+        private const string PART_HostCanvas = "PART_HostCanvas";
+        private const string PART_ModalCanvas = "PART_ModalCanvas";
+        private const string PART_IconBarContainer = "PART_IconBarContainer";
+        private const string PART_Overlay = "PART_Overlay";
+        private const string PART_IconBar = "PART_IconBar";
+        private const string PART_BottomBar = "PART_BottomBar";
+        private const string PART_BootstrapButton = "PART_BootstrapButton";
+        private const string PART_BarContent = "PART_BarContent";
+
+        // VSM groups
+        private const string VSMGROUP_Overlay = "OverlayStates";
+
+        // VSM states
+        private const string VSMSTATE_VisibleOverlay = "VisibleOverlay";
+        private const string VSMSTATE_HiddenOverlay = "HiddenOverlay";
+
+        // Style typed properties
+        private const string PROPERTY_BottomBarStyle = "BottomBarStyle";
+        private const string PROPERTY_BootstrapButtonStyle = "BootstrapButtonStyle";
+        private const string PROPERTY_WindowIconStyle = "WindowIconStyle";
+
+        // Thickness of resizing area.
+        private const double SnapinDistanceDefaultValue = 5.0;
+
+        // Default icon size
+        private const double DefaultIconWidth = 120;
+        private const double DefaultIconHeight = 70;
+
+        #endregion
+
+        #region Member Fields
+
+        /// <summary>
+        /// Current ZIndex of a child element
+        /// </summary>
+        private static int zIndex = 1;
+
+        private Grid root;
+        private FrameworkElement contentRoot;
+        private Canvas hostCanvas;
+        private Canvas modalCanvas;
+        private FrameworkElement iconBarContainer;
+        private Grid overlay;
+        private IconBar iconBar;
+        private FrameworkElement bottomBar;
+        private BootstrapButton bootstrapButton;
+        private ContentControl barContent;
+
+        private bool templateIsApplied;
+
+        #endregion Member Fields
+
+        #region public Style BottomBarStyle
+
+        /// <summary>
+        /// Gets or sets the style of the BottomBar.
+        /// </summary>
+        public Style BottomBarStyle
+        {
+            get { return GetValue(BottomBarStyleProperty) as Style; }
+            set { SetValue(BottomBarStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.BottomBarStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty BottomBarStyleProperty =
+            DependencyProperty.Register(
+                "BottomBarStyle",
+                typeof(Style),
+                typeof(FloatingWindowHost),
+                new PropertyMetadata(BottomBarStylePropertyChanged));
+
+        /// <summary>
+        /// BottomBarStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindowHost object whose BottomBarStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void BottomBarStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindowHost host = (FloatingWindowHost)d;
+            if (host != null && host.bottomBar != null)
+            {
+                host.bottomBar.Style = e.NewValue as Style;
+            }
+        }
+
+        #endregion
+
+        #region public Style BootstrapButtonStyle
+
+        /// <summary>
+        /// Gets or sets the style of the BootstrapButton.
+        /// </summary>
+        public Style BootstrapButtonStyle
+        {
+            get { return GetValue(BootstrapButtonStyleProperty) as Style; }
+            set { SetValue(BootstrapButtonStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.BootstrapButtonStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty BootstrapButtonStyleProperty =
+            DependencyProperty.Register(
+                "BootstrapButtonStyle",
+                typeof(Style),
+                typeof(FloatingWindowHost),
+                new PropertyMetadata(BootstrapButtonStylePropertyChanged));
+
+        /// <summary>
+        /// BootstrapButtonStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindowHost object whose BootstrapButtonStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void BootstrapButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindowHost host = (FloatingWindowHost)d;
+            if (host != null && host.bottomBar != null)
+            {
+                host.bootstrapButton.Style = e.NewValue as Style;
+            }
+        }
+
+        #endregion
+
+        #region public Style WindowIconStyle
+
+        /// <summary>
+        /// Gets or sets the style of the WindowIcon.
+        /// </summary>
+        public Style WindowIconStyle
+        {
+            get { return GetValue(WindowIconStyleProperty) as Style; }
+            set { SetValue(WindowIconStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.WindowIconStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty WindowIconStyleProperty =
+            DependencyProperty.Register(
+                "WindowIconStyle",
+                typeof(Style),
+                typeof(FloatingWindowHost),
+                new PropertyMetadata(WindowIconStylePropertyChanged));
+
+        /// <summary>
+        /// WindowIconStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindowHost object whose WindowIconStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void WindowIconStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindowHost host = (FloatingWindowHost)d;
+            if (host != null && host.iconBar != null)
+            {
+                host.iconBar.WindowIconStyle = e.NewValue as Style;
+            }
+        }
+
+        #endregion
+
+        #region public bool SnapinEnabled
+
+        /// <summary>
+        /// Gets or sets a value indicating whether snap in is enabled.
+        /// </summary>
+        /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value>
+        public bool SnapinEnabled
+        {
+            get { return (bool)GetValue(SnapinEnabledProperty); }
+            set { SetValue(SnapinEnabledProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.SnapinEnabled" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.SnapinEnabled" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty SnapinEnabledProperty =
+            DependencyProperty.Register(
+            "SnapinEnabled",
+            typeof(bool),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(true, null));
+
+        #endregion
+
+        #region public double SnapinDistance
+
+        /// <summary>
+        /// Gets or sets a value of the snap in distance.
+        /// </summary>
+        /// <value>Snap in distance.</value>
+        public double SnapinDistance
+        {
+            get { return (double)GetValue(SnapinDistanceProperty); }
+            set { SetValue(SnapinDistanceProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.SnapinDistance" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.SnapinDistance" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty SnapinDistanceProperty =
+            DependencyProperty.Register(
+            "SnapinDistance",
+            typeof(double),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(SnapinDistanceDefaultValue, null));
+
+        #endregion
+
+        #region public double SnapinMargin
+
+        /// <summary>
+        /// Gets or sets a value of the snap in margin - distance between adjacent edges.
+        /// </summary>
+        /// <value>Snap in margin.</value>
+        public double SnapinMargin
+        {
+            get { return (double)GetValue(SnapinMarginProperty); }
+            set { SetValue(SnapinMarginProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.SnapinMargin" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.SnapinMargin" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty SnapinMarginProperty =
+            DependencyProperty.Register(
+            "SnapinMargin",
+            typeof(double),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(0.0, null));
+
+        #endregion
+
+        #region public bool ShowMinimizedOnlyInIconbar
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to show only minimized windows in the iconbar.
+        /// </summary>
+        /// <value><c>true</c> if to show only minimized windows in the iconbar; otherwise, <c>false</c>.</value>
+        public bool ShowMinimizedOnlyInIconbar
+        {
+            get { return (bool)GetValue(ShowMinimizedOnlyInIconbarProperty); }
+            set { SetValue(ShowMinimizedOnlyInIconbarProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.ShowMinimizedOnlyInIconbarProperty" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.ShowMinimizedOnlyInIconbarProperty" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty ShowMinimizedOnlyInIconbarProperty =
+            DependencyProperty.Register(
+            "ShowMinimizedOnlyInIconbar",
+            typeof(bool),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(false, null));
+
+        #endregion
+
+        #region public Brush OverlayBrush
+
+        /// <summary>
+        /// Gets or sets the overlay color.
+        /// </summary>
+        /// <value>The overlay color.</value>
+        public Brush OverlayBrush
+        {
+            get { return (Brush)GetValue(OverlayBrushProperty); }
+            set { SetValue(OverlayBrushProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.OverlayBrush" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.OverlayBrush" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty OverlayBrushProperty =
+            DependencyProperty.Register(
+            "OverlayBrush",
+            typeof(Brush),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(new SolidColorBrush(Color.FromArgb(0x90, 0x20, 0x20, 0x30)), OnOverlayBrushPropertyChanged));
+
+        /// <summary>
+        /// OverlayBrushProperty PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">FloatingWindowHost object whose OverlayBrush property is changed.</param>
+        /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param>
+        private static void OnOverlayBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            FloatingWindowHost host = (FloatingWindowHost)d;
+
+            if (host != null && host.overlay != null)
+                host.overlay.Background = (Brush)e.NewValue;
+        }
+
+        #endregion
+
+        #region public double IconWidth
+
+        /// <summary>
+        /// Gets or sets the width of the window's icon.
+        /// </summary>
+        /// <value>The width of the window's icon.</value>
+        public double IconWidth
+        {
+            get { return (double)GetValue(IconWidthProperty); }
+            set { SetValue(IconWidthProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.IconWidth" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.IconWidth" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconWidthProperty =
+            DependencyProperty.Register(
+            "IconWidth",
+            typeof(double),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(DefaultIconWidth, null));
+
+        #endregion
+
+        #region public double IconHeight
+
+        /// <summary>
+        /// Gets or sets the height of the window's icon.
+        /// </summary>
+        /// <value>The height of the window's icon.</value>
+        public double IconHeight
+        {
+            get { return (double)GetValue(IconHeightProperty); }
+            set { SetValue(IconHeightProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.IconHeight" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.IconHeight" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconHeightProperty =
+            DependencyProperty.Register(
+            "IconHeight",
+            typeof(double),
+            typeof(FloatingWindowHost),
+            new PropertyMetadata(DefaultIconHeight, null));
+
+        #endregion
+
+        #region public object Bar
+
+        /// <summary>
+        /// Gets or sets a control displayed in the BottomBar.
+        /// </summary>
+        /// <value>The control displayed in the BottomBar. The default is null.</value>
+        public object Bar
+        {
+            get { return (double)GetValue(BarProperty); }
+            set { SetValue(BarProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="FloatingWindowHost.Bar" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="FloatingWindowHost.Bar" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty BarProperty =
+            DependencyProperty.Register(
+            "Bar",
+            typeof(object),
+            typeof(FloatingWindowHost),
+            null);
+
+        #endregion
+
+        /// <summary>
+        /// Gets a collection of windows shown in the IconBar.
+        /// </summary>
+        /// <value>Collection of windows shown in the IconBar.</value>
+        public IOrderedEnumerable<FloatingWindow> WindowsInIconBar
+        {
+            get
+            {
+                var windows = from window in this.FloatingWindows
+                              where window.IsOpen && window.ShowInIconbar &&
+                              !(ShowMinimizedOnlyInIconbar && window.WindowState != WindowState.Minimized)
+                              orderby window.IconText
+                              select window;
+
+                return windows;
+            }
+        }
+
+        /// <summary>
+        /// Gets the host panel, containing the floating windows.
+        /// </summary>
+        /// <value>The host panel.</value>
+        public Canvas HostPanel
+        {
+            get { return hostCanvas; }
+        }
+
+        /// <summary>
+        /// Gets the floating windows collection.
+        /// </summary>
+        /// <value>The floating windows collection.</value>
+        public IEnumerable<FloatingWindow> FloatingWindows
+        {
+            get { return hostCanvas.Children.OfType<FloatingWindow>(); }
+        }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the layout of the FloatingWindowHost is updated.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if the layout of the FloatingWindowHost is updated; otherwise, <c>false</c>.
+        /// </value>
+        internal bool IsLayoutUpdated { get; private set; }
+
+        /// <summary>
+        /// Gets current modal window.
+        /// </summary>
+        /// <value>The modal window.</value>
+        private FloatingWindow ModalWindow
+        {
+            get { return modalCanvas.Children.OfType<FloatingWindow>().FirstOrDefault(); }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FloatingWindowHost"/> class.
+        /// </summary>
+        public FloatingWindowHost()
+        {
+            DefaultStyleKey = typeof(FloatingWindowHost);
+        }
+
+        /// <summary>
+        /// Builds the visual tree for the <see cref="FloatingWindowHost" /> control 
+        /// when a new template is applied.
+        /// </summary>
+        public override void OnApplyTemplate()
+        {
+            UnsubscribeFromEvents();
+            UnsubscribeFromTemplatePartEvents();
+
+            base.OnApplyTemplate();
+
+            root = GetTemplatePart<Grid>(PART_Root);
+            contentRoot = GetTemplatePart<FrameworkElement>(PART_ContentRoot);
+            hostCanvas = GetTemplatePart<Canvas>(PART_HostCanvas);
+            modalCanvas = GetTemplatePart<Canvas>(PART_ModalCanvas);
+            iconBarContainer = GetTemplatePart<FrameworkElement>(PART_IconBarContainer);
+            overlay = GetTemplatePart<Grid>(PART_Overlay);
+            iconBar = GetTemplatePart<IconBar>(PART_IconBar);
+            bottomBar = GetTemplatePart<FrameworkElement>(PART_BottomBar);
+            bootstrapButton = GetTemplatePart<BootstrapButton>(PART_BootstrapButton);
+            barContent = GetTemplatePart<ContentControl>(PART_BarContent);
+
+            iconBar.FloatingWindowHost = this;
+
+            SetStyles();
+            SubscribeToTemplatePartEvents();
+            SubscribeToEvents();
+
+            templateIsApplied = true;
+        }
+
+        #region Events
+
+        /// <summary>
+        /// Occurs when the <see cref="FloatingWindowHost" /> is loaded and its template is applied.
+        /// </summary>
+        public event EventHandler Rendered;
+
+        /// <summary>
+        /// Occurs when the active <see cref="FloatingWindow" /> is changed.
+        /// </summary>
+        public event EventHandler<ActiveWindowChangedEventArgs> ActiveWindowChanged;
+
+        #endregion Events
+
+        /// <summary>
+        /// Adds the specified floating window to the collection of child elements of the host.
+        /// </summary>
+        /// <param name="window">The floating window.</param>
+        /// <exception cref="ArgumentNullException">Floating window is null.</exception>
+        public void Add(FloatingWindow window)
+        {
+            if (window == null)
+                throw new ArgumentNullException("window");
+
+            // Guarantee that the visual tree of the control is complete
+            if (!templateIsApplied)
+                templateIsApplied = ApplyTemplate();
+
+            if (!hostCanvas.Children.Contains(window))
+            {
+                hostCanvas.Children.Add(window);
+                window.FloatingWindowHost = this;
+            }
+        }
+
+        /// <summary>
+        /// Removes the specified floating window from the collection of child elements of the host.
+        /// </summary>
+        /// <param name="window">The floating window.</param>
+        public void Remove(FloatingWindow window)
+        {
+            if (window != null)
+            {
+                hostCanvas.Children.Remove(window);
+                modalCanvas.Children.Remove(window);
+                iconBar.Remove(window);
+            }
+        }
+
+        /// <summary>
+        /// Closes all floating windows.
+        /// </summary>
+        public void CloseAllWindows()
+        {
+            HideIconBar();
+            FloatingWindows.ToList().ForEach(x => x.Close());
+        }
+
+        /// <summary>
+        /// Shows the IconBar.
+        /// </summary>
+        public void ShowIconBar()
+        {
+            iconBar.Show();
+        }
+
+        /// <summary>
+        /// Hides the IconBar.
+        /// </summary>
+        public void HideIconBar()
+        {
+            iconBar.Hide();
+        }
+
+        /// <summary>
+        /// Updates the IconBar if it is open.
+        /// </summary>
+        public void UpdateIconBar()
+        {
+            iconBar.Update();
+        }
+
+        /// <summary>
+        /// Sets the specified floating window topmost, and set Focus on it.
+        /// </summary>
+        /// <param name="window">FloatingWindow to set topmost.</param>
+        /// <exception cref="ArgumentNullException">FloatingWindow is null.</exception>
+        public void SetTopmostWindow(FloatingWindow window)
+        {
+            if (window == null)
+                throw new ArgumentNullException("window");
+
+            FloatingWindow topmostWindow = GetTopmostWindow();
+            if (topmostWindow == null || window != topmostWindow)
+            {
+                SetTopmost(window);
+                SetFocusToActiveWindow(window);
+
+                if (!window.TopMost && !window.IsModal)
+                    ShowTopmostWindows();
+
+                ActiveWindowChangedEventArgs e = new ActiveWindowChangedEventArgs(topmostWindow, window);
+                OnActiveWindowChanged(e);
+            }
+        }
+
+        /// <summary>
+        /// Activates the topmost window and sets focus on it.
+        /// </summary>
+        public void ActivateTopmostWindow()
+        {
+            // First, try to activate a modal window, if exists
+            var topmostWindow = this.ModalWindow;
+
+            if (topmostWindow == null)
+                topmostWindow = GetTopmostWindow();
+
+            SetFocusToActiveWindow(topmostWindow);
+
+            ActiveWindowChangedEventArgs e = new ActiveWindowChangedEventArgs(null, topmostWindow);
+            OnActiveWindowChanged(e);
+        }
+
+        /// <summary>
+        /// Gets Snap In bounds as bounds of the host and all open windows except the specified one.
+        /// </summary>
+        /// <param name="windowToExclude">The window to exclude from the list.</param>
+        /// <returns>List of bounding rectangles.</returns>
+        internal IEnumerable<Rect> GetSnapinBounds(FloatingWindow windowToExclude)
+        {
+            List<Rect> bounds = new List<Rect>();
+
+            // Add host bounds
+            bounds.Add(hostCanvas.GetActualBoundingRectangle());
+
+            if (!overlay.IsVisible())
+            {
+                foreach (var window in FloatingWindows)
+                {
+                    if (window != windowToExclude && window.IsOpen)
+                        bounds.Add(window.BoundingRectangle);
+                }
+            }
+
+            return bounds;
+        }
+
+        /// <summary>
+        /// Shows the overlay, moves the window to the "modal" layer and hides the IconBar.
+        /// </summary>
+        /// <param name="modalWindow">The modal window.</param>
+        internal void ShowWindowAsModal(FloatingWindow modalWindow)
+        {
+            HideIconBar();
+            VisualStateManager.GoToState(this, VSMSTATE_VisibleOverlay, true);
+
+            MoveWindowToModalLayer(modalWindow);
+        }
+
+        /// <summary>
+        /// Removes the overlay under the modal window.
+        /// </summary>
+        internal void RemoveOverlay()
+        {
+            if (overlay.IsVisible())
+            {
+                FloatingWindow topmostWindow = null;
+
+                if (FloatingWindows.Count(x => x.IsOpen && x.IsModal) == 0)
+                {
+                    // If there are no more modal windows - remove the overlay
+                    VisualStateManager.GoToState(this, VSMSTATE_HiddenOverlay, true);
+
+                    topmostWindow = GetTopmostWindow();
+                }
+                else
+                {
+                    topmostWindow = GetTopmostModalWindow();
+
+                    if (topmostWindow != null)
+                        topmostWindow.MoveToContainer(modalCanvas);
+                }
+
+                SetFocusToActiveWindow(topmostWindow);
+            }
+        }
+
+        /// <summary>
+        /// Moves the window to the "modal" layer.
+        /// </summary>
+        /// <param name="modalWindow">The modal window.</param>
+        private void MoveWindowToModalLayer(FloatingWindow modalWindow)
+        {
+            FloatingWindow window = this.ModalWindow;
+            if (window != null && window != modalWindow)
+            {
+                // If there is already a modal window - move it to the HostCanvas
+                window.MoveToContainer(hostCanvas);
+                SetTopmost(window);
+            }
+
+            modalWindow.MoveToContainer(modalCanvas);
+        }
+
+        /// <summary>
+        /// Raises the <see cref="FloatingWindowHost.ActiveWindowChanged" /> event.
+        /// </summary>
+        /// <param name="e">The event data.</param>
+        protected virtual void OnActiveWindowChanged(ActiveWindowChangedEventArgs e)
+        {
+            EventHandler<ActiveWindowChangedEventArgs> handler = ActiveWindowChanged;
+
+            if (handler != null)
+                handler(this, e);
+        }
+
+        /// <summary>
+        /// Shows a floating window when the layout is updated.
+        /// </summary>
+        /// <param name="action">A method that displays a window in the specified coordinates.</param>
+        /// <param name="point">Coordinates of the upper-left corner of the window.</param>
+        internal void ShowWindow(Action<Point> action, Point point)
+        {
+            if (IsLayoutUpdated)
+            {
+                action(point);
+            }
+            else
+            {
+                this.Rendered += (s, e) => { action(point); };
+            }
+        }
+
+        /// <summary>
+        /// Shows a floating window when the layout is updated.
+        /// </summary>
+        /// <param name="action">A method that displays a window taking into account specified margins.</param>
+        /// <param name="margins">Window margins.</param>
+        internal void ShowWindow(Action<Thickness> action, Thickness margins)
+        {
+            if (IsLayoutUpdated)
+            {
+                action(margins);
+            }
+            else
+            {
+                this.Rendered += (s, e) => { action(margins); };
+
+            }
+        }
+
+        /// <summary>
+        /// Subscribes to the events on the template parts.
+        /// </summary>
+        private void SubscribeToTemplatePartEvents()
+        {
+            bootstrapButton.Click += new RoutedEventHandler(BootstrapButton_Click);
+            iconBar.Opened += new EventHandler(IconBarVisibilityChanged);
+            iconBar.Closed += new EventHandler(IconBarVisibilityChanged);
+            hostCanvas.SizeChanged += new SizeChangedEventHandler(HostCanvas_SizeChanged);
+            modalCanvas.SizeChanged += new SizeChangedEventHandler(ModalCanvas_SizeChanged);
+            iconBarContainer.SizeChanged += new SizeChangedEventHandler(IconBarContainer_SizeChanged);
+        }
+
+        /// <summary>
+        /// Unsubscribe from the events that are subscribed on the template part elements.
+        /// </summary>
+        private void UnsubscribeFromTemplatePartEvents()
+        {
+            if (bootstrapButton != null)
+                bootstrapButton.Click -= new RoutedEventHandler(BootstrapButton_Click);
+
+            if (iconBar != null)
+                iconBar.Opened -= new EventHandler(IconBarVisibilityChanged);
+
+            if (iconBar != null)
+                iconBar.Closed -= new EventHandler(IconBarVisibilityChanged);
+
+            if (hostCanvas != null)
+                hostCanvas.SizeChanged -= new SizeChangedEventHandler(HostCanvas_SizeChanged);
+
+            if (modalCanvas != null)
+                modalCanvas.SizeChanged -= new SizeChangedEventHandler(ModalCanvas_SizeChanged);
+
+            if (iconBarContainer != null)
+                iconBarContainer.SizeChanged -= new SizeChangedEventHandler(IconBarContainer_SizeChanged);
+        }
+
+        /// <summary>
+        /// Subscribes to the events the control shall handle.
+        /// </summary>
+        private void SubscribeToEvents()
+        {
+            this.MouseLeftButtonDown += new MouseButtonEventHandler(FloatingWindowHost_MouseLeftButtonDown);
+            this.LayoutUpdated += new EventHandler(FloatingWindowHost_LayoutUpdated);
+        }
+
+        /// <summary>
+        /// Unsubscribes from the subscribed events.
+        /// </summary>
+        private void UnsubscribeFromEvents()
+        {
+            this.MouseLeftButtonDown -= new MouseButtonEventHandler(FloatingWindowHost_MouseLeftButtonDown);
+            this.LayoutUpdated -= new EventHandler(FloatingWindowHost_LayoutUpdated);
+        }
+
+        /// <summary>
+        /// Handles the first LayoutUpdated event of the FloatingWindowHost control to raise the OnRendered event.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        private void FloatingWindowHost_LayoutUpdated(object sender, EventArgs e)
+        {
+            if (!IsLayoutUpdated)
+            {
+                this.LayoutUpdated -= new EventHandler(FloatingWindowHost_LayoutUpdated);
+                IsLayoutUpdated = true;
+                OnRendered(EventArgs.Empty);
+            }
+        }
+
+        /// <summary>
+        /// Raises the <see cref="E:Rendered"/> event. 
+        /// Occures when the control template is applied and the control can be rendered.
+        /// </summary>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        protected virtual void OnRendered(EventArgs e)
+        {
+            EventHandler handler = Rendered;
+
+            if (handler != null)
+                handler(this, e);
+        }
+
+        /// <summary>
+        /// Gets the topmost open FloatingWindow.
+        /// </summary>
+        /// <returns>The topmost open FloatingWindow.</returns>
+        private FloatingWindow GetTopmostWindow()
+        {
+            var topmost = (from window in FloatingWindows
+                           where !window.TopMost && window.IsOpen && window.WindowState != WindowState.Minimized
+                           select new
+                           {
+                               Window = window,
+                               ZIndex = Canvas.GetZIndex(window)
+                           }
+                           ).ToList().OrderBy(x => x.ZIndex).LastOrDefault();
+
+            return topmost != null ? topmost.Window : null;
+        }
+
+        /// <summary>
+        /// Gets the topmost modal FloatingWindow on the HostCanvas.
+        /// </summary>
+        /// <returns>The topmost modal FloatingWindow.</returns>
+        private FloatingWindow GetTopmostModalWindow()
+        {
+            var topmost = (from window in FloatingWindows
+                           where window.IsModal && window.IsOpen
+                           select new
+                           {
+                               Window = window,
+                               ZIndex = Canvas.GetZIndex(window)
+                           }
+                           ).ToList().OrderBy(x => x.ZIndex).LastOrDefault();
+
+            return topmost != null ? topmost.Window : null;
+        }
+
+        /// <summary>
+        /// Shows the topmost windows in front of other windows.
+        /// </summary>
+        private void ShowTopmostWindows()
+        {
+            FloatingWindows
+                .Where(x => x.IsOpen && x.TopMost).ToList()
+                .ForEach(x => SetTopmost(x));
+        }
+
+        /// <summary>
+        /// Sets the specified UIElement topmost.
+        /// </summary>
+        /// <param name="element">UIElement to set topmost.</param>
+        /// <exception cref="ArgumentNullException">UIElement is null.</exception>
+        private void SetTopmost(UIElement element)
+        {
+            if (element == null)
+                throw new ArgumentNullException("element");
+
+            zIndex++;
+            Canvas.SetZIndex(element, zIndex);
+        }
+
+        /// <summary>
+        /// Attempts to set the focus on the FloatingWindow.
+        /// </summary>
+        /// <param name="window">The window.</param>
+        private void SetFocusToActiveWindow(FloatingWindow window)
+        {
+            if (window != null && !window.TopMost)
+                window.Focus();
+        }
+
+        /// <summary>
+        /// Handles the MouseLeftButtonDown event of the FloatingWindowHost control. 
+        /// Closes the IconBar on mouse left click.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
+        private void FloatingWindowHost_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
+        {
+            e.Handled = false;
+            HideIconBar();
+        }
+
+        /// <summary>
+        /// Handles the Click event of the BootstrapButton.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+        private void BootstrapButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (bootstrapButton.IsOpen)
+                ShowIconBar();
+            else
+                HideIconBar();
+        }
+
+        /// <summary>
+        /// Handles the IconBar Visibility Changed event.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        private void IconBarVisibilityChanged(object sender, EventArgs e)
+        {
+            bootstrapButton.IsOpen = iconBar.IsOpen;
+        }
+
+        /// <summary>
+        /// Handles the SizeChanged event of the HostCanvas control to set its clipping region.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void HostCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            hostCanvas.Clip = new RectangleGeometry()
+            {
+                Rect = hostCanvas.GetActualBoundingRectangle()
+            };
+        }
+
+        /// <summary>
+        /// Handles the SizeChanged event of the ModalCanvas control to set its clipping region.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void ModalCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            modalCanvas.Clip = new RectangleGeometry()
+            {
+                Rect = modalCanvas.GetActualBoundingRectangle()
+            };
+        }
+
+        /// <summary>
+        /// Handles the SizeChanged event of the IconBarContainer control to set its clipping region.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void IconBarContainer_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            iconBarContainer.Clip = new RectangleGeometry()
+            {
+                Rect = iconBarContainer.GetActualBoundingRectangle()
+            };
+        }
+
+        /// <summary>
+        /// Sets styles that are applied for different template parts.
+        /// </summary>
+        private void SetStyles()
+        {
+            if (bottomBar != null && this.BottomBarStyle != null)
+                bottomBar.Style = this.BottomBarStyle;
+
+            if (bootstrapButton != null && this.BootstrapButtonStyle != null)
+                bootstrapButton.Style = this.BootstrapButtonStyle;
+
+            if (iconBar != null && this.WindowIconStyle != null)
+                iconBar.WindowIconStyle = this.WindowIconStyle;
+        }
+
+        /// <summary>
+        /// Gets the FrameworkElement template part with the specified name.
+        /// </summary>
+        /// <typeparam name="T">The template part type.</typeparam>
+        /// <param name="partName">The template part name.</param>
+        /// <returns>The requested element.</returns>
+        /// <exception cref="NotImplementedException">The template part not found.</exception>
+        private T GetTemplatePart<T>(string partName) where T : class
+        {
+            T part = this.GetTemplateChild(partName) as T;
+
+            if (part == null)
+                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName));
+
+            return part;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/IconBar.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,527 @@
+using System;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media.Animation;
+using SilverFlow.Controls.Extensions;
+using SilverFlow.Controls.Helpers;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// IconBar containing window icons.
+    /// </summary>
+    [TemplatePart(Name = PART_LayoutRoot, Type = typeof(FrameworkElement))]
+    [TemplatePart(Name = PART_FixedBar, Type = typeof(Border))]
+    [TemplatePart(Name = PART_SlidingBar, Type = typeof(Border))]
+    [TemplatePart(Name = PART_Carousel, Type = typeof(StackPanel))]
+    [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_States)]
+    [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_States)]
+    [StyleTypedProperty(Property = PROPERTY_TitleStyle, StyleTargetType = typeof(Border))]
+    [StyleTypedProperty(Property = PROPERTY_WindowIconStyle, StyleTargetType = typeof(WindowIcon))]
+    public class IconBar : ContentControl, INotifyPropertyChanged
+    {
+        // Template parts
+        private const string PART_LayoutRoot = "PART_LayoutRoot";
+        private const string PART_FixedBar = "PART_FixedBar";
+        private const string PART_SlidingBar = "PART_SlidingBar";
+        private const string PART_Carousel = "PART_Carousel";
+
+        // VSM groups
+        private const string VSMGROUP_States = "VisualStateGroup";
+
+        // VSM states
+        private const string VSMSTATE_StateOpen = "Open";
+        private const string VSMSTATE_StateClosed = "Closed";
+
+        // Style typed properties
+        private const string PROPERTY_TitleStyle = "IconBarStyle";
+        private const string PROPERTY_WindowIconStyle = "WindowIconStyle";
+
+        // Animation duration in milliseconds
+        private const double SlidingDurationInMilliseconds = 200;
+
+        #region public Style IconBarStyle
+
+        /// <summary>
+        /// Gets or sets the style of the IconBar.
+        /// </summary>
+        public Style IconBarStyle
+        {
+            get { return GetValue(IconBarStyleProperty) as Style; }
+            set { SetValue(IconBarStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="IconBar.IconBarStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty IconBarStyleProperty =
+            DependencyProperty.Register(
+                "IconBarStyle",
+                typeof(Style),
+                typeof(IconBar),
+                new PropertyMetadata(IconBarStylePropertyChanged));
+
+        /// <summary>
+        /// IconBarStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">IconBar object whose IconBarStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void IconBarStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            IconBar iconBar = (IconBar)d;
+            if (iconBar != null && iconBar.fixedBar != null)
+            {
+                iconBar.fixedBar.Style = e.NewValue as Style;
+            }
+        }
+
+        #endregion
+
+        #region public Style WindowIconStyle
+
+        /// <summary>
+        /// Gets or sets the style of the WindowIcon.
+        /// </summary>
+        public Style WindowIconStyle
+        {
+            get { return GetValue(WindowIconStyleProperty) as Style; }
+            set { SetValue(WindowIconStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="IconBar.WindowIconStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty WindowIconStyleProperty =
+            DependencyProperty.Register(
+                "WindowIconStyle",
+                typeof(Style),
+                typeof(IconBar),
+                null);
+
+        #endregion
+
+        private FrameworkElement layoutRoot;
+        private Border fixedBar;
+        private Border slidingBar;
+        private StackPanel carousel;
+        private Storyboard closingStoryboard;
+        private Storyboard openingStoryboard;
+        private bool isOpen;
+        private double slidingBarPosition;
+        private IVisualHelper visualHelper;
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the IconBar is open.
+        /// </summary>
+        /// <value><c>true</c> if the IconBar is open; otherwise, <c>false</c>.</value>
+        public bool IsOpen
+        {
+            get { return isOpen; }
+            private set
+            {
+                if (value != isOpen)
+                {
+                    isOpen = value;
+                    OnPropertyChanged(new PropertyChangedEventArgs("IsOpen"));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the FloatingWindowHost containing the IconBar.
+        /// </summary>
+        /// <value>FloatingWindowHost containing the IconBar.</value>
+        public FloatingWindowHost FloatingWindowHost { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="IconBar"/> class.
+        /// </summary>
+        public IconBar()
+        {
+            DefaultStyleKey = typeof(IconBar);
+            visualHelper = new VisualHelper();
+        }
+
+        /// <summary>
+        /// Occurs when the <see cref="IconBar" /> is opened.
+        /// </summary>
+        public event EventHandler Opened;
+
+        /// <summary>
+        /// Occurs when the <see cref="IconBar" /> is closed.
+        /// </summary>
+        public event EventHandler Closed;
+
+        #region INotifyPropertyChanged implementation
+        /// <summary>
+        /// Occurs when a property changed.
+        /// </summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// Raises the <see cref="E:PropertyChanged"/> event.
+        /// </summary>
+        /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
+        public void OnPropertyChanged(PropertyChangedEventArgs e)
+        {
+            if (PropertyChanged != null)
+                PropertyChanged(this, e);
+        }
+        #endregion
+
+        /// <summary>
+        /// Builds the visual tree for the <see cref="IconBar" /> control 
+        /// when a new template is applied.
+        /// </summary>
+        public override void OnApplyTemplate()
+        {
+            UnsubscribeFromEvents();
+
+            base.OnApplyTemplate();
+
+            layoutRoot = GetTemplatePart<FrameworkElement>(PART_LayoutRoot);
+            fixedBar = GetTemplatePart<Border>(PART_FixedBar);
+            slidingBar = GetTemplatePart<Border>(PART_SlidingBar);
+            carousel = GetTemplatePart<StackPanel>(PART_Carousel);
+
+            SetStyles();
+            GetStoryboards();
+            SubscribeToEvents();
+        }
+
+        /// <summary>
+        /// Shows the IconBar.
+        /// </summary>
+        public void Show()
+        {
+            if (!IsOpen)
+            {
+                FillCarousel();
+                SetSlidingBarPosition(0);
+                VisualStateManager.GoToState(this, VSMSTATE_StateOpen, true);
+            }
+        }
+
+        /// <summary>
+        /// Hides the IconBar.
+        /// </summary>
+        public void Hide()
+        {
+            if (IsOpen)
+            {
+                VisualStateManager.GoToState(this, VSMSTATE_StateClosed, true);
+            }
+        }
+
+        /// <summary>
+        /// Updates the IconBar if it is open.
+        /// </summary>
+        public void Update()
+        {
+            if (IsOpen)
+            {
+                FillCarousel();
+            }
+        }
+
+        /// <summary>
+        /// Removes the specified window from the IconBar.
+        /// </summary>
+        /// <param name="window">The window to remove from the IconBar.</param>
+        public void Remove(FloatingWindow window)
+        {
+            if (window != null)
+            {
+                var icon = (from windowIcon in carousel.Children.OfType<WindowIcon>()
+                            where windowIcon.Window == window
+                            select windowIcon).FirstOrDefault();
+
+                if (icon != null)
+                {
+                    icon.Click -= new RoutedEventHandler(Icon_Click);
+                    carousel.Children.Remove(icon);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the storyboards defined in the <see cref="IconBar" /> style.
+        /// </summary>
+        private void GetStoryboards()
+        {
+            var groups = VisualStateManager.GetVisualStateGroups(layoutRoot) as Collection<VisualStateGroup>;
+            if (groups != null)
+            {
+                var states = (from stategroup in groups
+                              where stategroup.Name == IconBar.VSMGROUP_States
+                              select stategroup.States).FirstOrDefault() as Collection<VisualState>;
+
+                if (states != null)
+                {
+                    openingStoryboard = (from state in states
+                                         where state.Name == IconBar.VSMSTATE_StateOpen
+                                         select state.Storyboard).FirstOrDefault();
+
+                    closingStoryboard = (from state in states
+                                         where state.Name == IconBar.VSMSTATE_StateClosed
+                                         select state.Storyboard).FirstOrDefault();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Subscribes to the events after new template is applied. 
+        /// </summary>
+        private void SubscribeToEvents()
+        {
+            if (closingStoryboard != null)
+                closingStoryboard.Completed += new EventHandler(Closing_Completed);
+
+            if (openingStoryboard != null)
+                openingStoryboard.Completed += new EventHandler(Opening_Completed);
+
+            if (fixedBar != null)
+                fixedBar.MouseMove += new MouseEventHandler(Bar_MouseMove);
+
+            if (fixedBar != null)
+                fixedBar.SizeChanged += new SizeChangedEventHandler(FixedBar_SizeChanged);
+        }
+
+        /// <summary>
+        /// Unsubscribe from events. 
+        /// </summary>
+        private void UnsubscribeFromEvents()
+        {
+            if (closingStoryboard != null)
+                closingStoryboard.Completed -= new EventHandler(Closing_Completed);
+
+            if (openingStoryboard != null)
+                openingStoryboard.Completed -= new EventHandler(Opening_Completed);
+
+            if (fixedBar != null)
+                fixedBar.MouseMove += new MouseEventHandler(Bar_MouseMove);
+
+            if (fixedBar != null)
+                fixedBar.SizeChanged -= new SizeChangedEventHandler(FixedBar_SizeChanged);
+        }
+
+        /// <summary>
+        /// Sets styles that are applied for different template parts.
+        /// </summary>
+        private void SetStyles()
+        {
+            if (fixedBar != null && this.IconBarStyle != null)
+                fixedBar.Style = this.IconBarStyle;
+        }
+
+        /// <summary>
+        /// Executed when the Closing storyboard ends.
+        /// </summary>
+        /// <param name="sender">Sender object.</param>
+        /// <param name="e">Event args.</param>
+        private void Closing_Completed(object sender, EventArgs e)
+        {
+            IsOpen = false;
+            ClearCarousel();
+            OnClosed(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Executed when the Opening storyboard finishes.
+        /// </summary>
+        /// <param name="sender">Sender object.</param>
+        /// <param name="e">Event args.</param>
+        private void Opening_Completed(object sender, EventArgs e)
+        {
+            IsOpen = true;
+            OnOpened(EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Raises the <see cref="E:Opened"/> event.
+        /// </summary>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        protected virtual void OnOpened(EventArgs e)
+        {
+            EventHandler handler = Opened;
+
+            if (handler != null)
+                handler(this, e);
+        }
+
+        /// <summary>
+        /// Raises the <see cref="E:Closed"/> event.
+        /// </summary>
+        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+        protected virtual void OnClosed(EventArgs e)
+        {
+            EventHandler handler = Closed;
+
+            if (handler != null)
+                handler(this, e);
+        }
+
+        /// <summary>
+        /// Add windows icons to the carousel.
+        /// </summary>
+        private void FillCarousel()
+        {
+            ClearCarousel();
+
+            Style style = this.WindowIconStyle ?? Application.Current.Resources["WindowIconStyle"] as Style;
+            foreach (var window in this.FloatingWindowHost.WindowsInIconBar)
+            {
+                WindowIcon icon = new WindowIcon()
+                {
+                    Style = style,
+                    Title = window.IconText,
+                    Thumbnail = window.WindowThumbnail,
+                    FlowDirection = window.FlowDirection,
+                    Window = window,
+                    IconWidth = this.FloatingWindowHost.IconWidth,
+                    IconHeight = this.FloatingWindowHost.IconHeight
+                };
+
+                icon.Click += new RoutedEventHandler(Icon_Click);
+                carousel.Children.Add(icon);
+            }
+        }
+
+        /// <summary>
+        /// Remove Icon Click event handlers and clear the carousel.
+        /// </summary>
+        private void ClearCarousel()
+        {
+            foreach (var icon in carousel.Children.OfType<WindowIcon>())
+            {
+                icon.Click -= new RoutedEventHandler(Icon_Click);
+            }
+
+            carousel.Children.Clear();
+        }
+
+        /// <summary>
+        /// Handles the Click event of the Icon control.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
+        private void Icon_Click(object sender, RoutedEventArgs e)
+        {
+            WindowIcon icon = sender as WindowIcon;
+
+            if (icon != null && icon.Window != null)
+            {
+                this.Hide();
+                icon.Window.RestoreWindow();
+            }
+        }
+
+        /// <summary>
+        /// Handles the MouseMove event of the Bar control. It implements "Carousel" logic.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.Input.MouseEventArgs"/> instance containing the event data.</param>
+        private void Bar_MouseMove(object sender, MouseEventArgs e)
+        {
+            // Get absolute mouse position
+            Point mousePosition = e.GetPosition(null);
+
+            var icon = carousel.Children.OfType<WindowIcon>().FirstOrDefault();
+
+            // If there is at least one icon on the bar
+            if (icon != null)
+            {
+                double a = e.GetPosition(fixedBar).X;
+                double b = fixedBar.ActualWidth - fixedBar.Padding.Horizontal();
+                double c = slidingBar.ActualWidth;
+
+                // If sliding bar does not fit into the bar, shift the sliding bar
+                if (c > b)
+                {
+                    double width = b - icon.ActualWidth;
+                    if (width != 0)
+                    {
+                        a -= icon.ActualWidth / 2;
+                        if (a < 0) a = 0;
+                        if (a > width) a = width;
+
+                        double x = Math.Round((a / width) * (b - c));
+
+                        if (x != slidingBarPosition)
+                        {
+                            Storyboard storyboard = slidingBar.AnimateDoubleProperty("(Canvas.Left)", null, x, SlidingDurationInMilliseconds);
+                            storyboard.Completed += (s, args) =>
+                                {
+                                    // Select an icon on storyboard completion
+                                    // That is necessary because MouseOver state won't be proceeded correctly
+                                    SlidingBarStoryboardCompleted(mousePosition);
+                                    slidingBarPosition = x;
+                                };
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Handles the Completed event of the SlidingBarStoryboard control.
+        /// </summary>
+        /// <param name="mousePosition">Absolute mouse position.</param>
+        private void SlidingBarStoryboardCompleted(Point mousePosition)
+        {
+            // Find selected icon
+            var selectedIcon = (from item in visualHelper.FindElementsInCoordinates(mousePosition, carousel).OfType<WindowIcon>()
+                                select item).FirstOrDefault();
+
+            // Select an icon in mouse position
+            foreach (var icon in carousel.Children.OfType<WindowIcon>())
+            {
+                icon.Selected = selectedIcon != null && icon == selectedIcon;
+            }
+        }
+
+        /// <summary>
+        /// Handles the SizeChanged event of the FixedBar control.
+        /// Sets the initial position of the sliding bar.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
+        private void FixedBar_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+            if (slidingBarPosition != 0)
+                SetSlidingBarPosition(0);
+        }
+
+        /// <summary>
+        /// Sets the sliding bar position.
+        /// </summary>
+        /// <param name="position">X-coordinate of the sliding bar.</param>
+        private void SetSlidingBarPosition(double x)
+        {
+            slidingBarPosition = x;
+            Canvas.SetLeft(slidingBar, slidingBarPosition);
+        }
+
+        /// <summary>
+        /// Gets the FrameworkElement template part with the specified name.
+        /// </summary>
+        /// <typeparam name="T">The template part type.</typeparam>
+        /// <param name="partName">The template part name.</param>
+        /// <returns>The requested element.</returns>
+        /// <exception cref="NotImplementedException">The template part not found.</exception>
+        private T GetTemplatePart<T>(string partName) where T : class
+        {
+            T part = this.GetTemplateChild(partName) as T;
+
+            if (part == null)
+                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName));
+
+            return part;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/WindowIcon.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,210 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Controls
+{
+    /// <summary>
+    /// Window icon containing a thumbnail and title of the windows.
+    /// </summary>
+    [TemplatePart(Name = PART_Border, Type = typeof(Border))]
+    [TemplatePart(Name = PART_Title, Type = typeof(TextBlock))]
+    [TemplatePart(Name = PART_Thumbnail, Type = typeof(Image))]
+    [StyleTypedProperty(Property = PROPERTY_IconBorderStyle, StyleTargetType = typeof(Border))]
+    public class WindowIcon : Button
+    {
+        // Template parts
+        private const string PART_Border = "PART_Border";
+        private const string PART_Title = "PART_Title";
+        private const string PART_Thumbnail = "PART_Thumbnail";
+
+        // VSM states
+        private const string VSMSTATE_StateNormal = "Normal";
+        private const string VSMSTATE_StateMouseOver = "MouseOver";
+
+        // Style typed properties
+        private const string PROPERTY_IconBorderStyle = "IconBorderStyle";
+
+        #region public Style IconBorderStyle
+
+        /// <summary>
+        /// Gets or sets the style of the WindowIcon.
+        /// </summary>
+        public Style IconBorderStyle
+        {
+            get { return GetValue(IconBorderStyleProperty) as Style; }
+            set { SetValue(IconBorderStyleProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="IconBar.IconBorderStyleProperty" /> dependency property.
+        /// </summary>
+        public static readonly DependencyProperty IconBorderStyleProperty =
+            DependencyProperty.Register(
+                "IconBorderStyle",
+                typeof(Style),
+                typeof(WindowIcon),
+                new PropertyMetadata(IconBorderStylePropertyChanged));
+
+        /// <summary>
+        /// IconBorderStyle PropertyChangedCallback call back static function.
+        /// </summary>
+        /// <param name="d">WindowIcon object whose IconBorderStyle property is changed.</param>
+        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
+        private static void IconBorderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            WindowIcon windowIcon = (WindowIcon)d;
+            if (windowIcon != null && windowIcon.border != null)
+            {
+                windowIcon.border.Style = e.NewValue as Style;
+            }
+        }
+
+        #endregion
+
+        #region public double IconWidth
+
+        /// <summary>
+        /// Gets or sets the width of the window's icon.
+        /// </summary>
+        /// <value>The width of the window's icon.</value>
+        public double IconWidth
+        {
+            get { return (double)GetValue(IconWidthProperty); }
+            set { SetValue(IconWidthProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="WindowIcon.IconWidth" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="WindowIcon.IconWidth" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconWidthProperty =
+            DependencyProperty.Register(
+            "IconWidth",
+            typeof(double),
+            typeof(WindowIcon),
+            null);
+
+        #endregion
+
+        #region public double IconHeight
+
+        /// <summary>
+        /// Gets or sets the height of the window's icon.
+        /// </summary>
+        /// <value>The height of the window's icon.</value>
+        public double IconHeight
+        {
+            get { return (double)GetValue(IconHeightProperty); }
+            set { SetValue(IconHeightProperty, value); }
+        }
+
+        /// <summary>
+        /// Identifies the <see cref="WindowIcon.IconHeight" /> dependency property.
+        /// </summary>
+        /// <value>
+        /// The identifier for the <see cref="WindowIcon.IconHeight" /> dependency property.
+        /// </value>
+        public static readonly DependencyProperty IconHeightProperty =
+            DependencyProperty.Register(
+            "IconHeight",
+            typeof(double),
+            typeof(WindowIcon),
+            null);
+
+        #endregion
+
+        private Border border;
+        private TextBlock title;
+        private Image thumbnail;
+        private bool selected;
+
+        /// <summary>
+        /// Gets or sets the window title that is displayed on the icon />.
+        /// </summary>
+        /// <value>The title displayed on the icon.</value>
+        public string Title { get; set; }
+
+        /// <summary>
+        /// Gets or sets the thumbnail.
+        /// </summary>
+        /// <value>The thumbnail.</value>
+        public ImageSource Thumbnail { get; set; }
+
+        /// <summary>
+        /// Gets or sets the FloatingWindow associated with the icon.
+        /// </summary>
+        /// <value>Floating window.</value>
+        public FloatingWindow Window { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this <see cref="WindowIcon"/> is selected.
+        /// </summary>
+        /// <value><c>true</c> if selected; otherwise, <c>false</c>.</value>
+        public bool Selected
+        {
+            get { return selected; }
+            set
+            {
+                if (value != selected)
+                {
+                    selected = value;
+                    VisualStateManager.GoToState(
+                        this,
+                        value ? VSMSTATE_StateMouseOver : VSMSTATE_StateNormal,
+                        true);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Builds the visual tree for the <see cref="WindowIcon" /> control 
+        /// when a new template is applied.
+        /// </summary>
+        public override void OnApplyTemplate()
+        {
+            base.OnApplyTemplate();
+
+            border = GetTemplatePart<Border>(PART_Border);
+            title = GetTemplatePart<TextBlock>(PART_Title);
+            thumbnail = GetTemplatePart<Image>(PART_Thumbnail);
+
+            SetStyles();
+
+            title.Text = Title;
+            title.FlowDirection = this.FlowDirection;
+            thumbnail.Source = Thumbnail;
+        }
+
+        /// <summary>
+        /// Sets styles that are applied for different template parts.
+        /// </summary>
+        private void SetStyles()
+        {
+            if (border != null && this.IconBorderStyle != null)
+                border.Style = this.IconBorderStyle;
+        }
+
+        /// <summary>
+        /// Gets the FrameworkElement template part with the specified name.
+        /// </summary>
+        /// <typeparam name="T">The template part type.</typeparam>
+        /// <param name="partName">The template part name.</param>
+        /// <returns>The requested element.</returns>
+        /// <exception cref="NotImplementedException">The template part not found.</exception>
+        private T GetTemplatePart<T>(string partName) where T : class
+        {
+            T part = this.GetTemplateChild(partName) as T;
+
+            if (part == null)
+                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName));
+
+            return part;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Geometry/Distance.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,73 @@
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Geometry
+{
+    /// <summary>
+    /// Defines displacement used for correction of window position or size.
+    /// </summary>
+    public class Distance
+    {
+        /// <summary>
+        /// Gets or sets displacement by X coordinate.
+        /// </summary>
+        /// <value>Displacement by X coordinate.</value>
+        public double X { get; set; }
+
+        /// <summary>
+        /// Gets or sets displacement by Y coordinate.
+        /// </summary>
+        /// <value>Displacement by Y coordinate.</value>
+        public double Y { get; set; }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance is nonzero.
+        /// </summary>
+        /// <value>
+        /// 	<c>true</c> if this instance is nonzero; otherwise, <c>false</c>.
+        /// </value>
+        public bool IsNonzero
+        {
+            get
+            {
+                return !double.IsNaN(X) && !double.IsNaN(Y) && (X != 0 || Y != 0);
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Distance"/> class.
+        /// </summary>
+        public Distance()
+        {
+            X = double.NaN;
+            Y = double.NaN;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Distance"/> class.
+        /// </summary>
+        /// <param name="x">Displacement by X coordinate.</param>
+        /// <param name="y">Displacement by Y coordinate.</param>
+        public Distance(double x, double y)
+        {
+            X = x;
+            Y = y;
+        }
+
+        /// <summary>
+        /// Gets the smallest of two distances.
+        /// </summary>
+        /// <param name="first">First distance.</param>
+        /// <param name="second">Second distance.</param>
+        /// <returns>Smallest distance.</returns>
+        public static Distance Min(Distance first, Distance second)
+        {
+            Distance distance = new Distance
+            {
+                X = MathExtensions.AbsMin(first.X, second.X),
+                Y = MathExtensions.AbsMin(first.Y, second.Y)
+            };
+
+            return distance;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Geometry/Trail.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,41 @@
+using System;
+using System.Windows;
+
+namespace SilverFlow.Geometry
+{
+    /// <summary>
+    /// Mouse pointer trail.
+    /// </summary>
+    public class Trail
+    {
+        /// <summary>
+        /// Gets or sets mouse position.
+        /// </summary>
+        /// <value>The position.</value>
+        public Point Position { get; set; }
+
+        /// <summary>
+        /// Gets or sets the timestamp.
+        /// </summary>
+        /// <value>The timestamp.</value>
+        public DateTime Timestamp { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Trail"/> class.
+        /// </summary>
+        public Trail()
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Trail"/> class.
+        /// </summary>
+        /// <param name="point">Point.</param>
+        /// <param name="time">Time.</param>
+        public Trail(Point point, DateTime time)
+        {
+            this.Position = point;
+            this.Timestamp = time;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Geometry/Vector2.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,156 @@
+using System;
+using System.Windows;
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Geometry
+{
+    /// <summary>
+    /// Defines two-dimensional vector.
+    /// </summary>
+    public class Vector2
+    {
+        /// <summary>
+        /// Gets or sets the starting point of the vector.
+        /// </summary>
+        /// <value>The starting point.</value>
+        public Point Start { get; set; }
+
+        /// <summary>
+        /// Gets or sets the ending point of the vector.
+        /// </summary>
+        /// <value>The ending point.</value>
+        public Point End { get; set; }
+
+        /// <summary>
+        /// Gets a value indicating whether this instance is not set.
+        /// </summary>
+        /// <value><c>true</c> if this instance is not set; otherwise, <c>false</c>.</value>
+        public bool IsNaN
+        {
+            get
+            {
+                return this.Start.IsNotSet() || this.End.IsNotSet();
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the vector is of zero length.
+        /// </summary>
+        /// <value><c>true</c> if the vector is of zero length; otherwise, <c>false</c>.</value>
+        public bool IsZero
+        {
+            get
+            {
+                return this.IsNaN ? true : this.Start == this.End;
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the vector is vertical.
+        /// </summary>
+        /// <value>
+        /// 	<c>true</c> if the vector is vertical; otherwise, <c>false</c>.
+        /// </value>
+        public bool IsVertical
+        {
+            get
+            {
+                return !this.IsZero && (this.Start.X == this.End.X);
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the vector is horizontal.
+        /// </summary>
+        /// <value>
+        /// 	<c>true</c> if the vector is horizontal; otherwise, <c>false</c>.
+        /// </value>
+        public bool IsHorizontal
+        {
+            get
+            {
+                return !this.IsZero && (this.Start.Y == this.End.Y);
+            }
+        }
+
+        /// <summary>
+        /// Gets the length of the vector by X-coordinate.
+        /// </summary>
+        /// <value>The length by X-coordinate.</value>
+        public double LengthX
+        {
+            get
+            {
+                return this.IsNaN ? 0 : (this.End.X - this.Start.X);
+            }
+        }
+
+        /// <summary>
+        /// Gets the length of the vector by Y-coordinate.
+        /// </summary>
+        /// <value>The length by Y-coordinate.</value>
+        public double LengthY
+        {
+            get
+            {
+                return this.IsNaN ? 0 : (this.End.Y - this.Start.Y);
+            }
+        }
+
+        /// <summary>
+        /// Gets the length of the vector.
+        /// </summary>
+        /// <value>The length of the vector.</value>
+        public double Length
+        {
+            get
+            {
+                if (this.IsNaN) 
+                    return 0;
+
+                return Math.Sqrt(LengthX * LengthX + LengthY * LengthY);
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Vector2"/> class.
+        /// </summary>
+        public Vector2()
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Vector2"/> class.
+        /// </summary>
+        /// <param name="start">The starting point.</param>
+        /// <param name="end">The ending point.</param>
+        public Vector2(Point start, Point end)
+        {
+            this.Start = start;
+            this.End = end;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Vector2"/> class.
+        /// </summary>
+        /// <param name="start">The starting point.</param>
+        /// <param name="lengthX">The length by X-coordinate.</param>
+        /// <param name="lengthY">The length by Y-coordinate.</param>
+        public Vector2(Point start, double lengthX, double lengthY)
+        {
+            this.Start = start;
+            this.End = start.Add(lengthX, lengthY);
+        }
+
+        /// <summary>
+        /// Rounds starting and ending points to the nearest integer coordinates.
+        /// </summary>
+        /// <returns>Vector with rounded coordinates.</returns>
+        public Vector2 Round()
+        {
+            this.Start = this.Start.Round();
+            this.End = this.End.Round();
+            return this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/BitmapHelper.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,57 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using SilverFlow.Controls.Extensions;
+
+namespace SilverFlow.Controls.Helpers
+{
+    /// <summary>
+    /// Bitmap helper.
+    /// </summary>
+    public class BitmapHelper : IBitmapHelper
+    {
+        /// <summary>
+        /// Renders the visual element and returns a bitmap, containing bitmap image of the element.
+        /// </summary>
+        /// <param name="element">The visual element.</param>
+        /// <param name="imageWidth">Image width.</param>
+        /// <param name="imageHeight">Image height.</param>
+        /// <returns>Bitmap image of the element.</returns>
+        public ImageSource RenderVisual(FrameworkElement element, double imageWidth, double imageHeight)
+        {
+            int width = element.Width.IsNotSet() ? (int)element.ActualWidth : (int)element.Width;
+            int height = element.Height.IsNotSet() ? (int)element.ActualHeight : (int)element.Height;
+
+            ScaleTransform transform = null;
+
+            // If the element is an image - do not scale it
+            if (!(element is Image))
+            {
+                // Scale down the element to fit it into the window's thumbnail
+                double scaleX = imageWidth / width;
+                double scaleY = imageHeight / height;
+                double minScale = Math.Min(scaleX, scaleY);
+
+                if (minScale < 1)
+                {
+                    transform = new ScaleTransform
+                    {
+                        ScaleX = minScale,
+                        ScaleY = minScale
+                    };
+
+                    width = (int)(width * minScale);
+                    height = (int)(height * minScale);
+                }
+            }
+
+            WriteableBitmap bitmap = new WriteableBitmap(width, height);
+            bitmap.Render(element, transform);
+            bitmap.Invalidate();
+
+            return bitmap;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/IBitmapHelper.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,20 @@
+using System.Windows;
+using System.Windows.Media;
+
+namespace SilverFlow.Controls.Helpers
+{
+    /// <summary>
+    /// This interface defines methods used the create bitmap images.
+    /// </summary>
+    public interface IBitmapHelper
+    {
+        /// <summary>
+        /// Renders the visual element and returns a bitmap, containing bitmap image of the element.
+        /// </summary>
+        /// <param name="element">The visual element.</param>
+        /// <param name="imageWidth">Image width.</param>
+        /// <param name="imageHeight">Image height.</param>
+        /// <returns>Bitmap image of the element.</returns>
+        ImageSource RenderVisual(FrameworkElement element, double imageWidth, double imageHeight);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/ILocalStorage.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,21 @@
+namespace SilverFlow.Controls.Helpers
+{
+    /// <summary>
+    /// This interface defines isolated storage methods and properties.
+    /// </summary>
+    public interface ILocalStorage
+    {
+        /// <summary>
+        /// Gets or saves the value associated with the specified key.
+        /// </summary>
+        /// <value>The value associated with the specified key.</value>
+        object this[string key] { get; set; }
+
+        /// <summary>
+        /// Determines if the local storage contains the specified key.
+        /// </summary>
+        /// <param name="key">The key for the entry to be located.</param>
+        /// <returns>True if the local storage contains the specified key; otherwise, false.</returns>
+        bool Contains(string key);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/IVisualHelper.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Windows;
+
+namespace SilverFlow.Controls.Helpers
+{
+    /// <summary>
+    /// This interface defines methods used to traverse object relationships 
+    /// in the visual tree.
+    /// </summary>
+    public interface IVisualHelper
+    {
+        /// <summary>
+        /// Retrieves a set of objects that are located within a specified point of an object's coordinate space.
+        /// </summary>
+        /// <param name="intersectingPoint">The point to use as the determination point.</param>
+        /// <param name="subtree">The object to search within.</param>
+        /// <returns>
+        /// An enumerable set of System.Windows.UIElement objects that are determined
+        /// to be located in the visual tree composition at the specified point and within
+        /// the specified subtee.
+        /// </returns>
+        IEnumerable<UIElement> FindElementsInCoordinates(Point intersectingPoint, UIElement subtree);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/LocalStorage.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,38 @@
+using System.IO.IsolatedStorage;
+
+namespace SilverFlow.Controls.Helpers
+{
+    /// <summary>
+    /// Local isolated storage.
+    /// </summary>
+    public class LocalStorage : ILocalStorage
+    {
+        /// <summary>
+        /// Gets or saves the value associated with the specified key.
+        /// </summary>
+        /// <value>The value associated with the specified key.</value>
+        public object this[string key]
+        {
+            get
+            {
+                return IsolatedStorageSettings.ApplicationSettings[key];
+            }
+            set
+            {
+                IsolatedStorageSettings.ApplicationSettings[key] = value;
+            }
+        }
+
+        /// <summary>
+        /// Determines if the local storage contains the specified key.
+        /// </summary>
+        /// <param name="key">The key for the entry to be located.</param>
+        /// <returns>
+        /// True if the local storage contains the specified key; otherwise, false.
+        /// </returns>
+        public bool Contains(string key)
+        {
+            return IsolatedStorageSettings.ApplicationSettings.Contains(key);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Helpers/VisualHelper.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,24 @@
+using System.Collections.Generic;
+using System.Windows;
+using System.Windows.Media;
+
+namespace SilverFlow.Controls.Helpers
+{
+    public class VisualHelper : IVisualHelper
+    {
+        /// <summary>
+        /// Retrieves a set of objects that are located within a specified point of an object's coordinate space.
+        /// </summary>
+        /// <param name="intersectingPoint">The point to use as the determination point.</param>
+        /// <param name="subtree">The object to search within.</param>
+        /// <returns>
+        /// An enumerable set of System.Windows.UIElement objects that are determined
+        /// to be located in the visual tree composition at the specified point and within
+        /// the specified subtee.
+        /// </returns>
+        public IEnumerable<UIElement> FindElementsInCoordinates(Point intersectingPoint, UIElement subtree)
+        {
+            return VisualTreeHelper.FindElementsInHostCoordinates(intersectingPoint, subtree);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Properties/AssemblyInfo.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,36 @@
+using System;
+using System.Reflection;
+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("SilverFlow.Controls")]
+[assembly: AssemblyDescription("FloatingWindow Control Library for Silverlight")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Jevgenij Pankov")]
+[assembly: AssemblyProduct("SilverFlow.Controls")]
+[assembly: AssemblyCopyright("Copyright © 2011")]
+[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)]
+[assembly: CLSCompliant(true)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("00b61972-c1f0-47b6-8507-872060367303")]
+
+// 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("2.0.2")]
+[assembly: AssemblyFileVersion("2.0.2")]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/SilverFlow.Controls.csproj	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3F3D3C8C-9724-4531-A04D-B92049F64686}</ProjectGuid>
+    <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>SilverFlow.Controls</RootNamespace>
+    <AssemblyName>SilverFlow.Controls</AssemblyName>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+    <Utf8Output>true</Utf8Output>
+    <ExpressionBlendVersion>4.0.20525.0</ExpressionBlendVersion>
+  </PropertyGroup>
+  <!-- This property group is only here to support building this project using the 
+       MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs 
+       to set the TargetFrameworkVersion to v3.5 -->
+  <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <RunCodeAnalysis>false</RunCodeAnalysis>
+    <CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System.Windows" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Windows.Controls, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Windows.Browser" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Converters\BooleanToVisibilityConverter.cs" />
+    <Compile Include="Extensions\AnimationExtensions.cs" />
+    <Compile Include="Extensions\ControlExtensions.cs" />
+    <Compile Include="Extensions\GeometryExtensions.cs" />
+    <Compile Include="Extensions\MathExtensions.cs" />
+    <Compile Include="FloatingWindow\ActiveWindowChangedEventArgs.cs" />
+    <Compile Include="FloatingWindow\BootstrapButton.cs" />
+    <Compile Include="FloatingWindow\FloatingWindow.cs" />
+    <Compile Include="FloatingWindow\FloatingWindowHost.cs" />
+    <Compile Include="Controllers\InertiaController.cs" />
+    <Compile Include="Controllers\IResizableElement.cs" />
+    <Compile Include="Controllers\ISnapinController.cs" />
+    <Compile Include="Controllers\SnapinController.cs" />
+    <Compile Include="Controllers\InertialMotion.cs" />
+    <Compile Include="Enums\WindowAction.cs" />
+    <Compile Include="Geometry\Distance.cs" />
+    <Compile Include="Enums\ResizeAnchor.cs" />
+    <Compile Include="Controllers\ResizeController.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Geometry\Trail.cs" />
+    <Compile Include="Geometry\Vector2.cs" />
+    <Compile Include="Helpers\BitmapHelper.cs" />
+    <Compile Include="Helpers\IBitmapHelper.cs" />
+    <Compile Include="Helpers\ILocalStorage.cs" />
+    <Compile Include="Helpers\IVisualHelper.cs" />
+    <Compile Include="Helpers\LocalStorage.cs" />
+    <Compile Include="Helpers\VisualHelper.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="FloatingWindow\IconBar.cs" />
+    <Compile Include="FloatingWindow\WindowIcon.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Themes\generic.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Resource>
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties />
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+  <!-- 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>
+  -->
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverFlow.Controls/Themes/generic.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,787 @@
+<ResourceDictionary
+  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+  xmlns:controls="clr-namespace:SilverFlow.Controls"
+  xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" 
+  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+  xmlns:System="clr-namespace:System;assembly=mscorlib">
+
+    <!-- Window Button Brushes -->
+    <SolidColorBrush x:Key="WindowButtonForeground">#FF9E9E9E</SolidColorBrush>
+    <SolidColorBrush x:Key="WindowButtonBorderBrush">#FFd1d9e1</SolidColorBrush>
+    <Color x:Key="WindowButtonOverColor">White</Color>
+    <Color x:Key="WindowButtonPressedColor">White</Color>
+    <Color x:Key="WindowButtonBorderOverColor">#FF899199</Color>
+    <Color x:Key="WindowButtonBorderPressedColor">#FF0667D4</Color>
+
+    <!-- FloatingWindow Brushes -->
+    <LinearGradientBrush x:Key="FloatingWindowTitleBackgroundBrush" StartPoint="0.5,0" EndPoint="0.5,1">
+        <GradientStop Color="White" Offset="0"/>
+        <GradientStop Color="#FFe7ebed" Offset="1"/>
+    </LinearGradientBrush>
+
+    <Style x:Key="CloseButtonStyle" TargetType="Button">
+        <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/>
+        <Setter Property="BorderThickness" Value="1,0,1,1"/>
+        <Setter Property="Width" Value="25"/>
+        <Setter Property="Height" Value="15"/>
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="VerticalContentAlignment" Value="Top"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" />
+                                        <ColorAnimation Duration="0" To="#FFf9acaf" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FFf64c4c" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" />
+                                        <ColorAnimation Duration="0" To="#FFfa8980" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF9a0000" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+                                    <GradientStop Offset="0"/>
+                                    <GradientStop Offset="1"/>
+                                </LinearGradientBrush>
+                            </Border.Background>
+                            <Canvas Width="8" Height="8">
+                                <Path x:Name="ButtonPath" Data="M0,0 L0.9371469,0 L4,3.0628543 L7.0628557,0 L8,0 L8,1.073151 L5.0731506,4 L8,6.9268494 L8,8 L6.9278555,8 L4,5.0721459 L1.0721471,8 L0,8 L0,7.0948515 L3.0948515,4 L0,0.90514863 z" 
+									          Fill="{TemplateBinding Foreground}" Stretch="None" StrokeThickness="0.5" Stroke="{TemplateBinding Foreground}"
+                                              UseLayoutRounding="True" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" />
+                            </Canvas>
+                        </Border>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="MinimizeButtonStyle" TargetType="Button">
+        <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/>
+        <Setter Property="BorderThickness" Value="1,0,1,1"/>
+        <Setter Property="Margin" Value="0,0,-1,0"/>
+        <Setter Property="Width" Value="21"/>
+        <Setter Property="Height" Value="15"/>
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="VerticalContentAlignment" Value="Top"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent" />
+                                        <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent" />
+                                        <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+                                    <GradientStop Offset="0"/>
+                                    <GradientStop Offset="1"/>
+                                </LinearGradientBrush>
+                            </Border.Background>
+                            <Canvas Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center">
+                                <Rectangle x:Name="ButtonContent" StrokeThickness="0" Width="9" Height="2" Fill="{TemplateBinding Foreground}" Canvas.Top="6" />
+                            </Canvas>
+                        </Border>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="MaximizeButtonStyle" TargetType="Button">
+        <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/>
+        <Setter Property="BorderThickness" Value="1,0,1,1"/>
+        <Setter Property="Margin" Value="0,0,-1,0"/>
+        <Setter Property="Width" Value="21"/>
+        <Setter Property="Height" Value="15"/>
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="VerticalContentAlignment" Value="Top"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent1" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent2" />
+                                        <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent1" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent2" />
+                                        <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+                                    <GradientStop Offset="0"/>
+                                    <GradientStop Offset="1"/>
+                                </LinearGradientBrush>
+                            </Border.Background>
+                            <Canvas Width="9" Height="8">
+                                <Rectangle x:Name="ButtonContent1" StrokeThickness="0" Width="9" Height="2" Fill="{TemplateBinding Foreground}" />
+                                <Rectangle x:Name="ButtonContent2" StrokeThickness="1" Width="9" Height="8" Stroke="{TemplateBinding Foreground}" />
+                            </Canvas>
+                        </Border>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="RestoreButtonStyle" TargetType="Button">
+        <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/>
+        <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/>
+        <Setter Property="BorderThickness" Value="1,0,1,1"/>
+        <Setter Property="Margin" Value="0,0,-1,0"/>
+        <Setter Property="Width" Value="21"/>
+        <Setter Property="Height" Value="15"/>
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="VerticalContentAlignment" Value="Top"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content1" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content2" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content3" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content4" />
+                                        <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content1" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content2" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content3" />
+                                        <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content4" />
+                                        <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                        <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True">
+                            <Border.Background>
+                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+                                    <GradientStop Offset="0"/>
+                                    <GradientStop Offset="1"/>
+                                </LinearGradientBrush>
+                            </Border.Background>
+                            <Canvas Width="9" Height="8">
+                                <Rectangle x:Name="Content1" StrokeThickness="0" Width="7" Height="1" Fill="{TemplateBinding Foreground}" Canvas.Top="3" />
+                                <Rectangle x:Name="Content2" StrokeThickness="1" Width="7" Height="5" Stroke="{TemplateBinding Foreground}" Canvas.Top="3" />
+                                <Path x:Name="Content3" Data="M0.35,0.345 L6.65,0.35 L6.65,5.65 L4.65,5.65 L4.65,3.65625 L0.35,3.65625 z" Width="7" Height="6"
+                                                Stretch="Fill" Stroke="{TemplateBinding Foreground}" StrokeThickness="1" Canvas.Left="2" />
+                                <Rectangle x:Name="Content4" StrokeThickness="0" Width="7" Height="2" Fill="{TemplateBinding Foreground}" Canvas.Left="2" />
+                            </Canvas>
+                        </Border>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="WindowButtonToolTipStyle" TargetType="ToolTip">
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="ToolTip">
+                    <Border Background="#FFf7f8fa" BorderThickness="1" CornerRadius="2" Padding="7,1">
+                        <Border.BorderBrush>
+                            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
+                                <GradientStop Color="#F09EBFCE" Offset="0" />
+                                <GradientStop Color="#F0698795" Offset="1" />
+                            </LinearGradientBrush>
+                        </Border.BorderBrush>
+                        <Border.Effect>
+                            <DropShadowEffect ShadowDepth="0.5" Opacity="0.3" BlurRadius="3" />
+                        </Border.Effect>
+                        <ContentPresenter Content="{TemplateBinding Content}"
+                                          ContentTemplate="{TemplateBinding ContentTemplate}" />
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="FloatingWindowTitleStyle" TargetType="ContentControl">
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="HorizontalAlignment" Value="Stretch"/>
+        <Setter Property="VerticalAlignment" Value="Center"/>
+        <Setter Property="Margin" Value="6,3,6,3"/>
+        <Setter Property="UseLayoutRounding" Value="True"/>
+        <Setter Property="FontWeight" Value="Bold"/>
+        <Setter Property="Foreground" Value="#FF67676C"/>
+        <Setter Property="FontSize" Value="10"/>
+    </Style>
+
+    <Style x:Key="BottomBarStyle" TargetType="Border">
+        <Setter Property="Height" Value="24" />
+        <Setter Property="Background" Value="#FFE7EBED" />
+        <Setter Property="BorderThickness" Value="0,1,0,0" />
+        <Setter Property="BorderBrush" Value="#FFFEFEFE" />
+    </Style>
+
+    <Style x:Key="IconBarStyle" TargetType="Border">
+        <Setter Property="VerticalAlignment" Value="Top" />
+        <Setter Property="Height" Value="104" />
+        <Setter Property="Padding" Value="2,2" />
+        <Setter Property="Background" Value="#FF202F50" />
+    </Style>
+
+    <Style x:Key="IconBorderStyle" TargetType="Border">
+        <Setter Property="Width" Value="140" />
+        <Setter Property="Height" Value="100" />
+        <Setter Property="Margin" Value="0,0,1,0" />
+        <Setter Property="Padding" Value="2" />
+        <Setter Property="VerticalAlignment" Value="Bottom" />
+        <Setter Property="CornerRadius" Value="2" />
+        <Setter Property="BorderThickness" Value="0.7" />
+        <Setter Property="BorderBrush" Value="Transparent" />
+        <Setter Property="Background">
+            <Setter.Value>
+                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
+                    <GradientStop Color="Transparent" Offset="0"/>
+                    <GradientStop Color="Transparent" Offset="1"/>
+                </LinearGradientBrush>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style TargetType="controls:FloatingWindow">
+        <Setter Property="Width" Value="300"/>
+        <Setter Property="Height" Value="200"/>
+        <Setter Property="IsTabStop" Value="False"/>
+        <Setter Property="TabNavigation" Value="Cycle"/>
+        <Setter Property="HorizontalAlignment" Value="Center"/>
+        <Setter Property="VerticalAlignment" Value="Center"/>
+        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
+        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
+        <Setter Property="BorderThickness" Value="1"/>
+        <Setter Property="BorderBrush" Value="#FFA2ADB8"/>
+        <Setter Property="Background" Value="#FFE7EBED" />
+        <Setter Property="TitleBackground" Value="{StaticResource FloatingWindowTitleBackgroundBrush}" />
+
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="controls:FloatingWindow">
+                    <Grid x:Name="Root" RenderTransformOrigin="0.5,0.5">
+                        <Grid.RenderTransform>
+                            <CompositeTransform/>
+                        </Grid.RenderTransform>
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="WindowStates">
+                                <VisualState x:Name="Open">
+                                    <Storyboard>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity">
+                                            <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:00.3" Value="1"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Visible</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Closed">
+                                    <Storyboard>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity">
+                                            <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Minimized">
+                                    <Storyboard>
+                                        <PointAnimation Duration="0" To="0,1" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="ContentRoot" />
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleX">
+                                            <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:0.2" Value="0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleY">
+                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:0.2" Value="0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity">
+                                            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
+                                            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames BeginTime="0" Duration="00:00:0.2" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="00:00:0.2">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Collapsed</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Restored">
+                                    <Storyboard>
+                                        <PointAnimation Duration="0" To="0,1" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="ContentRoot" />
+                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentRoot">
+                                            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                            <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="00:00:00">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Visible</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleX">
+                                            <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:0.3" Value="1" KeySpline="0,0.86,0.19,1"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleY">
+                                            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
+                                            <SplineDoubleKeyFrame KeyTime="00:00:0.3" Value="1" KeySpline="0,0.86,0.19,1"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Grid x:Name="ContentRoot" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" 
+							  RenderTransformOrigin="0,0" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}">
+                            <Grid.Effect>
+                                <DropShadowEffect ShadowDepth="0.5" Opacity="0.35" BlurRadius="12" />
+                            </Grid.Effect>
+                            <Grid.RenderTransform>
+                                <TransformGroup>
+                                    <ScaleTransform />
+                                    <SkewTransform />
+                                    <RotateTransform />
+                                    <TranslateTransform />
+                                </TransformGroup>
+                            </Grid.RenderTransform>
+
+                            <Border x:Name="ContentBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" 
+								BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3">
+                                <Grid>
+                                    <Grid.RowDefinitions>
+                                        <RowDefinition Height="Auto"/>
+                                        <RowDefinition/>
+                                    </Grid.RowDefinitions>
+
+                                    <Border x:Name="Chrome" Width="Auto" Background="{TemplateBinding TitleBackground}" UseLayoutRounding="False" CornerRadius="2,2,0,0">
+                                        <Grid Height="Auto" Width="Auto">
+                                            <Grid.ColumnDefinitions>
+                                                <ColumnDefinition/>
+                                                <ColumnDefinition Width="Auto"/>
+                                                <ColumnDefinition Width="Auto"/>
+                                                <ColumnDefinition Width="6"/>
+                                            </Grid.ColumnDefinitions>
+
+                                            <ContentControl x:Name="TitleContent" Content="{TemplateBinding Title}" Style="{StaticResource FloatingWindowTitleStyle}" />
+
+                                            <StackPanel x:Name="MenuPanel" Orientation="Horizontal"  Grid.Column="1" VerticalAlignment="Top">
+                                                <Button x:Name="MinimizeButton" Style="{StaticResource MinimizeButtonStyle}">
+                                                    <ToolTipService.ToolTip>
+                                                        <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Minimize" />
+                                                    </ToolTipService.ToolTip>
+                                                </Button>
+                                                <Button x:Name="MaximizeButton" Style="{StaticResource MaximizeButtonStyle}">
+                                                    <ToolTipService.ToolTip>
+                                                        <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Maximize" />
+                                                    </ToolTipService.ToolTip>
+                                                </Button>
+                                                <Button x:Name="RestoreButton" Style="{StaticResource RestoreButtonStyle}" Visibility="Collapsed">
+                                                    <ToolTipService.ToolTip>
+                                                        <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Restore" />
+                                                    </ToolTipService.ToolTip>
+                                                </Button>
+                                            </StackPanel>
+                                            <Button x:Name="CloseButton" Style="{StaticResource CloseButtonStyle}" Grid.Column="2">
+                                                <ToolTipService.ToolTip>
+                                                    <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Close" />
+                                                </ToolTipService.ToolTip>
+                                            </Button>
+                                        </Grid>
+                                    </Border>
+                                    <Border Grid.Row="1">
+                                        <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}"
+												ContentTemplate="{TemplateBinding ContentTemplate}"
+												HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+												VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+                                    </Border>
+                                </Grid>
+                            </Border>
+                        </Grid>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="BootstrapButtonStyle" TargetType="controls:BootstrapButton">
+        <Setter Property="Width" Value="24"/>
+        <Setter Property="Height" Value="24"/>
+        <Setter Property="BorderBrush" Value="#FFA2ADB8"/>
+        <Setter Property="Background" Value="#FF4E4E4E"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="IsTabStop" Value="false"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="controls:BootstrapButton">
+                    <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" RenderTransformOrigin="0.5,0.5">
+                        <Grid.RenderTransform>
+                            <CompositeTransform/>
+                        </Grid.RenderTransform>
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualStateGroup.Transitions>
+                                    <VisualTransition GeneratedDuration="0"/>
+                                </VisualStateGroup.Transitions>
+                                <VisualState x:Name="Disabled">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="LightGray" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Normal"/>
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" />
+                                        <DoubleAnimation Duration="0" By="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_Arrow"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                            <VisualStateGroup x:Name="ButtonStates">
+                                <VisualState x:Name="Open">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0:0:0.4" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="PART_Arrow">
+                                            <DoubleAnimation.EasingFunction>
+                                                <CubicEase EasingMode="EaseOut"/>
+                                            </DoubleAnimation.EasingFunction>
+                                        </DoubleAnimation>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Close">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0:0:0.4" To="180" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="PART_Arrow">
+                                            <DoubleAnimation.EasingFunction>
+                                                <CubicEase EasingMode="EaseOut"/>
+                                            </DoubleAnimation.EasingFunction>
+                                        </DoubleAnimation>
+                                        <DoubleAnimation Duration="0:0:0.4" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_Arrow"/>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+
+                        <Ellipse>
+                            <Ellipse.Fill>
+                                <LinearGradientBrush EndPoint="0.691,0.972" StartPoint="0.307,0.037">
+                                    <GradientStop Color="#FFA2ADB8"/>
+                                    <GradientStop Color="White" Offset="1"/>
+                                </LinearGradientBrush>
+                            </Ellipse.Fill>
+                        </Ellipse>
+                        <Ellipse Margin="1">
+                            <Ellipse.Fill>
+                                <LinearGradientBrush EndPoint="0.631,1" MappingMode="RelativeToBoundingBox" StartPoint="0.29,0.045">
+                                    <GradientStop Color="#FFB8C3C8" Offset="1"/>
+                                    <GradientStop Color="#FFE7EBED" Offset="0.27"/>
+                                </LinearGradientBrush>
+                            </Ellipse.Fill>
+                        </Ellipse>
+                        <Path x:Name="PART_Arrow" Data="M27.671843,6 L31.333334,2 L35.02343,6 z" 
+                			HorizontalAlignment="Center" Width="8" Height="4" Stretch="Fill" UseLayoutRounding="False" 
+                			VerticalAlignment="Center" Fill="#FF686D76" RenderTransformOrigin="0.5,0.5">
+                            <Path.RenderTransform>
+                                <CompositeTransform TranslateY="-1"/>
+                            </Path.RenderTransform>
+                        </Path>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style TargetType="controls:FloatingWindowHost">
+        <Setter Property="Width" Value="Auto" />
+        <Setter Property="Height" Value="Auto" />
+        <Setter Property="SnapinEnabled" Value="True" />
+        <Setter Property="SnapinDistance" Value="5" />
+        <Setter Property="SnapinMargin" Value="0" />
+        <Setter Property="ShowMinimizedOnlyInIconbar" Value="False" />
+        <Setter Property="HorizontalAlignment" Value="Stretch" />
+        <Setter Property="VerticalAlignment" Value="Stretch" />
+        <Setter Property="OverlayBrush" Value="#90202030" />
+        <Setter Property="Background" Value="#FF7ED2E9" />
+
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="controls:FloatingWindowHost">
+                    <Grid x:Name="PART_Root" Background="{TemplateBinding Background}" 
+                          Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="OverlayStates">
+                                <VisualState x:Name="VisibleOverlay">
+                                    <Storyboard>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Opacity">
+                                            <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Visible</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="HiddenOverlay">
+                                    <Storyboard>
+                                        <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Opacity">
+                                            <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
+                                        </DoubleAnimationUsingKeyFrames>
+                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Visibility">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.3">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Collapsed</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+
+                        <Grid x:Name="PART_ContentRoot">
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="*" />
+                                <RowDefinition Height="Auto" />
+                            </Grid.RowDefinitions>
+
+                            <Canvas x:Name="PART_HostCanvas" />
+
+                            <Grid x:Name="PART_IconBarContainer" VerticalAlignment="Bottom">
+                                <controls:IconBar x:Name="PART_IconBar"/>
+                            </Grid>
+
+                            <Border x:Name="PART_BottomBar" Grid.Row="1" Style="{StaticResource BottomBarStyle}">
+                                <Grid>
+                                    <Grid.ColumnDefinitions>
+                                        <ColumnDefinition Width="Auto" />
+                                        <ColumnDefinition Width="*" />
+                                    </Grid.ColumnDefinitions>
+
+                                    <controls:BootstrapButton x:Name="PART_BootstrapButton" Style="{StaticResource BootstrapButtonStyle}"
+										Margin="10,-4,10,0" IsOpen="{Binding IsOpen, ElementName=PART_IconBar}" />
+
+                                    <Border Grid.Column="1">
+                                        <ContentControl x:Name="PART_BarContent" Content="{TemplateBinding Bar}" 
+                                                        VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" />
+                                    </Border>
+                                </Grid>
+                            </Border>
+                        </Grid>
+                        
+                        <Grid x:Name="PART_Overlay" Background="{TemplateBinding OverlayBrush}" Opacity="0" Visibility="Collapsed" />
+                        <Canvas x:Name="PART_ModalCanvas" />
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style TargetType="controls:IconBar">
+        <Setter Property="IsTabStop" Value="false"/>
+        <Setter Property="HorizontalAlignment" Value="Stretch"/>
+        <Setter Property="VerticalAlignment" Value="Bottom"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="controls:IconBar">
+                    <Grid x:Name="PART_LayoutRoot">
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="VisualStateGroup">
+                                <VisualState x:Name="Open">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_FixedBar">
+                                            <DoubleAnimation.EasingFunction>
+                                                <CubicEase EasingMode="EaseOut"/>
+                                            </DoubleAnimation.EasingFunction>
+                                        </DoubleAnimation>
+                                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PART_FixedBar">
+                                            <DiscreteObjectKeyFrame KeyTime="0">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Visible</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Closed">
+                                    <Storyboard>
+                                        <DoubleAnimation Duration="0:0:0.2" To="104" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_FixedBar">
+                                            <DoubleAnimation.EasingFunction>
+                                                <CubicEase EasingMode="EaseOut"/>
+                                            </DoubleAnimation.EasingFunction>
+                                        </DoubleAnimation>
+                                        <ObjectAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PART_FixedBar">
+                                            <DiscreteObjectKeyFrame KeyTime="0:0:0.2">
+                                                <DiscreteObjectKeyFrame.Value>
+                                                    <Visibility>Collapsed</Visibility>
+                                                </DiscreteObjectKeyFrame.Value>
+                                            </DiscreteObjectKeyFrame>
+                                        </ObjectAnimationUsingKeyFrames>
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+
+                        <Border x:Name="PART_FixedBar" RenderTransformOrigin="0.5,1" Style="{StaticResource IconBarStyle}">
+                            <Border.RenderTransform>
+                                <!-- Hide the IconBar -->
+                                <CompositeTransform TranslateY="104" />
+                            </Border.RenderTransform>
+
+                            <Canvas>
+                                <Border x:Name="PART_SlidingBar" Canvas.Left="0" VerticalAlignment="Bottom">
+                                    <StackPanel x:Name="PART_Carousel" RenderTransformOrigin="0.5,1" Orientation="Horizontal" 
+                                                  HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
+                                </Border>
+                            </Canvas>
+                        </Border>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+    <Style x:Key="WindowIconStyle" TargetType="controls:WindowIcon">
+        <Setter Property="IsTabStop" Value="false"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="controls:WindowIcon">
+                    <Border x:Name="PART_Border" Style="{StaticResource IconBorderStyle}">
+                        <VisualStateManager.VisualStateGroups>
+                            <VisualStateGroup x:Name="CommonStates">
+                                <VisualStateGroup.Transitions>
+                                    <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.2" To="Normal">
+                                        <VisualTransition.GeneratedEasingFunction>
+                                            <QuadraticEase EasingMode="EaseOut"/>
+                                        </VisualTransition.GeneratedEasingFunction>
+                                    </VisualTransition>
+                                </VisualStateGroup.Transitions>
+                                <VisualState x:Name="Disabled"/>
+                                <VisualState x:Name="Normal" />
+                                <VisualState x:Name="MouseOver">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Title" />
+                                        <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Border" />
+                                        <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="PART_Border" />
+                                        <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="PART_Border" />
+                                    </Storyboard>
+                                </VisualState>
+                                <VisualState x:Name="Pressed">
+                                    <Storyboard>
+                                        <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Title" />
+                                        <ColorAnimation Duration="0" To="#A0FFFFFF" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Border" />
+                                        <ColorAnimation Duration="0" To="#90D0D0E0" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="PART_Border" />
+                                        <ColorAnimation Duration="0" To="#80B0B0F0" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="PART_Border" />
+                                    </Storyboard>
+                                </VisualState>
+                            </VisualStateGroup>
+                        </VisualStateManager.VisualStateGroups>
+                        <Grid>
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="*" />
+                                <RowDefinition Height="Auto" />
+                            </Grid.RowDefinitions>
+                            <Border Grid.Row="0" Padding="2">
+                                <Image x:Name="PART_Thumbnail" Stretch="None" />
+                            </Border>
+                            <Border Grid.Row="1" HorizontalAlignment="Center">
+                                <TextBlock x:Name="PART_Title" Foreground="LightGray" VerticalAlignment="Center" Margin="5,2" TextTrimming="WordEllipsis" FontSize="10.667" />
+                            </Border>
+                        </Grid>
+                    </Border>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+</ResourceDictionary>
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/App.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/App.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -1,39 +1,28 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
 using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
 using SilverlightGlimpse.Services;
 //using Glimpse;
+using System.Reflection;
 
 namespace SilverlightGlimpse.Test
 {
     public partial class App : Application
     {
-
         public App()
         {
-            this.Startup += this.Application_Startup;
-            this.Exit += this.Application_Exit;
-            this.UnhandledException += this.Application_UnhandledException;
+            Startup += Application_Startup;
+            Exit += Application_Exit;
+            UnhandledException += Application_UnhandledException;
 
             InitializeComponent();
         }
 
         private void Application_Startup(object sender, StartupEventArgs e)
         {
-            string appName = "SilverlightGlimpse";
-
             try
             {
-                this.RootVisual = new MainPage();
-                GlimpseService.CreateInstance.Load(this, appName);
+                RootVisual = new MainPage();
+                GlimpseService.CreateInstance.Load(this, Assembly.GetCallingAssembly().FullName);
             }
             catch (Exception ex)
             {
@@ -74,6 +63,7 @@
             }
             catch (Exception)
             {
+                //TODO: log here
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/BuggyControl.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,42 @@
+<UserControl x:Class="SilverlightGlimpse.Test.BuggyControl"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             d:DesignHeight="300"
+             d:DesignWidth="400"
+             mc:Ignorable="d">
+
+    <Grid x:Name="LayoutRoot" Background="White">
+        <ListBox x:Name="listbox1" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
+            <ListBox.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <c:WrapPanel ItemHeight="100"
+                                 ItemWidth="100"
+                                 Orientation="Horizontal" />
+                </ItemsPanelTemplate>
+            </ListBox.ItemsPanel>
+            <ListBox.ItemTemplate>
+                <DataTemplate>
+                    <StackPanel Margin="20" HorizontalAlignment="Center">
+                        <Viewbox>
+                            <Grid x:Name="backgroundGrid"
+                                  Width="48"
+                                  Height="48">
+                                <Rectangle x:Name="Rect" Fill="Orange" />
+                                <TextBlock x:Name="LabelForIdProperty"
+                                           HorizontalAlignment="Center"
+                                           VerticalAlignment="Center"
+                                           FontFamily="Segoe UI"
+                                           FontSize="24"
+                                           Foreground="White"
+                                           Text="{Binding INCORRECTPATH}" />
+                            </Grid>
+                        </Viewbox>
+                    </StackPanel>
+                </DataTemplate>
+            </ListBox.ItemTemplate>
+        </ListBox>
+    </Grid>
+</UserControl>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/BuggyControl.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+
+namespace SilverlightGlimpse.Test
+{
+    public partial class BuggyControl
+    {
+        public BuggyControl()
+        {
+            InitializeComponent();
+
+            var list = new List<object>(5)
+            {
+                new Person { Id = 1 , Name = "Steve"},
+                new Person { Id = 2 , Name = "Dave"},
+                new Person { Id = 3 , Name = "Bob"},
+                new Person { Id = 4 , Name = "Rich"},
+                new Person { Id = 5 , Name = "Clare"}
+            };
+            
+            listbox1.ItemsSource = list;
+        }
+    }
+
+    public class Person
+    {
+        public int Id { get; set; }
+        public string Name { get; set; }
+    }
+}
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -2,6 +2,7 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:local="clr-namespace:SilverlightGlimpse.Test"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              d:DesignHeight="300"
              d:DesignWidth="400"
@@ -9,22 +10,10 @@
 
     <Grid x:Name="LayoutRoot" Background="White">
         <Grid.RowDefinitions>
-            <RowDefinition Height="100" />
+            <RowDefinition Height="800" />
         </Grid.RowDefinitions>
 
-        <Button Width="150"
-                Height="60"
-                Click="Button_Click"
-                Content="Open form" />
-        <ListBox x:Name="Listbox1" Grid.Row="1">
-            <ListBox.ItemTemplate>
-                <DataTemplate>
-                    <StackPanel>
-                        <TextBlock Text="{Binding Id }" />
-                        <TextBlock Text="{Binding FAIL}" />
-                    </StackPanel>
-                </DataTemplate>
-            </ListBox.ItemTemplate>
-        </ListBox>
+        <local:BuggyControl />
+
     </Grid>
 </UserControl>
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -1,37 +1,13 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Dynamic;
-
-namespace SilverlightGlimpse.Test
+namespace SilverlightGlimpse.Test
 {
-    public partial class MainPage : UserControl
+    public partial class MainPage
     {
         public MainPage()
         {
             InitializeComponent();
-            throw new Exception("Test");
-        }
 
-        private void Button_Click(object sender, RoutedEventArgs e)
-        {
-            var list = new List<object>(5)
-            {
-                new { Id = 1 , Name = "Steve"},
-                new { Id = 2 , Name = "Dave"},
-                new { Id = 3 , Name = "Bob"},
-                new { Id = 4 , Name = "Rich"},
-                new { Id = 5 , Name = "Clare"}
-            };
-            this.DataContext = list;
+            // uncomment this exception to view exception on startup 
+            //throw new Exception("This exception has been thrown to demonstrate an exception during startup", new Exception("This is an inner exception"));
         }
     }
 }
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/SilverlightGlimpse.Test.csproj	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse.Test/SilverlightGlimpse.Test.csproj	Sun Apr 22 13:33:42 2012 +0100
@@ -31,6 +31,8 @@
     <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
     <LinkedServerProject>
     </LinkedServerProject>
+    <Utf8Output>true</Utf8Output>
+    <ExpressionBlendVersion>4.1.20402.0</ExpressionBlendVersion>
   </PropertyGroup>
   <!-- This property group is only here to support building this project using the 
        MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs 
@@ -64,10 +66,8 @@
     <Reference Include="System.Windows" />
     <Reference Include="system" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Net" />
-    <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\Libs\System.Windows.Controls.dll</HintPath>
-    </Reference>
+    <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="System.Windows.Controls.Toolkit, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Windows.Browser" />
   </ItemGroup>
@@ -75,6 +75,9 @@
     <Compile Include="App.xaml.cs">
       <DependentUpon>App.xaml</DependentUpon>
     </Compile>
+    <Compile Include="BuggyControl.xaml.cs">
+      <DependentUpon>BuggyControl.xaml</DependentUpon>
+    </Compile>
     <Compile Include="MainPage.xaml.cs">
       <DependentUpon>MainPage.xaml</DependentUpon>
     </Compile>
@@ -85,6 +88,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </ApplicationDefinition>
+    <Page Include="BuggyControl.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="MainPage.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
@@ -99,6 +106,9 @@
       <Name>SilverlightGlimpse</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Service References\" />
+  </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.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.
@@ -114,4 +124,5 @@
       </FlavorProperties>
     </VisualStudio>
   </ProjectExtensions>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Expression\Blend\Silverlight\v5.0\Microsoft.Expression.Blend.Silverlight.targets" />
 </Project>
\ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -1,6 +1,7 @@
 <UserControl x:Class="SilverlightGlimpse.Controls.BrokenBindingsViewer"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             Loaded="BrokenBindings_Loaded">
     <Grid x:Name="LayoutRoot" Background="White">
         <ScrollViewer>
             <ItemsControl x:Name="icBrokenBindings" />
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -1,9 +1,8 @@
-using System.Reflection;
-using System.Windows.Data;
+using System.Diagnostics;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Media;
 using SilverlightGlimpse.Models;
-using System.Windows;
-using System.Diagnostics;
-using System.Windows.Media;
 using SilverlightGlimpse.Services;
 
 namespace SilverlightGlimpse.Controls
@@ -17,74 +16,71 @@
 
         private void BrokenBindings_Loaded(object sender, RoutedEventArgs e)
         {
-            this.icBrokenBindings.Items.Clear();
+            icBrokenBindings.Items.Clear();
             LoadBrokenBindings(GlimpseService.CreateInstance.RootVisual);
         }
 
         private void LoadBrokenBindings(UIElement uiElement)
         {
             var frameworkElement = uiElement as FrameworkElement;
+            if (frameworkElement == null) return;
 
-            if (frameworkElement != null)
+            foreach (var fieldInfo in frameworkElement.GetType().GetFields(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static))
             {
-                foreach (var fieldInfo in frameworkElement.GetType().GetFields(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static))
-                {
-                    if (object.ReferenceEquals(fieldInfo.FieldType, typeof(DependencyProperty)))
-                    {
-                        var bindingExpression = frameworkElement.GetBindingExpression((DependencyProperty)fieldInfo.GetValue(null));
+                if (!ReferenceEquals(fieldInfo.FieldType, typeof (DependencyProperty))) continue;
+                
+                var bindingExpression = frameworkElement.GetBindingExpression((DependencyProperty)fieldInfo.GetValue(null));
 
-                        if (bindingExpression != null && bindingExpression.ParentBinding.Source == null && bindingExpression.ParentBinding.RelativeSource == null)
-                        {
-                            var isInherited = false;
+                if (bindingExpression == null || bindingExpression.ParentBinding.Source != null ||
+                    bindingExpression.ParentBinding.RelativeSource != null) continue;
 
-                            if (frameworkElement.DataContext != null && !string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path))
-                            {
-                                foreach (var propertyInfo in frameworkElement.DataContext.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance))
-                                {
-                                    if (string.Compare(propertyInfo.Name, bindingExpression.ParentBinding.Path.Path) == 0)
-                                    {
-                                        isInherited = true;
-                                        break; // TODO: might not be correct. Was : Exit For
-                                    }
-                                }
-                            }
-
-                            if (isInherited)
-                            {
-                                break; // TODO: might not be correct. Was : Exit For
-                            }
+                var isInherited = false;
 
-                            //this code handles empty bindings on the Button controls
-                            //I'll have to look into why the Button has an empty or unresolved binding
-                            if (string.IsNullOrEmpty(frameworkElement.Name) 
-                                && frameworkElement.GetType().Name == "TextBlock" 
-                                && fieldInfo.Name == "TextProperty" 
-                                && string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path))
-                            {
-                                break; // TODO: might not be correct. Was : Exit For
-                            }
-
-                            BrokenBinding objBrokenBinding = new BrokenBinding(
-                                frameworkElement.Name, 
-                                frameworkElement.GetType().Name, 
-                                fieldInfo.Name, 
-                                bindingExpression.ParentBinding.Path.Path);
-                            this.icBrokenBindings.Items.Add(objBrokenBinding);
-                            Debug.WriteLine("Broken Binding - ", objBrokenBinding.ToString());
+                if (frameworkElement.DataContext != null && !string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path))
+                {
+                    foreach (var propertyInfo in frameworkElement.DataContext.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance))
+                    {
+                        if (string.Compare(propertyInfo.Name, bindingExpression.ParentBinding.Path.Path) == 0)
+                        {
+                            isInherited = true;
+                            break; // TODO: might not be correct. Was : Exit For
                         }
                     }
                 }
 
-                int children = VisualTreeHelper.GetChildrenCount(frameworkElement);
+                if (isInherited)
+                {
+                    break; // TODO: might not be correct. Was : Exit For
+                }
 
-                for (int j = 0; j <= children - 1; j++)
+                //this code handles empty bindings on the Button controls
+                //I'll have to look into why the Button has an empty or unresolved binding
+                if (string.IsNullOrEmpty(frameworkElement.Name) 
+                    && frameworkElement.GetType().Name == "TextBlock" 
+                    && fieldInfo.Name == "TextProperty" 
+                    && string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path))
                 {
-                    FrameworkElement child = VisualTreeHelper.GetChild(frameworkElement, j) as FrameworkElement;
+                    break; // TODO: might not be correct. Was : Exit For
+                }
 
-                    if (child != null)
-                    {
-                        LoadBrokenBindings(child);
-                    }
+                var brokenBinding = new BrokenBinding(
+                    frameworkElement.Name, 
+                    frameworkElement.GetType().Name, 
+                    fieldInfo.Name, 
+                    bindingExpression.ParentBinding.Path.Path);
+                icBrokenBindings.Items.Add(brokenBinding);
+                Debug.WriteLine("Broken Binding: {0}", brokenBinding);
+            }
+
+            int children = VisualTreeHelper.GetChildrenCount(frameworkElement);
+
+            for (int j = 0; j <= children - 1; j++)
+            {
+                var child = VisualTreeHelper.GetChild(frameworkElement, j) as FrameworkElement;
+
+                if (child != null)
+                {
+                    LoadBrokenBindings(child);
                 }
             }
         }
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -1,30 +1,37 @@
 <UserControl x:Class="SilverlightGlimpse.Controls.ExceptionsViewer"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-    <Grid x:Name="LayoutRoot" Background="White">
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             Loaded="ExceptionsViewer_Loaded">
+    <Grid x:Name="LayoutRoot">
+
         <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="250" />
+            <ColumnDefinition Width="150" />
             <ColumnDefinition Width="*" />
         </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto" />
             <RowDefinition Height="*" />
-            <RowDefinition Height="Auto" />
         </Grid.RowDefinitions>
 
-        <TextBlock Grid.ColumnSpan="2"
-                   Margin="3.5"
-                   VerticalAlignment="Center"
-                   FontSize="18"
-                   Foreground="Red"
-                   Text="Exceptions Viewer" />
+        <Grid Grid.Row="1">
+            <Grid.RowDefinitions>
+                <RowDefinition Height="*" />
+                <RowDefinition Height="Auto" />
+            </Grid.RowDefinitions>
 
-        <ListBox x:Name="lbExceptions"
-                 Grid.Row="1"
-                 Margin="3.5"
-                 ItemsSource="{Binding}"
-                 SelectionChanged="lbExceptions_SelectionChanged" />
+            <ListBox x:Name="lbExceptions"
+                     Margin="3.5"
+                     ItemsSource="{Binding}"
+                     SelectionChanged="lbExceptions_SelectionChanged" />
 
+            <Button Grid.Row="1"
+                    Width="135"
+                    Margin="7"
+                    HorizontalAlignment="Center"
+                    VerticalAlignment="Center"
+                    Click="ClearExceptions_Click"
+                    Content="Clear Exceptions" />
+        </Grid>
         <ScrollViewer Grid.Row="1"
                       Grid.Column="1"
                       Margin="3.5"
@@ -42,9 +49,7 @@
                     <RowDefinition Height="Auto" />
                 </Grid.RowDefinitions>
 
-                <Rectangle Fill="BlanchedAlmond" />
                 <TextBlock x:Name="tbAction"
-                           FontSize="14"
                            Text="Action"
                            TextDecorations="Underline" />
                 <TextBlock Grid.Row="1"
@@ -54,10 +59,8 @@
                            Visibility="{Binding ElementName=tbAction,
                                                 Path=Visibility}" />
 
-                <Rectangle Grid.Row="2" Fill="BlanchedAlmond" />
                 <TextBlock Grid.Row="2"
                            Margin="0,7,0,0"
-                           FontSize="14"
                            Text="Control Name"
                            TextDecorations="Underline"
                            Visibility="{Binding ElementName=tbAction,
@@ -69,21 +72,18 @@
                            Visibility="{Binding ElementName=tbAction,
                                                 Path=Visibility}" />
 
-                <Rectangle Grid.Row="4" Fill="BlanchedAlmond" />
                 <TextBlock Grid.Row="4"
                            Margin="0,7,0,0"
-                           FontSize="14"
                            Text="Message"
                            TextDecorations="Underline" />
+
                 <TextBlock Grid.Row="5"
                            FontSize="11"
                            Text="{Binding Path=Exception.Message}"
                            TextWrapping="Wrap" />
 
-                <Rectangle Grid.Row="6" Fill="BlanchedAlmond" />
                 <TextBlock Grid.Row="6"
                            Margin="0,7,0,0"
-                           FontSize="14"
                            Text="Stack Trace"
                            TextDecorations="Underline" />
                 <TextBlock Grid.Row="7"
@@ -93,13 +93,5 @@
 
             </Grid>
         </ScrollViewer>
-        <Button Grid.Row="2"
-                Grid.Column="1"
-                Margin="11"
-                HorizontalAlignment="Right"
-                VerticalAlignment="Center"
-                Click="ClearExceptions_Click"
-                Content="Clear Exceptions"
-                Padding="7" />
     </Grid>
 </UserControl>
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -1,7 +1,6 @@
-using System;
-using System.Windows;
+using System.Windows;
+using System.Windows.Controls;
 using SilverlightGlimpse.Models;
-using System.Windows.Controls;
 using SilverlightGlimpse.Services;
 
 namespace SilverlightGlimpse.Controls 
@@ -20,20 +19,19 @@
 
         private void ExceptionsViewer_Loaded(object sender, RoutedEventArgs e)
         {
-            this.DataContext = GlimpseService.CreateInstance.HostExceptions;
+            DataContext = GlimpseService.CreateInstance.HostExceptions;
             if (GlimpseService.CreateInstance.HostExceptions.Count > 0)
-                this.lbExceptions.SelectedIndex = 0;
+                lbExceptions.SelectedIndex = 0;
         }
 
         private void lbExceptions_SelectionChanged(object sender, SelectionChangedEventArgs e)
         {
-            if (this.lbExceptions.SelectedItem != null && this.lbExceptions.SelectedItem is ExceptionWrapper)
-            {
-                if (((ExceptionWrapper)this.lbExceptions.SelectedItem).IsValidationException)
-                    this.tbAction.Visibility = Visibility.Visible;
-                else
-                    this.tbAction.Visibility = Visibility.Collapsed;
-            }
+            if (lbExceptions.SelectedItem == null || !(lbExceptions.SelectedItem is ExceptionWrapper)) 
+                return;
+
+            tbAction.Visibility = ((ExceptionWrapper)lbExceptions.SelectedItem).IsValidationException 
+                ? Visibility.Visible 
+                : Visibility.Collapsed;
         }
     }
 }
\ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -3,25 +3,28 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
              xmlns:localc="clr-namespace:SilverlightGlimpse.Controls">
-    <Grid x:Name="LayoutRoot" Background="Khaki">
+    <Grid x:Name="LayoutRoot">
         <Grid.Resources>
-            <SolidColorBrush x:Name="noExceptionsBrush" Color="LightGreen" />
+            <SolidColorBrush x:Name="noExceptionsBrush" Color="SteelBlue" />
             <SolidColorBrush x:Name="hasExceptionsBrush" Color="Red" />
         </Grid.Resources>
+
         <Grid x:Name="layoutInstrumentPanel">
             <StackPanel Orientation="Horizontal">
                 <Grid Margin="7">
                     <Ellipse x:Name="elpValidationExceptions"
                              Width="40"
                              Height="40"
-                             Fill="LightGreen"
-                             Stroke="Brown"
-                             StrokeThickness="2" />
+                             Fill="{StaticResource noExceptionsBrush}"
+                             Stroke="LightBlue"
+                             StrokeThickness="3" />
+
                     <TextBlock x:Name="tbValidationExceptions"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                FontSize="12"
                                FontWeight="Bold"
+                               Foreground="White"
                                Text="0"
                                ToolTipService.ToolTip="Binding Exception Count" />
                 </Grid>
@@ -29,20 +32,22 @@
                     <Ellipse x:Name="elpUnhandledExceptions"
                              Width="40"
                              Height="40"
-                             Fill="LightGreen"
-                             Stroke="Brown"
-                             StrokeThickness="2" />
+                             Fill="{StaticResource noExceptionsBrush}"
+                             Stroke="LightBlue"
+                             StrokeThickness="3" />
                     <TextBlock x:Name="tbUnhandledExceptions"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                FontSize="12"
                                FontWeight="Bold"
+                               Foreground="White"
                                Text="0"
                                ToolTipService.ToolTip="Unhandled Exception Count" />
                 </Grid>
                 <Button x:Name="btnExpand"
                         Margin="7"
                         VerticalAlignment="Center"
+                        Click="btnExpand_Click"
                         Content="Expand" />
             </StackPanel>
         </Grid>
@@ -51,28 +56,34 @@
                 <RowDefinition Height="Auto" />
                 <RowDefinition Height="*" />
             </Grid.RowDefinitions>
-            <TextBlock Margin="3.5"
+
+            <TextBlock Margin="3.5,0,0,0"
                        VerticalAlignment="Center"
+                       FontFamily="Lucida Sans Unicode"
                        FontSize="18"
-                       Foreground="DarkGreen"
-                       Text="Glimpse Viewer" />
+                       Foreground="SteelBlue"
+                       Text="Silverlight Glimpse" />
+
             <Button x:Name="btnContract"
                     Margin="7"
                     HorizontalAlignment="Right"
                     VerticalAlignment="Center"
+                    Click="btnContract_Click"
                     Content="Contract" />
+
             <c:TabControl Grid.Row="1"
-                          Width="690"
-                          Height="390"
-                          Background="Khaki"
-                          SelectedIndex="2">
+                          Width="500"
+                          Height="250">
+
                 <c:TabItem Header="Exceptions">
                     <localc:ExceptionsViewer />
                 </c:TabItem>
+
                 <c:TabItem Header="Bindings with no Source">
                     <localc:BrokenBindingsViewer />
                 </c:TabItem>
             </c:TabControl>
+
         </Grid>
     </Grid>
 
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -10,18 +10,18 @@
         public GlimpseViewer()
         {
             InitializeComponent();
-            this.DataContext = GlimpseService.CreateInstance;
+            DataContext = GlimpseService.CreateInstance;
             GlimpseService.CreateInstance.HostExceptions.CollectionChanged += HostExceptions_CollectionChanged;
         }
 
-        private void btnContract_Click(object sender, System.Windows.RoutedEventArgs e)
+        private void btnContract_Click(object sender, RoutedEventArgs e)
         {
-            this.layoutViewer.Visibility = Visibility.Collapsed;
+            layoutViewer.Visibility = Visibility.Collapsed;
         }
 
-        private void btnExpand_Click(object sender, System.Windows.RoutedEventArgs e)
+        private void btnExpand_Click(object sender, RoutedEventArgs e)
         {
-            this.layoutViewer.Visibility = Visibility.Visible;
+            layoutViewer.Visibility = Visibility.Visible;
         }
 
         private void HostExceptions_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -37,17 +37,17 @@
                     unhandledExceptionCount++;
             }
 
-            this.tbValidationExceptions.Text = validationExceptionCount.ToString();
+            tbValidationExceptions.Text = validationExceptionCount.ToString();
 
-            this.elpValidationExceptions.Fill = validationExceptionCount == 0
-                ? this.noExceptionsBrush
-                : this.hasExceptionsBrush;
+            elpValidationExceptions.Fill = validationExceptionCount == 0
+                ? noExceptionsBrush
+                : hasExceptionsBrush;
 
-            this.tbUnhandledExceptions.Text = unhandledExceptionCount.ToString();
+            tbUnhandledExceptions.Text = unhandledExceptionCount.ToString();
 
-            this.elpUnhandledExceptions.Fill = unhandledExceptionCount == 0
-                ? this.noExceptionsBrush
-                : this.hasExceptionsBrush;
+            elpUnhandledExceptions.Fill = unhandledExceptionCount == 0
+                ? noExceptionsBrush
+                : hasExceptionsBrush;
         }
     }
 }
\ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml	Sun Apr 22 13:33:42 2012 +0100
@@ -8,30 +8,26 @@
             BorderThickness="6"
             CornerRadius="5">
         <Grid x:Name="LayoutRoot">
-            <Grid.ColumnDefinitions>
-                <ColumnDefinition Width="200" />
-                <ColumnDefinition Width="*" />
-            </Grid.ColumnDefinitions>
             <Grid.RowDefinitions>
                 <RowDefinition Height="Auto" />
+                <RowDefinition Height="100" />
                 <RowDefinition Height="*" />
             </Grid.RowDefinitions>
 
-            <Rectangle Grid.ColumnSpan="2" Fill="SteelBlue" />
+            <Rectangle Fill="SteelBlue" />
+
             <TextBlock x:Name="txtTitle"
-                       Grid.ColumnSpan="2"
                        Margin="3.5"
                        VerticalAlignment="Center"
                        Foreground="White"
-                       Text="Exception" />
+                       Text="Exception source goes here from code behind" />
 
             <ListBox x:Name="lbExceptions"
                      Grid.Row="1"
                      Margin="3.5"
                      DisplayMemberPath="Message" />
 
-            <ScrollViewer Grid.Row="1"
-                          Grid.Column="1"
+            <ScrollViewer Grid.Row="2"
                           Margin="3.5"
                           Background="White"
                           DataContext="{Binding ElementName=lbExceptions,
@@ -46,24 +42,19 @@
                         <RowDefinition Height="Auto" />
                     </Grid.RowDefinitions>
 
-                    <TextBlock FontSize="14"
-                               Text="Message"
-                               TextDecorations="Underline" />
+                    <TextBlock Text="Message" TextDecorations="Underline" />
                     <TextBlock Grid.Row="1"
-                               FontSize="11"
                                Text="{Binding Path=Message}"
                                TextWrapping="Wrap" />
 
                     <TextBlock Grid.Row="2"
                                Margin="0,11,0,0"
-                               FontSize="14"
                                Text="Stack Trace"
                                TextDecorations="Underline" />
                     <TextBlock Grid.Row="3"
                                FontSize="11"
                                Text="{Binding Path=StackTrace}"
                                TextWrapping="Wrap" />
-
                 </Grid>
             </ScrollViewer>
         </Grid>
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/LoadExceptionViewer.xaml.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -1,9 +1,8 @@
 using System;
-using System.Windows.Controls;
 
 namespace SilverlightGlimpse.Controls
 {
-    public partial class LoadExceptionViewer : UserControl
+    public partial class LoadExceptionViewer
     {
         public LoadExceptionViewer()
         {
@@ -12,19 +11,19 @@
 
         public LoadExceptionViewer(Exception e, string sourceLocation) : this()
         {
-            this.txtTitle.Text = string.Concat("Exception ", sourceLocation.TrimStart());
+            txtTitle.Text = string.Concat("Exception ", sourceLocation.TrimStart());
 
-            Exception ex = e;
+            var ex = e;
 
             while (ex != null)
             {
-                this.lbExceptions.Items.Add(ex);
+                lbExceptions.Items.Add(ex);
                 ex = ex.InnerException;
             }
 
-            if (this.lbExceptions.Items.Count > 0)
+            if (lbExceptions.Items.Count > 0)
             {
-                this.lbExceptions.SelectedIndex = 0;
+                lbExceptions.SelectedIndex = 0;
             }
         }
     }
--- a/SilverlightGlimpse/SilverlightGlimpse/Services/GlimpseService.cs	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/Services/GlimpseService.cs	Sun Apr 22 13:33:42 2012 +0100
@@ -30,7 +30,7 @@
 
         public static GlimpseService CreateInstance
         {
-            get { return (_instance == null) ? _instance = new GlimpseService() : _instance; }
+            get { return _instance ?? (_instance = new GlimpseService()); }
         }
 
         internal Application App { get; private set; }
@@ -45,30 +45,32 @@
 
         public void DisplayLoadFailure(Application app, Exception ex)
         {
-            string source = ex.StackTrace.Substring(0, ex.StackTrace.IndexOf(Environment.NewLine));
-            Debug.WriteLine("{0} had exception. {1}", this.HostApplicationName, ex.ToString());
+            var source = ex.StackTrace.Substring(0, ex.StackTrace.IndexOf(Environment.NewLine, StringComparison.Ordinal));
+            Debug.WriteLine("{0} had exception. {1}", HostApplicationName, ex);
             App = app;
             App.RootVisual = new LoadExceptionViewer(ex, source);
         }
 
         public void Load(Application app, string hostApplicationName)
         {
-            this.App = app;
-            this.RootVisual = App.RootVisual as FrameworkElement;
-            this.HostApplicationName = hostApplicationName;
+            App = app;
+            RootVisual = App.RootVisual as FrameworkElement;
+            HostApplicationName = hostApplicationName;
 
             RootVisual.BindingValidationError += HostRootVisual_BindingValidationError;
             App.UnhandledException += Application_UnhandledException;
 
-            FloatableWindow window = new FloatableWindow();
-            window.Title = this.HostApplicationName;
-            window.Content = new GlimpseViewer();
-            window.ParentLayoutRoot = (Panel)VisualTreeHelper.GetChild(RootVisual, 0); ;
-
+            GlimpseWindow = new FloatableWindow
+            {
+                Title = this.HostApplicationName,
+                Content = new GlimpseViewer(),
+                ParentLayoutRoot = (Panel) VisualTreeHelper.GetChild(RootVisual, 0),
+                ResizeMode = ResizeMode.NoResize
+            };
             if (Double.IsNaN(RootVisual.Width))
             {
                 //if the host control is autosized (consumes the browser window) then locate Glimpse in the top, left
-                window.Show();
+                GlimpseWindow.Show(10,10);
             }
             else
             {
@@ -78,7 +80,7 @@
                 if (dblLeft < 0)
                     dblLeft = 0;
 
-                window.Show(dblLeft,10);
+                GlimpseWindow.Show(dblLeft, 10);
             }
         }
         #endregion
--- a/SilverlightGlimpse/SilverlightGlimpse/SilverlightGlimpse.csproj	Sun Apr 22 09:01:20 2012 +0100
+++ b/SilverlightGlimpse/SilverlightGlimpse/SilverlightGlimpse.csproj	Sun Apr 22 13:33:42 2012 +0100
@@ -64,12 +64,10 @@
     <Reference Include="System.Windows" />
     <Reference Include="system" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Net" />
     <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\Libs\System.Windows.Controls.dll</HintPath>
     </Reference>
     <Reference Include="System.Xml" />
-    <Reference Include="System.Windows.Browser" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Controls\BrokenBindingsViewer.xaml.cs">
Binary file SilverlightValidation/SilverlightValidation.zip has changed