private List<MenuCommand> CreateMenuCommands(Process replProcess, TextBox interactiveText, Entity<ReplState> replEntity)
        {
            var dte = (DTE2) _serviceProvider.GetService(typeof (DTE));

            var loadSelectedFilesIntoRepl =
                new LoadFilesIntoRepl(
                    new ReplWriter(replProcess, new TextBoxWriter(interactiveText, replEntity)),
                    new SelectedFilesProvider(dte.ToolWindows.SolutionExplorer),
                    _replToolWindow);

            var loadSelectedProjectIntoRepl =
                new LoadFilesIntoRepl(
                    new ReplWriter(replProcess, new TextBoxWriter(interactiveText, replEntity)),
                    new ProjectFilesProvider(
                        new SelectedProjectProvider(dte.Solution, dte.ToolWindows.SolutionExplorer)),
                    _replToolWindow);

            var loadActiveFileIntoRepl =
                new LoadFilesIntoRepl(
                    new ReplWriter(replProcess, new TextBoxWriter(interactiveText, replEntity)),
                    new ActiveFileProvider(dte),
                    _replToolWindow);

            var componentModel = (IComponentModel) _serviceProvider.GetService(typeof (SComponentModel));

            var namespaceParser = new NamespaceParser(NamespaceParser.NamespaceSymbols);

            var activeTextBufferStateProvider =
                new ActiveTextBufferStateProvider(
                    componentModel.GetService<IVsEditorAdaptersFactoryService>(),
                    (IVsTextManager) _serviceProvider.GetService(typeof (SVsTextManager)));

            var changeReplNamespace =
                new ChangeReplNamespace(new ReplWriter(replProcess, new TextBoxWriter(interactiveText, replEntity)));

            var menuCommands = new List<MenuCommand>();
            menuCommands.Add(new MenuCommand((sender, args) => loadSelectedProjectIntoRepl.Execute(), new CommandID(Guids.GuidClojureExtensionCmdSet, 11)));
            menuCommands.Add(new MenuCommand((sender, args) => loadSelectedFilesIntoRepl.Execute(), new CommandID(Guids.GuidClojureExtensionCmdSet, 12)));
            menuCommands.Add(new MenuCommand((sender, args) => loadActiveFileIntoRepl.Execute(), new CommandID(Guids.GuidClojureExtensionCmdSet, 13)));
            menuCommands.Add(new MenuCommand((sender, args) => changeReplNamespace.Execute(namespaceParser.Execute(activeTextBufferStateProvider.Get())), new CommandID(Guids.GuidClojureExtensionCmdSet, 14)));
            menuCommands.Add(new MenuCommand((sender, args) => new ReplWriter(replProcess, new TextBoxWriter(interactiveText, replEntity)).WriteBehindTheSceneExpressionToRepl((string)dte.ActiveDocument.Selection.Text), new CommandID(Guids.GuidClojureExtensionCmdSet, 15)));
            return menuCommands;
        }
		public void Initialize()
		{
			_tokenizer = new Tokenizer();
			_parser = new NamespaceParser(new List<string>() {"ns"});
		}
        public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
        {
            if (_metadata == null)
            {
                return;
            }

            var caretPosition = session.TextView.Caret.Position.BufferPosition.Position;
            var tokenTriggeringIntellisense = _tokenizedBuffer.CurrentState.FindTokenAtIndex(caretPosition);
            if (caretPosition == tokenTriggeringIntellisense.IndexToken.StartIndex) tokenTriggeringIntellisense = tokenTriggeringIntellisense.Previous();
            var numberOfCharactersBeforeCursor = caretPosition - tokenTriggeringIntellisense.IndexToken.StartIndex;
            var textFromSymbolBeforeCursor = tokenTriggeringIntellisense.IndexToken.Token.Text.Substring(0, numberOfCharactersBeforeCursor);

            if (string.IsNullOrWhiteSpace(textFromSymbolBeforeCursor))
            {
                return;
            }

            var completions = new List<Completion>();

            //todo: convert current file being edited to constantly try to compile in background thread & update metadatacache (allowing Clojure commands to present intellisense for file being edited)
            //todo: add context sensitivity to filter for functions/variables depending on 1st argument to list or not & whether list is quoted or list starts with .. or ->
            NamespaceParser namespaceParser = new NamespaceParser(NamespaceParser.NamespaceSymbols);
            string namespaceOfFile = "";
            try
            {
                namespaceOfFile = namespaceParser.Execute(_tokenizedBuffer.CurrentState);
            }
            catch { }

            var currentIndexToken = _tokenizedBuffer.CurrentState.FindTokenAtIndex(0);

            while (currentIndexToken != null)
            {
                if (currentIndexToken.IndexToken.StartIndex != tokenTriggeringIntellisense.IndexToken.StartIndex)
                {
                    if (currentIndexToken.Node.Value.Type == TokenType.Symbol && currentIndexToken.Node.Value.Text.StartsWith(textFromSymbolBeforeCursor))
                    {
                        if (completions.Find(c => c.DisplayText == currentIndexToken.Node.Value.Text) == null)
                        {
                            completions.Add(new Completion(currentIndexToken.Node.Value.Text));
                        }
                    }
                }

                currentIndexToken = currentIndexToken.Next();
            }

            completions.AddRange(_metadata.LoadCoreCompletionsMatchingString(textFromSymbolBeforeCursor));

            //todo: load assemblies in separate appDomain
            List<Reference> references = GetAllProjectReferences();
            List<Assembly> referencedAssemblies = references.Select(x => Assembly.LoadFrom(x.Path)).ToList();

            completions.AddRange(referencedAssemblies.SelectMany(x => _metadata.LoadCompletionsInAssemblyMatchingString(x, textFromSymbolBeforeCursor)));

            //completions.AddRange(_metadata.LoadCompletionsInCljFileMatchingString(, textFromSymbolBeforeCursor));

            var snapshot = session.TextView.TextSnapshot;
            var start = new SnapshotPoint(snapshot, tokenTriggeringIntellisense.IndexToken.StartIndex);
            var end = new SnapshotPoint(snapshot, start.Position + tokenTriggeringIntellisense.IndexToken.Token.Text.Length);
            var applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, end), SpanTrackingMode.EdgeInclusive);
            completionSets.Add(new CompletionSet("All", "All", applicableTo, completions, new List<Completion>()));
        }