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

            TimeOfWeek time = FindClickTime(e);

            if (TimeOfWeek.ReferenceEquals(time, null))
            {
                return;
            }

            if (TimetableMouseDoubleClick != null)
            {
                TimetableMouseDoubleClick(this, new TimetableEventArgs(e, time));
            }
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            TimeOfWeek time = FindClickTime(e);

            if (TimeOfWeek.ReferenceEquals(time, null))
            {
                return;
            }

            if (EnableDrag_ && e.Button == MouseButtons.Left && Timetable_ != null)
            {
                DragSession_ = Timetable_.FindClassAt(time, !ShowAll_);
                Unavailability dragUnavail = Timetable_.FindUnavailableAt(time);
                if (DragSession_ != null)
                {
                    BeginDrag(DragSession_.Stream.Type);
                    DragCursor_ = DragCursor(DragSession_);

                    DoDragDrop(DragSession_.Stream.Type, DragDropEffects.Move);

                    EndDrag();
                    DragCursor_ = null;
                }
                else if (dragUnavail != null)
                {
                    HoverUnavail_ = null;
                    Invalidate();
                    DragCursor_ = DragCursor(dragUnavail);

                    DoDragDrop(dragUnavail, DragDropEffects.Move);

                    HoverUnavail_ = null;
                    Invalidate();
                    DragCursor_ = null;
                }
            }

            if (TimetableMouseDown != null)
            {
                TimetableMouseDown(this, new TimetableEventArgs(e, time));
            }
        }
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            TimeOfWeek time = FindClickTime(PointToClient(new Point(drgevent.X, drgevent.Y)));

            // outside of table bounds?
            if (TimeOfWeek.ReferenceEquals(time, null))
            {
                // clear current preview (at edge of timetable)
                EndPreviewStream();
                // cannot drag outside of the actual table
                drgevent.Effect = DragDropEffects.None;
                return;
            }

            // dragging a class
            if (drgevent.Data.GetDataPresent(typeof(Session)) || drgevent.Data.GetDataPresent(typeof(Type)))
            {
                drgevent.Effect = DragDropEffects.Move;
                Type dragType;
                if (drgevent.Data.GetDataPresent(typeof(Session)))
                {
                    dragType = ((Session)drgevent.Data.GetData(typeof(Session))).Stream.Type;
                }
                else
                {
                    dragType = (Type)drgevent.Data.GetData(typeof(Type));
                }

                Session session = Timetable.From(dragType).FindClassAt(time, false);
                if (session == null)
                {
                    EndPreviewStream();
                }
                else
                {
                    PreviewEquiv(session.Stream);
                }
            }
            // dragging an unavailability
            else if (drgevent.Data.GetDataPresent(typeof(Unavailability)))
            {
                Unavailability dragUnavail = (Unavailability)drgevent.Data.GetData(typeof(Unavailability));
                TimeLength     offset      = new TimeLength(dragUnavail.StartMinute);
                TimeOfWeek     start       = time - dragUnavail.Length / 2;
                start -= offset;
                start.RoundToNearestHour();
                start += offset;

                HoverUnavail_ = new Timeslot(start.Day, (TimeOfDay)start, (TimeOfDay)start + dragUnavail.Length);
                if (HoverUnavail_.StartTime < new TimeOfDay(HourStart_, 0) || HoverUnavail_.EndTime > new TimeOfDay(HourEnd_, 0))
                {
                    drgevent.Effect = DragDropEffects.None;
                    HoverUnavail_   = null;
                }
                else
                {
                    drgevent.Effect = DragDropEffects.Move;
                }
                Invalidate();
            }
            else
            {
                base.OnDragOver(drgevent);
            }
        }