function _showFindBar(scope, showReplace) {
        FindUtils.notifySearchScopeChanged();
        // If the scope is a file with a custom viewer, then we
        // don't show find in files dialog.
        if (scope && !EditorManager.canOpenPath(scope.fullPath)) {
            return;
        }

        if (scope instanceof InMemoryFile) {
            CommandManager.execute(Commands.FILE_OPEN, { fullPath: scope.fullPath }).done(function () {
                CommandManager.execute(Commands.CMD_FIND);
            });
            return;
        }

        // Get initial query/replace text
        var currentEditor = EditorManager.getActiveEditor(),
            initialQuery = FindBar.getInitialQuery(_findBar, currentEditor);

        // Close our previous find bar, if any. (The open() of the new _findBar will
        // take care of closing any other find bar instances.)
        if (_findBar) {
            _findBar.close();
        }

        _findBar = new FindBar({
            multifile: true,
            replace: showReplace,
            initialQuery: initialQuery.query,
            initialReplaceText: initialQuery.replaceText,
            queryPlaceholder: Strings.FIND_QUERY_PLACEHOLDER,
            scopeLabel: FindUtils.labelForScope(scope)
        });
        _findBar.open();

        // TODO Should push this state into ModalBar (via a FindBar API) instead of installing a callback like this.
        // Custom closing behavior: if in the middle of executing search, blur shouldn't close ModalBar yet. And
        // don't close bar when opening Edit Filter dialog either.
        _findBar._modalBar.isLockedOpen = function () {
            // TODO: should have state for whether the search is executing instead of looking at find bar state
            // TODO: should have API on filterPicker to figure out if dialog is open
            return !_findBar.isEnabled() || $(".modal.instance .exclusions-editor").length > 0;
        };

        var candidateFilesPromise = FindInFiles.getCandidateFiles(scope),  // used for eventual search, and in exclusions editor UI
            filterPicker;

        function handleQueryChange() {
            // Check the query expression on every input event. This way the user is alerted
            // to any RegEx syntax errors immediately.
            var queryInfo = _findBar.getQueryInfo(),
                queryResult = FindUtils.parseQueryInfo(queryInfo);

            // Enable the replace button appropriately.
            _findBar.enableReplace(queryResult.valid);

            if (queryResult.valid || queryResult.empty) {
                _findBar.showNoResults(false);
                _findBar.showError(null);
            } else {
                _findBar.showNoResults(true, false);
                _findBar.showError(queryResult.error);
            }
        }

        function startSearch(replaceText) {
            var queryInfo = _findBar.getQueryInfo(),
                disableFindBar = FindUtils.isNodeSearchDisabled() || (replaceText ? true : false);
            if (queryInfo && queryInfo.query) {
                _findBar.enable(!disableFindBar);
                StatusBar.showBusyIndicator(disableFindBar);
                if (queryInfo.isRegexp) {
                    HealthLogger.searchDone(HealthLogger.SEARCH_REGEXP);
                }
                if (queryInfo.isCaseSensitive) {
                    HealthLogger.searchDone(HealthLogger.SEARCH_CASE_SENSITIVE);
                }

                var filter;
                if (filterPicker) {
                    filter = FileFilters.commitPicker(filterPicker);
                } else {
                    // Single-file scope: don't use any file filters
                    filter = null;
                }
                searchAndShowResults(queryInfo, scope, filter, replaceText, candidateFilesPromise);
            }
            return null;
        }

        function startReplace() {
            startSearch(_findBar.getReplaceText());
        }

        _findBar
            .on("doFind.FindInFiles", function () {
                // Subtle issue: we can't just pass startSearch directly as the handler, because
                // we don't want it to get the event object as an argument.
                startSearch();
            })
            .on("queryChange.FindInFiles", handleQueryChange)
            .on("close.FindInFiles", function (e) {
                _findBar.off(".FindInFiles");
                _findBar = null;
            });

        if (showReplace) {
            // We shouldn't get a "doReplace" in this case, since the Replace button
            // is hidden when we set options.multifile.
            _findBar.on("doReplaceBatch.FindInFiles", startReplace);
        }

        var oldModalBarHeight = _findBar._modalBar.height();

        // Show file-exclusion UI *unless* search scope is just a single file
        if (!scope || scope.isDirectory) {
            var exclusionsContext = {
                label: FindUtils.labelForScope(scope),
                promise: candidateFilesPromise
            };

            filterPicker = FileFilters.createFilterPicker(exclusionsContext);
            // TODO: include in FindBar? (and disable it when FindBar is disabled)
            _findBar._modalBar.getRoot().find(".scope-group").append(filterPicker);
        }

        handleQueryChange();

        // Appending FilterPicker and query text can change height of modal bar, so resize editor.
        // Preserve scroll position of the current full editor across the editor refresh, adjusting
        // for the height of the modal bar so the code doesn't appear to shift if possible.
        var fullEditor = EditorManager.getCurrentFullEditor(),
            scrollPos;
        if (fullEditor) {
            scrollPos = fullEditor.getScrollPos();
            scrollPos.y -= oldModalBarHeight;   // modalbar already showing, adjust for old height
        }
        WorkspaceManager.recomputeLayout();
        if (fullEditor) {
            fullEditor._codeMirror.scrollTo(scrollPos.x, scrollPos.y + _findBar._modalBar.height());
        }
    }
@private
Displays a non-modal embedded dialog above the code mirror editor that allows the user to do
a find operation across all files in the project.
@param {?Entry} scope  Project file/subfolder to search within; else searches whole project.
@param {boolean=} showReplace If true, show the Replace controls.