function MultiRangeInlineEditor(ranges, messageCB, labelCB, fileComparator) {
        InlineTextEditor.call(this);

        // Store the results to show in the range list. This creates TextRanges bound to the Document,
        // which will stay up to date automatically (but we must be sure to detach them later)
        this._ranges = ranges.map(function (rangeResult) {
            return new SearchResultItem(rangeResult);
        });
        this._messageCB = messageCB;
        this._labelCB = labelCB;

        this._selectedRangeIndex = -1;
        this._collapsedFiles = {};

        // Set up list sort order
        this._fileComparator = fileComparator || function defaultComparator(file1, file2) {
            return FileUtils.comparePaths(file1.fullPath, file2.fullPath);
        };
        this._ranges.sort(function (result1, result2) {
            return this._fileComparator(result1.textRange.document.file, result2.textRange.document.file);
        }.bind(this));
    }
@constructor
@param {Array.<{name:String,document:Document,lineStart:number,lineEnd:number}>} ranges The text
     ranges to display. Results within the same file are expected to be contiguous in this array.
@param {?function(): $.Promise} messageCB Optional; returns a promise resolved with a message to
     show when no matches are available. The message should be already-escaped HTML.
@param {?function(range): string} labelCB Optional; returns an updated label string for the given
     range. Called when we detect that the content of a range has changed. The label is plain
     text, not HTML.
@param {?function(!File, !File):number} fileComparator Optional comparison function for sorting
     the results list (based on range.document.file). Defaults to FileUtils.comparePaths().
@extends {InlineTextEditor}