public function search(Query $obj_query)
    {
        $obj_request = new SearchRequest();
        $obj_params = $this->prepareRequestParams($obj_request);

        // Basics
        $obj_params
            ->setQuery($obj_query->getQuery())
            ->setLimit($obj_query->getLimit())
            ->setOffset($obj_query->getOffset())
        ;

        // Sorting
        $arr_sorts = $obj_query->getSorts();
        if(null !== $arr_sorts && count($arr_sorts) > 0) {
            foreach ($arr_sorts as $arr_sort) {
                $obj_sort = $obj_params->addSortSpec();
                $obj_sort->setSortExpression($arr_sort[0]);
                $obj_sort->setSortDescending(Query::DESC === $arr_sort[1]);
            }
        }

        // Match Scoring
        if(Query::SCORE_REGULAR === $obj_query->getScorer()) {
            $obj_params->mutableScorerSpec()->setScorer(Scorer::MATCH_SCORER)->setLimit($obj_query->getLimit());
        } elseif (Query::SCORE_RESCORING === $obj_query->getScorer()) {
            $obj_params->mutableScorerSpec()->setScorer(Scorer::RESCORING_MATCH_SCORER)->setLimit($obj_query->getLimit());
        }

        // Return Fields
        $arr_return_fields = $obj_query->getReturnFields();
        if(null !== $arr_return_fields && count($arr_return_fields) > 0) {
            $obj_fields = $obj_params->mutableFieldSpec();
            foreach ($arr_return_fields as $str_field) {
                $obj_fields->addName($str_field);
            }
        }

        // Return Expressions
        $arr_return_exps = $obj_query->getReturnExpressions();
        if(null !== $arr_return_exps && count($arr_return_exps) > 0) {
            $obj_fields = $obj_params->mutableFieldSpec();
            foreach ($arr_return_exps as $arr_exp) {
                $obj_fields->addExpression()->setName($arr_exp[0])->setExpression($arr_exp[1]);
            }
        }

        // Facets
        $arr_facets = $obj_query->getFacets();
        if(null !== $arr_facets) {
            if(count($arr_facets) > 0) {
                // We want a specific set of facets in the response
                foreach($arr_facets as $str_facet) {
                    $obj_params->addIncludeFacet()->setName($str_facet);
                }
            } else {
                // We want all facets back...
                $obj_params->setAutoDiscoverFacetCount(100);
            }
        }

        $this->execute('Search', $obj_request, new SearchResponse());
        return $this->processSearchResponse();
    }