public MainWindowViewModel(AutoCompleteBasedOnLucene autoCompleteText, IGetActionsForItem getActionsForItem,
            Logger log, UpdateManagerAdapter updateManager, IWindowManager windowManager,
            Shutdown shutdown)
        {
            _autoCompleteText = autoCompleteText;
            _getActionsForItem = getActionsForItem;
            _log = log;

            _updateManager = updateManager;
            _windowManager = windowManager;
            _shutdown = shutdown;
            _updateManager.UpdatesAvailable += (sender, args) =>
            {
                {
                    Status.SetMessage(this, "Update available, downloading");
                    _updateManager.PrepareUpdates();
                }
            };
            _updateManager.UpdatesReady += (sender, args) =>
            {
                Status.SetMessage(this, "Update prepared, ready for install");
                NotifyOfPropertyChange(() => UpdateVisible);
                NotifyOfPropertyChange(() => CanUpdate);
            };

            _cancelationTokenSource = new CancellationTokenSource();
            _argumentCancelationTokenSource = new CancellationTokenSource();
            CommandOptions =
                new ListWithCurrentSelection<AutoCompletionResult.CommandResult>(
                    new AutoCompletionResult.CommandResult(new TextItem(string.Empty), null));
            ArgumentOptions = new ListWithCurrentSelection<string>();
            Result = CommandOptions.Current;
        }
        public async void AutoCompleteArgument()
        {
            _argumentCancelationTokenSource.Cancel();
            _argumentCancelationTokenSource = new CancellationTokenSource();
            ArgumentOptions = new ListWithCurrentSelection<string>();

            var token = _argumentCancelationTokenSource.Token;
            var autoCompleteArgumentsCommand = SelectedAction as IActOnItemWithAutoCompletedArguments;
            if (autoCompleteArgumentsCommand == null)
                return;
            await Task.Run(() =>
            {
                var result = autoCompleteArgumentsCommand.AutoCompleteArguments(Item, Arguments);

                token.ThrowIfCancellationRequested();
                _log.Info("Got autocompletion '{0}' for '{1}' with {2} alternatives",
                    result.AutoCompletedArgument, result.OriginalText,
                    result.OtherOptions.Count());
                if (result.HasAutoCompletion)
                {
                    ArgumentOptions =
                        new[] {result.AutoCompletedArgument}
                            .Concat(result.OtherOptions)
                            .ToListWithCurrentSelection();
                }
                else
                {
                    ArgumentOptions = new ListWithCurrentSelection<string>(Arguments);
                }

                Arguments = ArgumentOptions.Current;
            }, token)
                .GuardForException(e => Description = e.Message);
        }
        private void UpdateCommandOptions(ListWithCurrentSelection<AutoCompletionResult.CommandResult> options)
        {
            // HACK: this temporaryResults should be a source with results expiring regularly
            var tempResults = _temporaryResults ?? new ListWithCurrentSelection<AutoCompletionResult.CommandResult>();
            if (tempResults.Count > 0)
            {
                options = tempResults.Concat(options).ToListWithCurrentSelection();
            }
            CommandOptions = options;
            Result = CommandOptions.Current;
            ArgumentOptions = new ListWithCurrentSelection<string>();
            Arguments = string.Empty;

            SetActionsForResult(Result);
            AutoCompleteArgument();
        }
        public void ProcessArgumentShortcut(FrameworkElement source, KeyEventArgs eventArgs)
        {
            if (eventArgs.Key == Key.Escape)
            {
                _temporaryResults = new ListWithCurrentSelection<AutoCompletionResult.CommandResult>();
                ((MainWindowView) Window.GetWindow(source)).Toggle();
                eventArgs.Handled = true;
                return;
            }

            if (eventArgs.Key == Key.Down || eventArgs.Key == Key.Up)
            {
                if (eventArgs.Key == Key.Down)
                    Arguments = ArgumentOptions.Next();
                else
                    Arguments = ArgumentOptions.Previous();

                eventArgs.Handled = true;
                return;
            }

            if (eventArgs.KeyboardDevice.Modifiers != ModifierKeys.Control)
            {
                return;
            }

            var str = new KeyConverter().ConvertToString(eventArgs.Key);
            int index;
            if (int.TryParse(str, out index))
            {
                index -= 1;
                if (index < ArgumentOptions.Count)
                {
                    Arguments = ArgumentOptions.SetIndex(index);
                    eventArgs.Handled = true;
                }
            }
        }
        public void ProcessShortcut(FrameworkElement source, KeyEventArgs eventArgs)
        {
            switch (eventArgs.Key)
            {
                case Key.Escape:
                    _temporaryResults = new ListWithCurrentSelection<AutoCompletionResult.CommandResult>();
                    ((MainWindowView) Window.GetWindow(source)).Toggle();
                    return;
                case Key.Down:
                case Key.Up:
                    Result = eventArgs.Key == Key.Down 
                        ? CommandOptions.Next() 
                        : CommandOptions.Previous();

                    Task.Factory.StartNew(() => SetActionsForResult(Result))
                        .GuardForException(SetError);
                    eventArgs.Handled = true;
                    return;
            }

            if (eventArgs.KeyboardDevice.Modifiers == ModifierKeys.Control)
            {
                int index;
                var str = new KeyConverter().ConvertToString(eventArgs.Key);
                if (int.TryParse(str, out index))
                {
                    if (index == 0) index = 10;

                    index -= 1;
                    if (index < CommandOptions.Count)
                    {
                        Result = CommandOptions.SetIndex(index);
                        Task.Factory.StartNew(() => SetActionsForResult(Result))
                            .GuardForException(SetError);
                        eventArgs.Handled = true;
                    }
                }
            }
        }
        public async void Execute(FrameworkElement source)
        {
            await Task.Run(() =>
            {
                try
                {
                    Status.SetMessage(this, "Executing");
                    IItem result = null;
                    if (ActionWithArguments != null)
                    {
                        result = ActionWithArguments.ActOn(Result.Item, Arguments);
                    }
                    else
                    {
                        result = SelectedAction.ActOn(Result.Item);
                    }
                    _autoCompleteText.LearnInputForCommandResult(Input, Result);
                    _getActionsForItem.LearnActionForCommandResult(Input, SelectedAction, Result);

                    result = result ?? NoReturnValue.Object;
                    if (result != NoReturnValue.Object)
                    {
                        _temporaryResults = result.ToListWithCurrentSelection();
                        UpdateCommandOptions(new ListWithCurrentSelection<AutoCompletionResult.CommandResult>());
                        Input = CommandOptions.First().Item.Text;
                    }
                    else
                    {
                        Input = string.Empty;
                        Arguments = string.Empty;
                        // HACK
                        _temporaryResults = new ListWithCurrentSelection<AutoCompletionResult.CommandResult>();
                        UpdateCommandOptions(_temporaryResults);
                        Caliburn.Micro.Execute.OnUIThread(() => ((MainWindowView) Window.GetWindow(source)).HideWindow());
                    }
                    
                    Status.SetMessage(this, "Done");
                }
                catch (Exception e)
                {
                    Status.SetMessage(this, "Error :" + e.Message);
                    Description = e.Message;
                    _log.Error(e);
                }
            });
        }