/// <summary>
        /// Hides a visible Metro Dialog instance.
        /// </summary>
        /// <param name="window">The window with the dialog that is visible.</param>
        /// <param name="dialog">The dialog instance to hide.</param>
        /// <param name="settings">An optional pre-defined settings instance.</param>
        /// <returns>A task representing the operation.</returns>
        /// <exception cref="InvalidOperationException">
        /// The <paramref name="dialog"/> is not visible in the window.
        /// This happens if <see cref="ShowMetroDialogAsync"/> hasn't been called before.
        /// </exception>
        public Task HideMetroDialogAsync(
            IMetroWindow metroWindow
            , IBaseMetroDialogFrame dialog
            , IMetroDialogFrameSettings settings = null)
        {
            metroWindow.Dispatcher.VerifyAccess();
            if (!metroWindow.MetroActiveDialogContainer.Children.Contains(dialog as UIElement) && !metroWindow.MetroInactiveDialogContainer.Children.Contains(dialog as UIElement))
            {
                throw new InvalidOperationException("The provided dialog is not visible in the specified window.");
            }

            metroWindow.SizeChanged -= dialog.SizeChangedHandler;

            dialog.OnClose();

            Task closingTask = (Task)metroWindow.Dispatcher.Invoke(new Func <Task>(dialog._WaitForCloseAsync));

            return(closingTask.ContinueWith(a =>
            {
                if (DialogClosed != null)
                {
                    metroWindow.Dispatcher.BeginInvoke(new Action(() => DialogClosed(this, new DialogStateChangedEventArgs())));
                }

                return (Task)metroWindow.Dispatcher.Invoke(new Func <Task>(() =>
                {
                    this.RemoveDialog(metroWindow, dialog);

                    return this.HandleOverlayOnHide(metroWindow, settings);
                }));
            }).Unwrap());
        }