--- ncbi-blast-2.6.0+-src/c++/src/algo/blast/blastinput/blast_fasta_input.cpp	2016-10-27 12:13:57.000000000 -0700
+++ ncbi-blast-2.6.0+-src/c++/src/algo/blast/blastinput/blast_fasta_input.cpp	2017-02-07 11:56:27.299726089 -0800
@@ -292,6 +292,12 @@ CBlastFastaInputSource::x_InitInputReade
                                     CFastaReader::fAllSeqIds :
                                     (CFastaReader::fNoParseID |
                                      CFastaReader::fDLOptional);
+
+    // Allow CFastaReader fSkipCheck flag to be set based
+    // on new CBlastInputSourceConfig property - GetSkipSeqCheck() -RMH-
+    flags += ( m_Config.GetSkipSeqCheck() ?
+               CFastaReader::fSkipCheck : 0 );
+
     flags += (m_ReadProteins
               ? CFastaReader::fAssumeProt 
               : CFastaReader::fAssumeNuc);
--- ncbi-blast-2.6.0+-src/c++/src/algo/blast/blastinput/blast_input.cpp	2016-06-20 08:45:40.000000000 -0700
+++ ncbi-blast-2.6.0+-src/c++/src/algo/blast/blastinput/blast_input.cpp	2017-02-07 11:56:27.300726093 -0800
@@ -53,12 +53,14 @@ CBlastInputSourceConfig::CBlastInputSour
      TSeqRange range                    /* = TSeqRange() */,
      bool retrieve_seq_data             /* = true */,
      int local_id_counter               /* = 1 */,
-     unsigned int seqlen_thresh2guess   /* = numeric_limits<unsigned int>::max()*/ )
+     unsigned int seqlen_thresh2guess   /* = numeric_limits<unsigned int>::max()*/,
+     bool skip_seq_check                /* = false -RMH- */ )
 : m_Strand(strand), m_LowerCaseMask(lowercase), 
   m_BelieveDeflines(believe_defline), m_Range(range), m_DLConfig(dlconfig),
   m_RetrieveSeqData(retrieve_seq_data),
   m_LocalIdCounter(local_id_counter),
   m_SeqLenThreshold2Guess(seqlen_thresh2guess),
+  m_SkipSeqCheck(skip_seq_check), /* -RMH- */
   m_GapsToNs(false)
 {
     // Set an appropriate default for the strand
--- ncbi-blast-2.6.0+-src/c++/include/algo/blast/blastinput/blast_input.hpp	2016-06-20 08:45:40.000000000 -0700
+++ ncbi-blast-2.6.0+-src/c++/include/algo/blast/blastinput/blast_input.hpp	2017-02-07 11:56:27.394726411 -0800
@@ -93,6 +93,8 @@ public:
     ///                 type guessing (see @ref kSeqLenThreshold2Guess) [in]
     /// @param local_id_counter counter used to create the CSeqidGenerator to
     ///                 create local identifiers for sequences read [in]
+    /// @param skip_seq_check When set this will avoid the sequence 
+    ///                       validation step when using the CFastaReader. -RMH-
     CBlastInputSourceConfig(const SDataLoaderConfig& dlconfig,
                   objects::ENa_strand strand = objects::eNa_strand_other,
                   bool lowercase = false,
@@ -101,7 +103,8 @@ public:
                   bool retrieve_seq_data = true,
                   int local_id_counter = 1,
                   unsigned int seqlen_thresh2guess = 
-                    numeric_limits<unsigned int>::max());
+                    numeric_limits<unsigned int>::max(),
+                  bool skip_seq_check = false /* -RMH- */ );
 
     /// Destructor
     ///
@@ -136,6 +139,18 @@ public:
     ///
     bool GetBelieveDeflines() const { return m_BelieveDeflines; }
 
+    /// Retrieve status of sequence alphabet validation
+    /// @return boolean to toggle validation of seq data 
+    /// -RMH-
+    ///
+    bool GetSkipSeqCheck() const { return m_SkipSeqCheck; }
+    
+    /// Turn validation of sequence on/off
+    /// @param skip boolean to toggle validation of sequence
+    /// -RMH-
+    ///
+    void SetSkipSeqCheck(bool skip) { m_SkipSeqCheck = skip; }
+
     /// Set range for all sequences
     /// @param r range to use [in]
     void SetRange(const TSeqRange& r) { m_Range = r; }
