CRef<SInternalData>
SplitQuery_CreateChunkData(CRef<IQueryFactory> qf,
                           CRef<CBlastOptions> options,
                           CRef<SInternalData> full_data,
                           bool is_multi_threaded /* = false */)
{
    BlastSeqSrc* seqsrc = 
        BlastSeqSrcCopy(full_data->m_SeqSrc->GetPointer());
    CRef<SBlastSetupData> setup_data = 
        BlastSetupPreliminarySearchEx(
                qf, options, 
                CRef<objects::CPssmWithParameters>(),
                seqsrc, is_multi_threaded);
    BlastSeqSrcResetChunkIterator(seqsrc);
    setup_data->m_InternalData->m_SeqSrc.Reset(new TBlastSeqSrc(seqsrc, 
                                               BlastSeqSrcFree));
    
    _ASSERT(setup_data->m_QuerySplitter->IsQuerySplit() == false);

    if (full_data->m_ProgressMonitor->Get()) {
        setup_data->m_InternalData->m_FnInterrupt = full_data->m_FnInterrupt;
        SBlastProgress* bp =
             SBlastProgressNew(full_data->m_ProgressMonitor->Get()->user_data);
        setup_data->m_InternalData->m_ProgressMonitor.Reset(new CSBlastProgress(bp));
    }
    return setup_data->m_InternalData;
}
 CPrelimSearchThread(SInternalData& internal_data,
                     const CBlastOptionsMemento* opts_memento)
     : m_InternalData(internal_data), m_OptsMemento(opts_memento)
 {
     // The following fields need to be copied to ensure MT-safety
     BlastSeqSrc* seqsrc = 
         BlastSeqSrcCopy(m_InternalData.m_SeqSrc->GetPointer());
     m_InternalData.m_SeqSrc.Reset(new TBlastSeqSrc(seqsrc, 
                                                    BlastSeqSrcFree));
     // The progress field must be copied to ensure MT-safety
     if (m_InternalData.m_ProgressMonitor->Get()) {
         SBlastProgress* bp = 
             SBlastProgressNew(m_InternalData.m_ProgressMonitor->Get()->user_data);
         m_InternalData.m_ProgressMonitor.Reset(new CSBlastProgress(bp));
     }
 }
Int2 SThreadLocalDataArraySetup(SThreadLocalDataArray* array,
                                EBlastProgramType program,
                                const BlastScoringOptions* score_options,
                                const BlastEffectiveLengthsOptions* eff_len_options,
                                const BlastExtensionOptions* ext_options,
                                const BlastHitSavingOptions* hit_options,
                                BlastQueryInfo* query_info,
                                BlastScoreBlk* sbp,
                                const BlastSeqSrc* seqsrc)
{
    Uint4 i;
    Int2 status = 0;

    if (!array)
        return BLASTERR_INVALIDPARAM;

    for (i = 0; i < array->num_elems; i++) {
        status =
           BLAST_GapAlignSetUp(program, seqsrc, score_options, eff_len_options,
              ext_options, hit_options, query_info, sbp,
              &array->tld[i]->score_params,
              &array->tld[i]->ext_params,
              &array->tld[i]->hit_params,
              &array->tld[i]->eff_len_params,
              &array->tld[i]->gap_align);
        if (status)
           return status;
        if ( !(array->tld[i]->query_info = BlastQueryInfoDup(query_info)) ) {
            return BLASTERR_MEMORY;
        }
        if ( !(array->tld[i]->seqsrc = BlastSeqSrcCopy(seqsrc)) ) {
            return BLASTERR_MEMORY;
        }
        if ( !(array->tld[i]->results = Blast_HSPResultsNew(query_info->num_queries)) ) {
            return BLASTERR_MEMORY;
        }
    }
    return 0;
}