CRef<CGC_Assembly> CGenomicCollectionsService::GetAssembly(const string& acc_,
                                            int level, 
                                            int asmAttrFlags, 
                                            int chrAttrFlags, 
                                            int scafAttrFlags, 
                                            int compAttrFlags)
{
    string acc = NStr::TruncateSpaces(acc_);
    ValidateAsmAccession(acc);

    CGCClient_GetAssemblyRequest req;
    CGCClientResponse reply;

    req.SetAccession(acc);
    req.SetLevel(level);
    req.SetAssm_flags(asmAttrFlags);
    req.SetChrom_flags(chrAttrFlags);
    req.SetScaf_flags(scafAttrFlags);
    req.SetComponent_flags(compAttrFlags);

    LogRequest(req);

    try {
        return AskGet_assembly(req, &reply);
    } catch (CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_THROW(CException, eUnknown, reply.GetSrvr_error().GetDescription());
        }
        throw;
    }
}
CRef<CGCClient_AssembliesForSequences> CGenomicCollectionsService::FindAssembliesBySequences(const list<string>& sequence_acc, int filter, CGCClient_GetAssemblyBySequenceRequest::ESort sort, bool top_only)

{
    CGCClient_GetAssemblyBySequenceRequest req;
    CGCClientResponse reply;

    for(auto acc : sequence_acc)
        if(acc.length() > 30) {
            NCBI_THROW(CException, eUnknown, "Accession is longer than 30 characters: " + acc);
        }

    req.SetSequence_acc().assign(sequence_acc.begin(), sequence_acc.end());
    req.SetFilter(filter);
    req.SetSort(sort);
    req.SetTop_assembly_only(top_only ? 1 : 0);

    LogRequest(req);

    try {
        CRef<CGCClient_AssembliesForSequences> assm = AskGet_assembly_by_sequence(req, &reply);

        return assm;
    } catch (const CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_REPORT_EXCEPTION(reply.GetSrvr_error().GetDescription(), ex);
        }
        throw;
    }
    return CRef<CGCClient_AssembliesForSequences>();
}
CRef<CGCClient_AssemblySequenceInfo> CGenomicCollectionsService::FindBestAssembly(const list<string>& seq_id, int filter_type, int sort_type)
{
    CGCClient_FindBestAssemblyRequest  req;
    CGCClientResponse reply;

    req.SetSeq_id_acc().assign(seq_id.begin(), seq_id.end());
    req.SetFilter(filter_type);
    req.SetSort(sort_type);
    req.SetAssembly_return_limit(1);

    LogRequest(req);

    try {
        CRef<CGCClient_AssembliesForSequences> assm = AskGet_best_assembly(req, &reply);

        return assm->CanGetAssemblies() && !assm->GetAssemblies().empty() ?
               CRef<CGCClient_AssemblySequenceInfo>(assm->SetAssemblies().front()) :
               CRef<CGCClient_AssemblySequenceInfo>();
    } catch (const CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_REPORT_EXCEPTION(reply.GetSrvr_error().GetDescription().c_str(), ex);
        }
        throw;
    }
}
CRef<CGC_Assembly> CGenomicCollectionsService::GetAssembly(int releaseId, 
                                            int level, 
                                            int asmAttrFlags, 
                                            int chrAttrFlags, 
                                            int scafAttrFlags, 
                                            int compAttrFlags)
{
    CGCClient_GetAssemblyRequest req;
    CGCClientResponse reply;

    req.SetRelease_id(releaseId);
    req.SetLevel(level);
    req.SetAssm_flags(asmAttrFlags);
    req.SetChrom_flags(chrAttrFlags);
    req.SetScaf_flags(scafAttrFlags);
    req.SetComponent_flags(compAttrFlags);

    LogRequest(req);

    try {
        return AskGet_assembly(req, &reply);
    } catch (CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_THROW(CException, eUnknown, reply.GetSrvr_error().GetDescription());
        }
        throw;
    }
}
string CGenomicCollectionsService::ValidateChrType(const string& chrType, const string& chrLoc)
{
    CGCClient_ValidateChrTypeLocRequest req;
    CGCClientResponse reply;
    
    req.SetType(chrType);
    req.SetLocation(chrLoc);

    LogRequest(req);

    try {
        return AskGet_chrtype_valid(req, &reply);
    } catch (CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_THROW(CException, eUnknown, reply.GetSrvr_error().GetDescription());
        }
        throw;
    }
}
CRef<CGC_Assembly> CGenomicCollectionsService::GetAssembly(int releaseId, const string& mode)
{
    CGCClient_GetAssemblyBlobRequest req;
    CGCClientResponse reply;

    req.SetRelease_id(releaseId);
    req.SetMode(mode);

    LogRequest(req);

    try {
        return CCachedAssembly(AskGet_assembly_blob(req, &reply)).Assembly();
    } catch (CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_THROW(CException, eUnknown, reply.GetSrvr_error().GetDescription());
        }
        throw;
    }
}
CRef<CGCClient_EquivalentAssemblies> CGenomicCollectionsService::GetEquivalentAssemblies(const string& acc, int equivalency)
{
    CGCClient_GetEquivalentAssembliesRequest req;
    CGCClientResponse reply;

    req.SetAccession(acc);
    req.SetEquivalency(equivalency);

    LogRequest(req);

    try {
        CRef<CGCClient_EquivalentAssemblies> assm = AskGet_equivalent_assemblies(req, &reply);

        return assm;
    } catch (const CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_REPORT_EXCEPTION(reply.GetSrvr_error().GetDescription(), ex);
        }
        throw;
    }
}
CRef<CGC_Assembly> CGenomicCollectionsService::GetAssembly(const string& acc_, const string& mode)
{
    string acc = NStr::TruncateSpaces(acc_);
    ValidateAsmAccession(acc);

    CGCClient_GetAssemblyBlobRequest req;
    CGCClientResponse reply;

    req.SetAccession(acc);
    req.SetMode(mode);

    LogRequest(req);

    try {
        return CCachedAssembly(AskGet_assembly_blob(req, &reply)).Assembly();
    } catch (CException& ex) {
        if(reply.IsSrvr_error()) {
            NCBI_THROW(CException, eUnknown, reply.GetSrvr_error().GetDescription());
        }
        throw;
    }
}