public function suggestedTerms()
    {
        if ( mb_strlen($this->searchQuery, 'UTF-8') < 3 )
        {
            return array();
        }

        eZDebug::accumulatorStart(__CLASS__.'::'.__FUNCTION__, 'Merck' );

        $solrHighlightParams = $this->solrHighlightParams();
        $suggestions         = array();
        $filters             = array();
        $solrFilter          = $this->solrFilter();
        $solrFacetsFiler     = $this->solrFacetsFilter();

        if( $solrFilter )
            $filters[] = $solrFilter;
        if( $solrFacetsFiler )
            $filters[] = $solrFacetsFiler;

        $queries = array();
        $terms   = MMGlobalSearchDictionaryTerm::fetchSolrTerms( $this->searchQuery, null, $this->suggestedTermsLimit() * 3 );

        foreach( $terms as $term )
        {
            $query = array();

            foreach( explode( ' ', $solrHighlightParams['hl.fl'] ) as $field )
                $query[] = $field.':"'.addslashes( $term ).'"';

            $queries[] = implode( ' OR ', $query );
        }

        $params = array(
                'start'	        => 0,
                'rows'	        => 0,
                'q'		        => '*:*',
                'fq'	        => implode(' AND ' , $filters),
                'facet'	        => 'true',
                'facet.query'   => $queries,
        );
        $solrResults = SolrTool::rawSearch( $params );

        $i = 0;
        foreach( $solrResults['facet_counts']['facet_queries'] as $solrTerm => $solrTermCount )
        {
            if( $solrTermCount )
            {
                $term = $terms[$i];
                if( strtolower( trim( $term ) ) != strtolower( trim( $this->searchQuery, ' "' ) ) )
                {
                    $suggestions[] = array(
                        't'	=> $term,
                        'c'	=> $solrTermCount);

                    if( count( $suggestions ) >= $this->suggestedTermsLimit() )
                        break;
                }
            }
            $i++;
        }


        // sort
        usort( $suggestions, function($a, $b){
            return ($a['c'] < $b['c']);
        } );

        eZDebug::accumulatorStop( __CLASS__.'::'.__FUNCTION__ );

        return $suggestions;
    }
    /**
     * @param string $kw
     * @return array
     */
    public function keywordsAutocomplete( $kw = null )
    {
        eZDebug::accumulatorStart( __CLASS__.'::'.__FUNCTION__, 'Merck' );
        
        $solrTextAttributesSuffix = SolrSafeOperatorHelper::clusterIni( 'SolrSettings', 'TextAttributesSuffix', 'merck.ini' );

        // taken from eZFindServerCallFunctions
        $result = array();
        if( is_null($kw) )
            $kw = isset($_GET['term']) ? $_GET['term'] : '';

        $findINI = eZINI::instance( 'ezfind.ini' );
        $limit   = $findINI->variable( 'AutoCompleteSettings', 'Limit');

        if ( $this->contentList->iniMerck()->hasVariable( 'ContentListApplicationSettings', 'KeywordsAutoCompleteLimit' ) )
            $limit = $this->contentList->iniMerck()->variable( 'ContentListApplicationSettings', 'KeywordsAutoCompleteLimit' );

        $minLength = 3;
        if ( $this->contentList->iniMerck()->hasVariable( 'ContentListApplicationSettings', 'KeywordsAutoCompleteMinLength' ) )
            $minLength = SolrSafeOperatorHelper::clusterIni('ContentListApplicationSettings', 'KeywordsAutoCompleteMinLength', 'merck.ini');

        $input = mb_strtolower( $kw, 'UTF-8' );

        if ( mb_strlen( $input, 'UTF-8') < $minLength )
        {
            return array();
        }

        $this->parseRequestParams();

        $solrFilter      = $this->solrFilter();
        $solrFacetsFiler = $this->solrFacetsFilter();

        // we autocomple on portal language only
        $filters = array(
            'meta_language_code_ms:'.substr( eZINI::instance()->variable( 'RegionalSettings', 'Locale'), 0, 3).'*'
        );

        if( $solrFilter )
            $filters[] = $solrFilter;
        if( $solrFacetsFiler )
            $filters[] = $solrFacetsFiler;

        // step 1 - get autocomplete terms from solr
        $params = array( 'q'                => '*:*',
                         'qf'               => 'k_spellcheck'.$solrTextAttributesSuffix,
                         'rows'             => 0,
                         'fq'               => implode( ' AND ', array_merge( $filters, array( '-k_spellcheck'.$solrTextAttributesSuffix.':"'.$input.'"' ) ) ),
                         'json.nl'          => 'arrarr',
                         'facet'            => 'true',
                         'facet.method'     => 'enum',
                         'facet.field'      => 'k_spellcheck'.$solrTextAttributesSuffix,
                         'facet.limit'      => $limit,
                         'facet.mincount'    => 1,
                         'facet.prefix'     => $input
        );
        $solrResults = SolrTool::rawSearch( $params );
        $sourceTerms = $solrResults['facet_counts']['facet_fields']['k_spellcheck'.$solrTextAttributesSuffix];

        // step 2 - get snomed terms from autocompletion terms
        $queries        = array();
        $searchTerms    = array_keys($sourceTerms);
        $searchTerms[]  = $input; // we add the input too as the previous request will return an emtpy set if it is a complete word
        $terms          = MMGlobalSearchDictionaryTerm::fetchSolrAutocompleteTerms( $searchTerms, null, $limit * 5 );

        // step 3 - we confront the terms to the current context
        $solrHighlightParams = $this->solrHighlightParams();
        foreach( $terms as $term )
        {
            if( mb_strtolower( $term, 'utf-8' ) == $input )
                continue;

            $query = array();
            foreach( explode( ' ', $solrHighlightParams['hl.fl'] ) as $field )
                $query[] = $field.':"'.addslashes( $term ).'"';

            $queries[] = implode( ' OR ', $query );
        }

        $params = array( 'q'                => '*:*',
                         'qf'               => 'k_spellcheck'.$solrTextAttributesSuffix,
                         'rows'             => 0,
                         'fq'               => implode( ' AND ', $filters ),
                         'json.nl'          => 'arrarr',
                         'facet'            => 'true',
                         'facet.query'      => $queries,
                         'facet.mincount'    => 0,
        );

        $solrResults = SolrTool::rawSearch( $params );
        $i           = 0;

        foreach( $solrResults['facet_counts']['facet_queries'] as $solrTerm => $solrTermCount )
        {
            if( $solrTermCount )
            {
                $term = $terms[$i];
                $result[] = array(  'label'    => $term,
                                    'count'    => $solrTermCount );
                if( count( $result ) >= $limit )
                    break;
            }
            $i++;
        }
        usort( $result, function($a, $b){ return $a['count'] < $b['count']; } );

        // step 4 - complete list with regular solr search if needed

        $termsIndex = null;
        while ( count( $result ) < $limit )
        {
            if( is_null($termsIndex) )
            {
                foreach( $result as $arr )
                    $termsIndex[mb_strtolower( trim($arr['label']), 'utf-8' )] = true;
            }

            $term = each( $sourceTerms );
            if(!$term)
                break;
            $key = mb_strtolower( $term['key'], 'utf-8' );

            if( !isset( $termsIndex[$key] ) )
            {
                $result[] = array( 'label' => $term['key'],
                                   'count' => $term['value'] );
                $termsIndex[$key] = true;
            }
        }

        eZDebug::accumulatorStop( __CLASS__.'::'.__FUNCTION__ );

        return $result;
    }