function editFilter(filter, index) {
        var lastFocus = window.document.activeElement;

        var templateVars = {
                instruction: StringUtils.format(Strings.FILE_FILTER_INSTRUCTIONS, brackets.config.glob_help_url),
                Strings: Strings
            };
        var dialog = Dialogs.showModalDialogUsingTemplate(Mustache.render(EditFilterTemplate, templateVars)),
            $nameField = dialog.getElement().find(".exclusions-name"),
            $editField = dialog.getElement().find(".exclusions-editor"),
            $remainingField = dialog.getElement().find(".exclusions-name-characters-remaining");

        $nameField.val(filter.name);
        $editField.val(filter.patterns.join("\n")).focus();

        function getValue() {
            var newFilter = $editField.val().split("\n");

            // Remove blank lines
            return newFilter.filter(function (glob) {
                return glob.trim().length;
            });
        }

        $nameField.bind('input', function () {
            var remainingCharacters = FILTER_NAME_CHARACTER_MAX - $(this).val().length;
            if (remainingCharacters < 0.25*FILTER_NAME_CHARACTER_MAX) {
                $remainingField.show();

                $remainingField.text(StringUtils.format(
                    Strings.FILTER_NAME_REMAINING,
                    remainingCharacters
                ));

                if (remainingCharacters < 0) {
                    $remainingField.addClass("exclusions-name-characters-limit-reached");
                } else {
                    $remainingField.removeClass("exclusions-name-characters-limit-reached");
                }
            }
            else {
                $remainingField.hide();
            }
            updatePrimaryButton();
        });

        dialog.done(function (buttonId) {
            if (buttonId === Dialogs.DIALOG_BTN_OK) {
                // Update saved filter preference
                setActiveFilter({ name: $nameField.val(), patterns: getValue() }, index);
                _updatePicker();
                _doPopulate();
            }
            lastFocus.focus();  // restore focus to old pos
        });

        // Code to update the file count readout at bottom of dialog (if context provided)
        var $fileCount = dialog.getElement().find(".exclusions-filecount");

        function updateFileCount() {
            _context.promise.done(function (files) {
                var filter = getValue();
                if (filter.length) {
                    var filtered = filterFileList(compile(filter), files);
                    $fileCount.html(StringUtils.format(Strings.FILTER_FILE_COUNT, filtered.length, files.length, _context.label));
                } else {
                    $fileCount.html(StringUtils.format(Strings.FILTER_FILE_COUNT_ALL, files.length, _context.label));
                }
            });
        }

        // Code to enable/disable the OK button at the bottom of dialog (whether filter is empty or not)
        var $primaryBtn = dialog.getElement().find(".primary");

        function updatePrimaryButton() {
            var trimmedValue = $editField.val().trim();
            var exclusionNameLength = $nameField.val().length;

            $primaryBtn.prop("disabled", !trimmedValue.length || (exclusionNameLength > FILTER_NAME_CHARACTER_MAX));
        }

        $editField.on("input", updatePrimaryButton);
        updatePrimaryButton();

        if (_context) {
            $editField.on("input", _.debounce(updateFileCount, 400));
            updateFileCount();
        } else {
            $fileCount.hide();
        }

        return dialog.getPromise();
    }
Opens a dialog box to edit the given filter. When editing is finished, the value of getActiveFilter() changes to
reflect the edits. If the dialog was canceled, the preference is left unchanged.
@param {!{name: string, patterns: Array.<string>}} filter
@param {number} index The index of the filter set to be edited or created. The value is -1 if it is for a new one
         to be created.
@return {!$.Promise} Dialog box promise