protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            controlMouseMoveLocation = e.Location;

            bool needsRefresh = false;

            LayoutProperties layoutProperties = new LayoutProperties();

            layoutProperties.DesignAreaLocation       = DesignAreaLocation;
            layoutProperties.DesignAreaSize           = DesignAreaSize;
            layoutProperties.ViewportLocation         = ViewportLocation;
            layoutProperties.ViewportSize             = ViewportSize;
            layoutProperties.ZoomRatio                = ZoomRatio;
            layoutProperties.ControlMouseDownLocation = controlMouseDownLocation;
            layoutProperties.ControlMouseMoveLocation = controlMouseMoveLocation;

            if (selectedElements != null)
            {
                foreach (LayoutElement selectedElement in selectedElements)
                {
                    TransformHandle handle = DesignerHelper.GetTransformHandleType(selectedElement, layoutProperties, controlMouseMoveLocation);
                    Cursor = DesignerHelper.GetCursorForTransformHandle(handle);
                }
            }

            if (isMouseDown)
            {
                // move
                if (interactionState == InteractionState.None && mouseHitsSelection && DesignerHelper.ExceedsThreshold(controlMouseMoveLocation, controlMouseDownLocation, MOVE_THRESHOLD))
                {
                    interactionState = InteractionState.Move;

                    // store offsets by mouse location
                    selectedElementOffsets = new List <Point>();
                    foreach (LayoutElement selectedElement in selectedElements)
                    {
                        Point selectedElementLocation = selectedElement.Location.Multiply(ZoomRatio);

                        selectedElementLocation = selectedElementLocation.Add(DesignAreaLocation);
                        selectedElementLocation = selectedElementLocation.Subtract(ViewportLocation);

                        selectedElementOffsets.Add(new Point(controlMouseMoveLocation.X - selectedElementLocation.X,
                                                             controlMouseMoveLocation.Y - selectedElementLocation.Y));
                    }
                }

                if (interactionState == InteractionState.SizeAttempt && DesignerHelper.ExceedsThreshold(controlMouseMoveLocation, controlMouseDownLocation, SIZE_THRESHOLD))
                {
                    interactionState    = InteractionState.Size;
                    interactionLocation = SelectedElement.Location;
                    interactionSize     = SelectedElement.Size;
                    needsRefresh        = true;
                }

                if (interactionState == InteractionState.Move)
                {
                    for (int i = 0; i < selectedElements.Count; i++)
                    {
                        LayoutElement selectedElement       = selectedElements[i];
                        Point         selectedElementOffset = selectedElementOffsets[i];

                        int selectedElementX = controlMouseMoveLocation.X + ViewportLocation.X - DesignAreaLocation.X;
                        selectedElementX -= selectedElementOffset.X;

                        int selectedElementY = controlMouseMoveLocation.Y + ViewportLocation.Y - DesignAreaLocation.Y;
                        selectedElementY -= selectedElementOffset.Y;

                        selectedElement.Location = new Point(selectedElementX, selectedElementY).Divide(ZoomRatio);
                    }

                    needsRefresh = true;
                }

                if (interactionState == InteractionState.Size)
                {
                    int locationX  = interactionLocation.X;
                    int locationY  = interactionLocation.Y;
                    int sizeWidth  = interactionSize.Width;
                    int sizeHeight = interactionSize.Height;

                    if (!KeyboardHelper.IsShiftKeyPressed)
                    {
                        if (transformHandle == TransformHandle.TopLeft)
                        {
                            locationX  = DesignAreaMouseMoveLocation.X;
                            locationY  = DesignAreaMouseMoveLocation.Y;
                            sizeWidth  = interactionLocation.X + interactionSize.Width - DesignAreaMouseMoveLocation.X;
                            sizeHeight = interactionLocation.Y + interactionSize.Height - DesignAreaMouseMoveLocation.Y;
                        }
                        else if (transformHandle == TransformHandle.TopCenter)
                        {
                            locationX  = interactionLocation.X;
                            locationY  = DesignAreaMouseMoveLocation.Y;
                            sizeWidth  = interactionSize.Width;
                            sizeHeight = interactionLocation.Y + interactionSize.Height - DesignAreaMouseMoveLocation.Y;
                        }
                        else if (transformHandle == TransformHandle.TopRight)
                        {
                            locationX  = interactionLocation.X;
                            locationY  = DesignAreaMouseMoveLocation.Y;
                            sizeWidth  = DesignAreaMouseMoveLocation.X - interactionLocation.X;
                            sizeHeight = interactionLocation.Y + interactionSize.Height - DesignAreaMouseMoveLocation.Y;
                        }
                        else if (transformHandle == TransformHandle.Left)
                        {
                            locationX  = DesignAreaMouseMoveLocation.X;
                            locationY  = interactionLocation.Y;
                            sizeWidth  = interactionLocation.X + interactionSize.Width - DesignAreaMouseMoveLocation.X;
                            sizeHeight = interactionSize.Height;
                        }
                        else if (transformHandle == TransformHandle.Right)
                        {
                            sizeWidth = DesignAreaMouseMoveLocation.X - interactionLocation.X;
                        }
                        else if (transformHandle == TransformHandle.BottomLeft)
                        {
                            locationX  = DesignAreaMouseMoveLocation.X;
                            locationY  = interactionLocation.Y;
                            sizeWidth  = interactionLocation.X + interactionSize.Width - DesignAreaMouseMoveLocation.X;
                            sizeHeight = DesignAreaMouseMoveLocation.Y - interactionLocation.Y;
                        }
                        else if (transformHandle == TransformHandle.BottomCenter)
                        {
                            sizeHeight = DesignAreaMouseMoveLocation.Y - interactionLocation.Y;
                        }
                        else if (transformHandle == TransformHandle.BottomRight)
                        {
                            sizeWidth  = DesignAreaMouseMoveLocation.X - interactionLocation.X;
                            sizeHeight = DesignAreaMouseMoveLocation.Y - interactionLocation.Y;
                        }
                    }
                    else
                    {
                        Point  pA;
                        Point  pK;
                        double m;
                        int    pPX;
                        int    pPY;

                        if (transformHandle == TransformHandle.TopLeft)
                        {
                            pA = new Point(interactionLocation.X + interactionSize.Width,
                                           interactionLocation.Y + interactionSize.Height);
                            pK = DesignAreaMouseMoveLocation;
                            m  = (double)interactionSize.Height / (double)interactionSize.Width;

                            pPX = (int)(((m * ((pA.X * m) - pA.Y + pK.Y)) + pK.X) / ((m * m) + 1));
                            pPY = (int)(((pPX - pA.X) * m) + pA.Y);

                            if (pA.X - pPX < SelectedElement.MinimumSize.Width)
                            {
                                locationX = pA.X - SelectedElement.MinimumSize.Width;
                            }
                            else
                            {
                                locationX = pPX;
                            }

                            if (pA.Y - pPY < SelectedElement.MinimumSize.Height)
                            {
                                locationY = pA.Y - SelectedElement.MinimumSize.Height;
                            }
                            else
                            {
                                locationY = pPY;
                            }

                            sizeWidth  = pA.X - pPX;
                            sizeHeight = pA.Y - pPY;
                        }
                        else if (transformHandle == TransformHandle.TopRight)
                        {
                            pA = new Point(interactionLocation.X,
                                           interactionLocation.Y + interactionSize.Height);
                            pK = DesignAreaMouseMoveLocation;
                            m  = -(double)interactionSize.Height / (double)interactionSize.Width;

                            pPX = (int)(((m * ((pA.X * m) - pA.Y + pK.Y)) + pK.X) / ((m * m) + 1));
                            pPY = (int)(((pPX - pA.X) * m) + pA.Y);

                            if (pA.Y - pPY < SelectedElement.MinimumSize.Height)
                            {
                                locationY = pA.Y - SelectedElement.MinimumSize.Height;
                            }
                            else
                            {
                                locationY = pPY;
                            }

                            sizeWidth  = pPX - pA.X;
                            sizeHeight = pA.Y - pPY;
                        }
                        else if (transformHandle == TransformHandle.BottomLeft)
                        {
                            pA = new Point(interactionLocation.X + interactionSize.Width,
                                           interactionLocation.Y);
                            pK = DesignAreaMouseMoveLocation;
                            m  = -(double)interactionSize.Height / (double)interactionSize.Width;

                            pPX = (int)(((m * ((pA.X * m) - pA.Y + pK.Y)) + pK.X) / ((m * m) + 1));
                            pPY = (int)(((pPX - pA.X) * m) + pA.Y);

                            if (pA.X - pPX < SelectedElement.MinimumSize.Width)
                            {
                                locationX = pA.X - SelectedElement.MinimumSize.Width;
                            }
                            else
                            {
                                locationX = pPX;
                            }

                            sizeWidth  = pA.X - pPX;
                            sizeHeight = pPY - pA.Y;
                        }
                        else if (transformHandle == TransformHandle.BottomRight)
                        {
                            pA = new Point(interactionLocation.X,
                                           interactionLocation.Y);
                            pK = DesignAreaMouseMoveLocation;
                            m  = (double)interactionSize.Height / (double)interactionSize.Width;

                            pPX = (int)(((m * ((pA.X * m) - pA.Y + pK.Y)) + pK.X) / ((m * m) + 1));
                            pPY = (int)(((pPX - pA.X) * m) + pA.Y);

                            sizeWidth  = pPX - pA.X;
                            sizeHeight = pPY - pA.Y;
                        }
                    }

                    if (locationX > interactionLocation.X + interactionSize.Width - SelectedElement.MinimumSize.Width)
                    {
                        locationX = interactionLocation.X + interactionSize.Width - SelectedElement.MinimumSize.Width;
                    }

                    if (locationY > interactionLocation.Y + interactionSize.Height - SelectedElement.MinimumSize.Height)
                    {
                        locationY = interactionLocation.Y + interactionSize.Height - SelectedElement.MinimumSize.Height;
                    }

                    if (locationX < interactionLocation.X + interactionSize.Width - SelectedElement.MaximumSize.Width)
                    {
                        locationX = interactionLocation.X + interactionSize.Width - SelectedElement.MaximumSize.Width;
                    }

                    if (locationY < interactionLocation.Y + interactionSize.Height - SelectedElement.MaximumSize.Height)
                    {
                        locationY = interactionLocation.Y + interactionSize.Height - SelectedElement.MaximumSize.Height;
                    }

                    if (sizeWidth < SelectedElement.MinimumSize.Width)
                    {
                        sizeWidth = SelectedElement.MinimumSize.Width;
                    }

                    if (sizeHeight < SelectedElement.MinimumSize.Height)
                    {
                        sizeHeight = SelectedElement.MinimumSize.Height;
                    }

                    if (sizeWidth > SelectedElement.MaximumSize.Width)
                    {
                        sizeWidth = SelectedElement.MaximumSize.Width;
                    }

                    if (sizeHeight > SelectedElement.MaximumSize.Height)
                    {
                        sizeHeight = SelectedElement.MaximumSize.Height;
                    }

                    SelectedElement.Location = new Point(locationX, locationY);
                    SelectedElement.Size     = new Size(sizeWidth, sizeHeight);

                    needsRefresh = true;
                }

                // selection
                if (interactionState == InteractionState.None && !mouseHitsSelection && DesignerHelper.ExceedsThreshold(controlMouseMoveLocation, controlMouseDownLocation, SELECTION_THRESHOLD))
                {
                    interactionState = InteractionState.Selection;
                    needsRefresh     = true;
                }

                if (interactionState == InteractionState.Selection)
                {
                    needsRefresh = true;
                }

                if (interactionState == InteractionState.Pan)
                {
                    ViewportLocation = oldViewportLocation.Subtract(controlMouseMoveLocation.Subtract(controlMouseDownLocation));
                    ValidateViewportLocation();

                    UpdateScrollBars();
                    needsRefresh = true;
                }
            }

            if (needsRefresh)
            {
                Refresh();
            }
        }