@@ -201,6 +216,8 @@ private:
     bool m_LowerCaseMask;          
     /// Whether to parse sequence IDs
     bool m_BelieveDeflines;        
+    /// Whether to validate sequence data -RMH-
+    bool m_SkipSeqCheck;
     /// Sequence range
     TSeqRange m_Range;             
     /// Configuration object for data loaders, used by CBlastInputReader
diff -rupN ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.in ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.in
--- ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.in	1969-12-31 16:00:00.000000000 -0800
+++ ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.in	2017-02-07 11:56:27.408726459 -0800
@@ -0,0 +1,16 @@
+# $Id: Makefile.in 371962 2012-08-14 09:45:56Z coulouri $
+
+# Meta-makefile("APP" project)
+#################################
+
+REQUIRES = objects algo
+
+APP_PROJ = rmblastn
+
+srcdir = @srcdir@
+include @builddir@/Makefile.meta
+
+.PHONY: all $(APP_PROJ)
+
+rmblastn:
+	${MAKE} ${MFLAGS} -f Makefile.rmblastn_app
diff -rupN ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.rmblastn.app ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.rmblastn.app
--- ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.rmblastn.app	1969-12-31 16:00:00.000000000 -0800
+++ ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/Makefile.rmblastn.app	2017-02-07 11:56:27.426726519 -0800
@@ -0,0 +1,16 @@
+WATCHERS = camacho madden maning
+
+APP = rmblastn
+SRC = rmblastn_app
+LIB_ = $(BLAST_INPUT_LIBS) $(BLAST_LIBS) $(OBJMGR_LIBS)
+LIB = blast_app_util $(LIB_:%=%$(STATIC))
+
+# De-universalize Mac builds to work around a PPC toolchain limitation
+CFLAGS   = $(FAST_CFLAGS:ppc=i386)
+CXXFLAGS = $(FAST_CXXFLAGS:ppc=i386)
+LDFLAGS  = $(FAST_LDFLAGS:ppc=i386)
+
+CPPFLAGS = $(ORIG_CPPFLAGS)
+LIBS = $(CMPRS_LIBS) $(DL_LIBS) $(PCRE_LIBS) $(NETWORK_LIBS) $(ORIG_LIBS)
+
+REQUIRES = objects -Cygwin
diff -rupN ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/rmblastn_app.cpp ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/rmblastn_app.cpp
--- ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/rmblastn_app.cpp	1969-12-31 16:00:00.000000000 -0800
+++ ncbi-blast-2.6.0+-src/c++/src/app/rmblastn/rmblastn_app.cpp	2017-02-07 11:56:27.434726546 -0800
@@ -0,0 +1,183 @@
+/*  $Id: rmblastn_app.cpp 371962 2012-08-14 09:45:56Z coulouri $
+ * ===========================================================================
+ *
+ *                            PUBLIC DOMAIN NOTICE
+ *
+ * ===========================================================================
+ *
+ * Authors:  Robert M. Hubley
+ *           Christiam Camacho ( original blastn_app.cpp )
+ *
+ */
+
+/** @file rmblastn_app.cpp
+ * RMBLASTN command line application
+ */
+
+#ifndef SKIP_DOXYGEN_PROCESSING
+static char const rcsid[] = 
+	"$Id: rmblastn_app.cpp 371962 2012-08-14 09:45:56Z coulouri $";
+#endif /* SKIP_DOXYGEN_PROCESSING */
+
+#include <ncbi_pch.hpp>
+#include <corelib/ncbiapp.hpp>
+#include <algo/blast/api/local_blast.hpp>
+#include <algo/blast/api/remote_blast.hpp>
+#include <algo/blast/blastinput/blast_fasta_input.hpp>
+#include <algo/blast/blastinput/rmblastn_args.hpp>
+#include <algo/blast/api/objmgr_query_data.hpp>
+#include <algo/blast/format/blast_format.hpp>
+#include "../blast/blast_app_util.hpp"
+
+#ifndef SKIP_DOXYGEN_PROCESSING
+USING_NCBI_SCOPE;
+USING_SCOPE(blast);
+USING_SCOPE(objects);
+#endif
+
+class CRMBlastnApp : public CNcbiApplication
+{
+public:
+    /** @inheritDoc */
+    CRMBlastnApp() {
+        CRef<CVersion> version(new CVersion());
+        version->SetVersionInfo(new CBlastVersion());
+        SetFullVersion(version);
+    }
+private:
+    /** @inheritDoc */
+    virtual void Init();
+    /** @inheritDoc */
+    virtual int Run();
+
+    /// This application's command line args
+    CRef<CRMBlastnAppArgs> m_CmdLineArgs; 
+};
+
+
+
+void CRMBlastnApp::Init()
+{
+    // formulate command line arguments
+    m_CmdLineArgs.Reset(new CRMBlastnAppArgs());
+
+    // read the command line
+
+    HideStdArgs(fHideLogfile | fHideConffile | fHideFullVersion | fHideXmlHelp | fHideDryRun);
+    SetupArgDescriptions(m_CmdLineArgs->SetCommandLine());
+}
+
+int CRMBlastnApp::Run(void)
+{
+    int status = BLAST_EXIT_SUCCESS;
+
+    try {
+
+        // Allow the fasta reader to complain on invalid sequence input
+        SetDiagPostLevel(eDiag_Warning);
+
+        /*** Get the BLAST options ***/
+        const CArgs& args = GetArgs();
+        CRef<CBlastOptionsHandle> opts_hndl;
+        if(RecoverSearchStrategy(args, m_CmdLineArgs)) {
+           	opts_hndl.Reset(&*m_CmdLineArgs->SetOptionsForSavedStrategy(args));
+        }
+        else {
+           	opts_hndl.Reset(&*m_CmdLineArgs->SetOptions(args));
+        }
+        const CBlastOptions& opt = opts_hndl->GetOptions();
+
+        /*** Get the query sequence(s) ***/
+        CRef<CQueryOptionsArgs> query_opts = 
+            m_CmdLineArgs->GetQueryOptionsArgs();
+        SDataLoaderConfig dlconfig(query_opts->QueryIsProtein());
+        dlconfig.OptimizeForWholeLargeSequenceRetrieval();
+        CBlastInputSourceConfig iconfig(dlconfig, query_opts->GetStrand(),
+                                     query_opts->UseLowercaseMasks(),
+                                     query_opts->GetParseDeflines(),
+                                     query_opts->GetRange());
+        iconfig.SetSkipSeqCheck(true);
+        CBlastFastaInputSource fasta(m_CmdLineArgs->GetInputStream(), iconfig);
+        CBlastInput input(&fasta, m_CmdLineArgs->GetQueryBatchSize());
+
+        /*** Initialize the database/subject ***/
+        CRef<CBlastDatabaseArgs> db_args(m_CmdLineArgs->GetBlastDatabaseArgs());
+        CRef<CLocalDbAdapter> db_adapter;
+        CRef<CScope> scope;
+        InitializeSubject(db_args, opts_hndl, m_CmdLineArgs->ExecuteRemotely(),
+                         db_adapter, scope);
+        _ASSERT(db_adapter && scope);
+
+        // Initialize the megablast database index now so we can know whether an indexed search will be run.
+        // This is only important for the reference in the report, but would be done anyway.
+        if (opt.GetUseIndex() && !m_CmdLineArgs->ExecuteRemotely()) {
+            CRef<CBlastOptions> my_options(&(opts_hndl->SetOptions()));
+            CSetupFactory::InitializeMegablastDbIndex(my_options);
+        }
+
+        /*** Get the formatting options ***/
+        CRef<CFormattingArgs> fmt_args(m_CmdLineArgs->GetFormattingArgs());
+        CBlastFormat formatter(opt, *db_adapter,
+                               fmt_args->GetFormattedOutputChoice(),
+                               query_opts->GetParseDeflines(),
+                               m_CmdLineArgs->GetOutputStream(),
+                               fmt_args->GetNumDescriptions(),
+                               fmt_args->GetNumAlignments(),
+                               *scope,
+                               opt.GetMatrixName(),
+                               fmt_args->ShowGis(),
+                               fmt_args->DisplayHtmlOutput(),
+                               opt.GetQueryGeneticCode(),
+                               opt.GetDbGeneticCode(),
+                               opt.GetSumStatisticsMode(),
+                               m_CmdLineArgs->ExecuteRemotely(),
+                               db_adapter->GetFilteringAlgorithm(),
+                               fmt_args->GetCustomOutputFormatSpec(),
+                               m_CmdLineArgs->GetTask() == "megablast",
+                               opt.GetMBIndexLoaded());
+                               
+        
+        formatter.PrintProlog();
+        
+        /*** Process the input ***/
+        for (; !input.End(); formatter.ResetScopeHistory()) {
+
+            CRef<CBlastQueryVector> query_batch(input.GetNextSeqBatch(*scope));
+            CRef<IQueryFactory> queries(new CObjMgr_QueryFactory(*query_batch));
+
+            SaveSearchStrategy(args, m_CmdLineArgs, queries, opts_hndl);
+
+            CRef<CSearchResultSet> results;
+
+            if (m_CmdLineArgs->ExecuteRemotely()) {
+                CRef<CRemoteBlast> rmt_blast = 
+                    InitializeRemoteBlast(queries, db_args, opts_hndl,
+                          m_CmdLineArgs->ProduceDebugRemoteOutput());
+                results = rmt_blast->GetResultSet();
+            } else {
+                CLocalBlast lcl_blast(queries, opts_hndl, db_adapter);
+                lcl_blast.SetNumberOfThreads(m_CmdLineArgs->GetNumThreads());
+                results = lcl_blast.Run();
+            }
+
+            ITERATE(CSearchResultSet, result, *results) {
+                formatter.PrintOneResultSet(**result, query_batch);
+            }
+        }
+
+        formatter.PrintEpilog(opt);
+
+        if (m_CmdLineArgs->ProduceDebugOutput()) {
+            opts_hndl->GetOptions().DebugDumpText(NcbiCerr, "BLAST options", 1);
+        }
+
+    } CATCH_ALL(status)
+    return status;
+}
+
+#ifndef SKIP_DOXYGEN_PROCESSING
+int main(int argc, const char* argv[] /*, const char* envp[]*/)
+{
+    return CRMBlastnApp().AppMain(argc, argv, 0, eDS_Default, 0);
+}
+#endif /* SKIP_DOXYGEN_PROCESSING */
--- ncbi-blast-2.6.0+-src/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp	2016-10-12 07:27:34.000000000 -0700
+++ ncbi-blast-2.6.0+-src/c++/src/objtools/blast/seqdb_reader/seqdbimpl.cpp	2017-03-29 11:14:01.852864789 -0700
@@ -1813,6 +1813,9 @@ void CSeqDBImpl::HashToOids(unsigned has
 
 CSeqDBIdSet CSeqDBImpl::GetIdSet()
 {
+    // RMH: Added to eliminate race condition for vector garbage collection
+    CFastMutexGuard guard(m_MutexForIdSet);
+    
     if (m_IdSet.Blank()) {
         if (! m_UserGiList.Empty()) {
             // Note: this returns a 'blank' IdSet list for positive
--- ncbi-blast-2.6.0+-src/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp	2016-02-03 07:19:38.000000000 -0800
+++ ncbi-blast-2.6.0+-src/c++/src/objtools/blast/seqdb_reader/seqdbimpl.hpp	2017-03-29 11:12:33.521480161 -0700
@@ -1133,6 +1133,9 @@ public:
 private:
     CLASS_MARKER_FIELD("IMPL")
 
+    // RMH
+    CFastMutex m_MutexForIdSet;
+
     /// Adjust string length to offset of first embedded NUL byte.
     ///
     /// This is a work-around for bad data in the database; probably
