void DocumentSourceSort::loadDocument(const Document& doc) {
    invariant(!populated);
    if (!_sorter) {
        _sorter.reset(MySorter::make(makeSortOptions(), Comparator(*this)));
    }
    _sorter->add(extractKey(doc), doc);
}
void DocumentSourceSort::loadingDone() {
    if (!_sorter) {
        _sorter.reset(MySorter::make(makeSortOptions(), Comparator(*this)));
    }
    _output.reset(_sorter->done());
    _sorter.reset();
    populated = true;
}
void DocumentSourceSort::populateFromCursors(const vector<DBClientCursor*>& cursors) {
    vector<boost::shared_ptr<MySorter::Iterator> > iterators;
    for (size_t i = 0; i < cursors.size(); i++) {
        iterators.push_back(boost::make_shared<IteratorFromCursor>(this, cursors[i]));
    }

    _output.reset(MySorter::Iterator::merge(iterators, makeSortOptions(), Comparator(*this)));
}
void DocumentSourceSort::populateFromBsonArrays(const vector<BSONArray>& arrays) {
    vector<boost::shared_ptr<MySorter::Iterator> > iterators;
    for (size_t i = 0; i < arrays.size(); i++) {
        iterators.push_back(boost::make_shared<IteratorFromBsonArray>(this, arrays[i]));
    }

    _output.reset(MySorter::Iterator::merge(iterators, makeSortOptions(), Comparator(*this)));
}
void DocumentSourceSort::populate() {
    if (_mergingPresorted) {
        typedef DocumentSourceMergeCursors DSCursors;
        typedef DocumentSourceCommandShards DSCommands;
        if (DSCursors* castedSource = dynamic_cast<DSCursors*>(pSource)) {
            populateFromCursors(castedSource->getCursors());
        } else if (DSCommands* castedSource = dynamic_cast<DSCommands*>(pSource)) {
            populateFromBsonArrays(castedSource->getArrays());
        } else {
            msgasserted(17196, "can only mergePresorted from MergeCursors and CommandShards");
        }
    } else {
        scoped_ptr<MySorter> sorter (MySorter::make(makeSortOptions(), Comparator(*this)));
        while (boost::optional<Document> next = pSource->getNext()) {
            sorter->add(extractKey(*next), *next);
        }
        _output.reset(sorter->done());
    }
    populated = true;
}