public function index($folder = '', $sort_field = NULL, $sort_order = NULL,
        $no_threads = false, $no_search = false
    ) {
        if (!$no_threads && $this->threading) {
            return $this->thread_index($folder, $sort_field, $sort_order);
        }

        $this->set_sort_order($sort_field, $sort_order);

        if (!strlen($folder)) {
            $folder = $this->folder;
        }

        // we have a saved search result, get index from there
        if ($this->search_string) {
            if ($this->search_set->is_empty()) {
                return new rcube_result_index($folder, '* SORT');
            }

            if ($this->search_set instanceof rcube_result_multifolder) {
                $index = $this->search_set;
                $index->folder = $folder;
                // TODO: handle changed sorting
            }
            // search result is an index with the same sorting?
            else if (($this->search_set instanceof rcube_result_index)
                && ((!$this->sort_field && !$this->search_sorted) ||
                    ($this->search_sorted && $this->search_sort_field == $this->sort_field))
            ) {
                $index = $this->search_set;
            }
            // $no_search is enabled when we are not interested in
            // fetching index for search result, e.g. to sort
            // threaded search result we can use full mailbox index.
            // This makes possible to use index from cache
            else if (!$no_search) {
                if (!$this->sort_field) {
                    // No sorting needed, just build index from the search result
                    // @TODO: do we need to sort by UID here?
                    $search = $this->search_set->get_compressed();
                    $index  = new rcube_result_index($folder, '* ESEARCH ALL ' . $search);
                }
                else {
                    $index = $this->index_direct($folder, $this->sort_field, $this->sort_order, $this->search_set);
                }
            }

            if (isset($index)) {
                if ($this->sort_order != $index->get_parameters('ORDER')) {
                    $index->revert();
                }

                return $index;
            }
        }

        // check local cache
        if ($mcache = $this->get_mcache_engine()) {
            return $mcache->get_index($folder, $this->sort_field, $this->sort_order);
        }

        // fetch from IMAP server
        return $this->index_direct($folder, $this->sort_field, $this->sort_order);
    }