private void Point_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            DebugHelper.AssertUIThread();

            FrameworkElement frameworkElement = sender as FrameworkElement;

            if (frameworkElement != null)
            {
                TimelineTimeProxy point = frameworkElement.DataContext as TimelineTimeProxy;
                if ((point != null) && point.IsFloating)
                {
                    TimelinePausePoint pausePoint = point as TimelinePausePoint;
                    if (pausePoint != null)
                    {
                        if (this.PausePointsSource != null)
                        {
                            if (!point.HasMovedDuringLastFloat)
                            {
                                this.PausePointsSource.Remove(pausePoint);
                            }
                        }
                    }

                    point.IsFloating = false;
                }
            }
        }
        private void Point_DragStarted(object sender, DragStartedEventArgs e)
        {
            DebugHelper.AssertUIThread();

            FrameworkElement frameworkElement = sender as FrameworkElement;

            if (frameworkElement != null)
            {
                TimelineTimeProxy point = frameworkElement.DataContext as TimelineTimeProxy;
                if (point != null)
                {
                    e.Handled = true;

                    TimelinePausePoint pausePoint = point as TimelinePausePoint;

                    if ((pausePoint != null) && pausePoint.HasCoupledMarker)
                    {
                        if (this.PausePointsSource != null)
                        {
                            this.PausePointsSource.OnTimePointDataChanged(pausePoint, pausePoint.RelativeTime, false, true, false);
                        }
                    }
                    else if ((pausePoint != null) || point.IsEnabled)
                    {
                        point.IsFloating = true;
                    }
                }
            }
        }
        private void PausePointDecouple_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            DebugHelper.AssertUIThread();

            if (e != null)
            {
                TimelinePausePoint pausePoint = e.Parameter as TimelinePausePoint;

                if (pausePoint != null)
                {
                    e.Handled    = true;
                    e.CanExecute = pausePoint.HasCoupledMarker;
                }
            }
        }
        private void PausePointToggle_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DebugHelper.AssertUIThread();

            if (e != null)
            {
                TimelinePausePoint pausePoint = e.Parameter as TimelinePausePoint;

                if (pausePoint != null)
                {
                    e.Handled = true;

                    pausePoint.IsEnabled = !pausePoint.IsEnabled;
                }
            }
        }
        private void PausePointDecouple_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DebugHelper.AssertUIThread();

            if (e != null)
            {
                TimelinePausePoint pausePoint = e.Parameter as TimelinePausePoint;

                if ((pausePoint != null) && pausePoint.HasCoupledMarker)
                {
                    e.Handled = true;

                    pausePoint.Remove();
                }
            }
        }
        public override void Remove()
        {
            DebugHelper.AssertUIThread();
            Debug.Assert(this.owner != null);

            if (!this.IsReadOnly)
            {
                this.owner.Remove(this);

                TimelinePausePoint temp = this.pausePoint;
                this.pausePoint = null;

                if (temp != null)
                {
                    temp.Remove();
                }
            }
        }
        public void DecouplePausePoint(TimelinePausePoint pausePointToDecouple)
        {
            DebugHelper.AssertUIThread();
            Debug.Assert(this.owner != null);

            if (pausePointToDecouple == null)
            {
                throw new ArgumentNullException("pausePointToDecouple");
            }

            if (this.pausePoint != null)
            {
                if (this.pausePoint != pausePointToDecouple)
                {
                    throw new InvalidOperationException("pause point not matching");
                }

                this.pausePoint = null;

                this.RaisePropertyChanged("CoupledPausePoint");
            }
        }
        public void DecouplePausePoint(TimelinePausePoint pausePointToDecouple)
        {
            DebugHelper.AssertUIThread();
            Debug.Assert(this.owner != null);

            if (pausePointToDecouple == null)
            {
                throw new ArgumentNullException("pausePointToDecouple");
            }

            if (this.pausePoint != null)
            {
                if (this.pausePoint != pausePointToDecouple)
                {
                    throw new InvalidOperationException("pause point not matching");
                }

                this.pausePoint = null;

                this.RaisePropertyChanged("CoupledPausePoint");
            }
        }