const TargetPhraseCollection*
PhraseDictionaryCompact::GetTargetPhraseCollection(const Phrase &sourcePhrase) const {
  
  // There is no souch source phrase if source phrase is longer than longest
  // observed source phrase during compilation 
  if(sourcePhrase.GetSize() > m_phraseDecoder->GetMaxSourcePhraseLength())
    return NULL;

  // Retrieve target phrase collection from phrase table
  TargetPhraseVectorPtr decodedPhraseColl
    = m_phraseDecoder->CreateTargetPhraseCollection(sourcePhrase, true);
  
  if(decodedPhraseColl != NULL && decodedPhraseColl->size()) {
    TargetPhraseVectorPtr tpv(new TargetPhraseVector(*decodedPhraseColl));
    TargetPhraseCollection* phraseColl = new TargetPhraseCollection();
    
    // Score phrases and if possible apply ttable_limit
    TargetPhraseVector::iterator nth =
      (m_tableLimit == 0 || tpv->size() < m_tableLimit) ?
      tpv->end() : tpv->begin() + m_tableLimit;
    std::nth_element(tpv->begin(), nth, tpv->end(), CompareTargetPhrase());
    for(TargetPhraseVector::iterator it = tpv->begin(); it != nth; it++)
      phraseColl->Add(new TargetPhrase(*it));
    
    // Cache phrase pair for for clean-up or retrieval with PREnc
    const_cast<PhraseDictionaryCompact*>(this)->CacheForCleanup(sourcePhrase, phraseColl);
    
    return phraseColl;
  }
  else
    return NULL;
  
}
void TargetPhraseCollection::NthElement(size_t tableLimit)
{
  vector<TargetPhrase*>::iterator 
  	iterMiddle = (tableLimit == 0 || m_collection.size() < tableLimit) ?m_collection.end() : m_collection.begin() + tableLimit;
  
	//std::sort(m_collection.begin(), m_collection.end(), CompareTargetPhrase());
  std::nth_element(m_collection.begin(), iterMiddle, m_collection.end(), CompareTargetPhrase());
}
void TargetPhraseCollection::NthElement(size_t tableLimit)
{
  CollType::iterator nth;
  nth = (tableLimit && tableLimit <= m_collection.size()
         ? m_collection.begin() + tableLimit
         : m_collection.end());
  std::nth_element(m_collection.begin(), nth, m_collection.end(), CompareTargetPhrase());
}
void TargetPhraseCollection::Sort(bool adhereTableLimit, size_t tableLimit)
{
  CollType::iterator iterMiddle;
  iterMiddle = (tableLimit == 0 || m_collection.size() < tableLimit)
               ? m_collection.end()
               : m_collection.begin()+tableLimit;

  std::partial_sort(m_collection.begin(), iterMiddle, m_collection.end(),
                    CompareTargetPhrase());

  if (adhereTableLimit && tableLimit && m_collection.size() > tableLimit) {
    for (size_t i = tableLimit; i < m_collection.size(); ++i) {
      const TargetPhrase *targetPhrase = m_collection[i];
      delete targetPhrase;
    }
    m_collection.erase(m_collection.begin()+tableLimit, m_collection.end());
  }
}